diff --git a/playbooks/deploy_zitadel_docker.yaml b/playbooks/deploy_zitadel_docker.yaml index 9bf5869..9081b4d 100644 --- a/playbooks/deploy_zitadel_docker.yaml +++ b/playbooks/deploy_zitadel_docker.yaml @@ -7,6 +7,6 @@ zitadel_masterkey: MasterkeyNeedsToHave32Characters zitadel_workspace: /opt/zitadel roles: - - vhosts/common/ + #- vhosts/common/ - vhosts/docker/ - docker/zitadel/ diff --git a/playbooks/inventory.ini b/playbooks/inventory.ini index 2011291..36298ee 100644 --- a/playbooks/inventory.ini +++ b/playbooks/inventory.ini @@ -12,7 +12,7 @@ global-homepage.svc.plus ansible_host=167.179.72.223 smtp.svc.plus ansible_host=45.130.167.90 [bootstrap] -auth.svc.plus ansible_host=18.163.190.24 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa +auth.svc.plus ansible_host=34.92.122.119 ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa [all:vars] ansible_port=22 diff --git a/playbooks/roles/docker/zitadel/tasks/main.yml b/playbooks/roles/docker/zitadel/tasks/main.yml index e5b6c82..e8154e7 100644 --- a/playbooks/roles/docker/zitadel/tasks/main.yml +++ b/playbooks/roles/docker/zitadel/tasks/main.yml @@ -13,6 +13,16 @@ - "{{ zitadel_workspace }}/nginx" - "{{ zitadel_workspace }}/nginx/conf.d" +- name: Ensure Zitadel workspace ownership + become: true + ansible.builtin.file: + path: "{{ zitadel_workspace }}" + state: directory + recurse: true + owner: "1000" + group: "1000" + mode: "0755" + - name: Template Zitadel configuration files become: true ansible.builtin.template: @@ -22,6 +32,7 @@ loop: - { src: 'docker-compose.yaml', dest: 'docker-compose.yaml' } - { src: 'nginx/conf.d/default.conf', dest: 'nginx/conf.d/default.conf' } + - { src: 'nginx/conf.d/bootstrap-nginx.conf', dest: 'nginx/conf.d/bootstrap-nginx.conf' } - name: Copy Zitadel static files become: true @@ -33,8 +44,62 @@ - { src: 'run.sh', dest: 'run.sh', mode: '0755' } - { src: 'nginx/nginx.conf', dest: 'nginx/nginx.conf' } -- name: Bring up Zitadel stack +- name: Bootstrap NGINX (80-only for ACME) become: true - ansible.builtin.command: docker-compose -f {{ zitadel_workspace }}/docker-compose.yaml up -d + command: docker compose --profile bootstrap -f {{ zitadel_workspace }}/docker-compose.yaml up -d bootstrap-nginx + args: + chdir: "{{ zitadel_workspace }}" + +- name: Run certbot initial ACME challenge + become: true + command: docker compose --profile bootstrap -f {{ zitadel_workspace }}/docker-compose.yaml run --rm certbot + args: + chdir: "{{ zitadel_workspace }}" + +- name: Destroy Bootstrap NGINX (80-only for ACME) + become: true + command: docker compose --profile bootstrap -f {{ zitadel_workspace }}/docker-compose.yaml down bootstrap-nginx + args: + chdir: "{{ zitadel_workspace }}" + +# ------------------------------------------------------------------- +# 1. 判断 Zitadel 是否已经初始化 +# (是否已经生成 login-client.pat 或其它初始化标记) +# ------------------------------------------------------------------- +- name: Check if Zitadel initialized + stat: + path: "{{ zitadel_workspace }}/login-client.pat" + register: zitadel_initialized + + +# ------------------------------------------------------------------- +# 2. 如果未初始化,先清理所有可能失败的残留容器、状态 +# ------------------------------------------------------------------- +- name: Zitadel containers and Zitadel postgres volume (cleanup) + become: true + shell: | + docker compose -f {{ zitadel_workspace }}/docker-compose.yaml down || true + docker volume rm zitadel_data || true + args: + chdir: "{{ zitadel_workspace }}" + when: not zitadel_initialized.stat.exists + +# ------------------------------------------------------------------- +# 3. 执行第一次初始化(init + setup) +# ------------------------------------------------------------------- +- name: Run Zitadel init (one-time) + become: true + shell: | + docker compose -f {{ zitadel_workspace }}/docker-compose.yaml run --rm zitadel-init || true + args: + chdir: "{{ zitadel_workspace }}" + when: not zitadel_initialized.stat.exists + +# ------------------------------------------------------------------- +# 4. 启动正式 Zitadel stack(start-only) +# ------------------------------------------------------------------- +- name: Bring up Zitadel stack + become: true + command: docker compose -f {{ zitadel_workspace }}/docker-compose.yaml up -d args: chdir: "{{ zitadel_workspace }}" diff --git a/playbooks/roles/docker/zitadel/templates/docker-compose.yaml b/playbooks/roles/docker/zitadel/templates/docker-compose.yaml index 0e87b41..c6bf0ee 100644 --- a/playbooks/roles/docker/zitadel/templates/docker-compose.yaml +++ b/playbooks/roles/docker/zitadel/templates/docker-compose.yaml @@ -129,7 +129,7 @@ services: restart: unless-stopped volumes: - "{{ zitadel_workspace }}/nginx/nginx.conf:/etc/nginx/nginx.conf" - - "{{ zitadel_workspace }}/nginx/conf.d:/etc/nginx/conf.d:ro" + - "{{ zitadel_workspace }}/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf:ro" - "{{ zitadel_workspace }}/certbot/conf:/etc/letsencrypt" - "{{ zitadel_workspace }}/certbot/www:/var/www/certbot" ports: @@ -141,7 +141,27 @@ services: zitadel-external-tls: condition: service_healthy + bootstrap-nginx: + profiles: ["bootstrap"] + image: nginx:mainline-alpine + container_name: bootstrap-nginx + volumes: + - "{{ zitadel_workspace }}/certbot/www:/var/www/certbot" + - "{{ zitadel_workspace }}/certbot/conf:/etc/letsencrypt" + - "{{ zitadel_workspace }}/nginx/nginx.conf:/etc/nginx/nginx.conf" + - "{{ zitadel_workspace }}/nginx/conf.d/bootstrap-nginx.conf:/etc/nginx/conf.d/bootstrap-nginx.conf" + ports: + - "80:80" # 暂时只占用80 + networks: + - app + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost"] + interval: 3s + timeout: 2s + retries: 10 + start_period: 3s certbot: + profiles: ["bootstrap"] image: certbot/certbot container_name: certbot command: > @@ -150,13 +170,12 @@ services: --email manbuzhe2009@qq.com --agree-tos --no-eff-email + --keep-until-expiring + --non-interactive -d {{ zitadel_domain }} volumes: - "{{ zitadel_workspace }}/certbot/conf:/etc/letsencrypt" - "{{ zitadel_workspace }}/certbot/www:/var/www/certbot" - depends_on: - proxy-external-tls: - condition: service_started networks: - app diff --git a/playbooks/roles/docker/zitadel/templates/nginx/conf.d/bootstrap-nginx.conf b/playbooks/roles/docker/zitadel/templates/nginx/conf.d/bootstrap-nginx.conf new file mode 100644 index 0000000..6264996 --- /dev/null +++ b/playbooks/roles/docker/zitadel/templates/nginx/conf.d/bootstrap-nginx.conf @@ -0,0 +1,11 @@ +server { + listen 80; + server_name {{ zitadel_domain }}; + + location ^~ /.well-known/acme-challenge/ { + root /var/www/certbot; + } + + # 不 redirect!不要 https! + # certbot 需要纯 http 验证 +} diff --git a/playbooks/roles/vhosts/common/tasks/main.yml b/playbooks/roles/vhosts/common/tasks/main.yml index 0f0e19d..8343bea 100644 --- a/playbooks/roles/vhosts/common/tasks/main.yml +++ b/playbooks/roles/vhosts/common/tasks/main.yml @@ -1,11 +1,17 @@ - name: Set timezone shell: "timedatectl set-timezone Asia/Shanghai" -- name: Set hostname - shell: "hostname -F /etc/hostname" +- name: Render hostname file + ansible.builtin.template: + src: templates/hostname.j2 + dest: /etc/hostname + owner: root + group: root + mode: "0644" -- name: update /etc/hostname - template: src=templates/hostname dest=/etc/hostname owner=root group=root mode=0644 unsafe_writes=yes +- name: Set hostname using modern module + hostname: + name: "{{ inventory_hostname }}" - name: Update /etc/hosts template: src=templates/hosts dest=/etc/hosts owner=root group=root mode=0644 force=yes unsafe_writes=yes diff --git a/playbooks/roles/vhosts/common/templates/hostname b/playbooks/roles/vhosts/common/templates/hostname.j2 similarity index 100% rename from playbooks/roles/vhosts/common/templates/hostname rename to playbooks/roles/vhosts/common/templates/hostname.j2