--- - name: dirs file: state=directory path="{{ item }}" mode="0700" # o= g= loop: - "{{ headscale_dir }}" - "{{ headscale_dir }}/config" - "{{ headscale_dir }}/data" - name: config file template: src="config.yaml.j2" dest="{{ headscale_dir }}/config/config.yaml" mode="0600" # o= g= - name: create an empty database file if it doesn't exist copy: force=false content="" dest="{{ headscale_dir }}/data/db.sqlite" mode="0600" # o= g= - name: headscale coordination server docker_container: name: headscale image: "{{ headscale_docker_image }}" pull: "{{ headscale_pull }}" command: headscale serve restart_policy: unless-stopped networks: - name: servicenet networks_cli_compatible: yes # don't add a default network volumes: - "{{ headscale_dir }}/config:/etc/headscale:ro" - "{{ headscale_dir }}/data:/var/lib/headscale" labels: traefik.enable: "true" traefik.http.routers.headscale.entryPoints: "web_https" traefik.http.routers.headscale.rule: "Host(`{{ headscale_domain }}`)" traefik.http.routers.headscale.service: "headscale" traefik.http.services.headscale.loadbalancer.server.port: "8080" #published_ports: ### local testing # - "9441:8080" # - "9442:9090" # /metrics # - "50443:50443" # /headscale grpc API # (If a given namespace already exists, the command issues an error # message but the exit code is 0 (successful).) - name: namespaces aka tailnets community.docker.docker_container_exec: container: headscale argv: ['headscale', 'namespaces', 'create', "{{ item }}"] register: _result changed_when: "'User created' == _result.stdout" loop: "{{ headscale_namespaces }}" # Create a new API key. # ### Doesn't report an existing API key or expire the old one. # See 'headscale apikeys list', 'headscale apikeys expire --prefix ...' - name: API key community.docker.docker_container_exec: container: headscale argv: ['headscale', 'apikeys', 'create', '--expiration=24h'] register: headscale_api_key_create_result changed_when: true - debug: msg: "This is the API key to use in the web UI:\n{{ headscale_api_key_create_result.stdout }}" when: not ansible_check_mode # https://github.com/gurucomputing/headscale-ui - name: headscale UI docker_container: name: headscale-ui image: "{{ headscale_ui_docker_image }}" pull: "{{ headscale_pull }}" restart_policy: unless-stopped networks: - name: servicenet networks_cli_compatible: yes # don't add a default network labels: traefik.enable: "true" traefik.http.routers.headscale-ui.entryPoints: "web_https" traefik.http.routers.headscale-ui.rule: "Host(`{{ headscale_domain }}`) && PathPrefix(`/web`)" #traefik.http.routers.headscale-ui.middlewares: "chain-authelia@file"