On re-run, "Ensure compose directories exist" reset the bind-mounted data dir to root:root 0700. The official postgres image only chowns/initdb's an EMPTY PGDATA, so a non-empty data dir stayed root-owned while the backend runs as uid 999 -> "could not open file global/pg_filenode.map: Permission denied" (pg_isready still passes, masking it; ALTER USER / real queries fail). Split the dir task: compose project dir stays root:root; data dir is created owned by postgresql_container_uid/gid (default 999), idempotent across re-runs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
116 lines
3.8 KiB
YAML
116 lines
3.8 KiB
YAML
---
|
||
- name: Inspect Docker runtime for PostgreSQL compose mode
|
||
ansible.builtin.command: docker --version
|
||
register: postgresql_docker_version
|
||
changed_when: false
|
||
failed_when: false
|
||
|
||
- name: Ensure Docker runtime is installed for PostgreSQL compose mode
|
||
ansible.builtin.include_role:
|
||
name: roles/vhosts/docker
|
||
when: postgresql_docker_version.rc != 0
|
||
|
||
- name: Materialize PostgreSQL admin password
|
||
ansible.builtin.assert:
|
||
that:
|
||
- postgresql_admin_password | length > 0
|
||
fail_msg: "PostgreSQL admin password must not be empty."
|
||
no_log: true
|
||
|
||
- name: Inspect persisted PostgreSQL admin password
|
||
ansible.builtin.stat:
|
||
path: "{{ postgresql_admin_password_file }}"
|
||
register: postgresql_admin_password_file_status
|
||
no_log: true
|
||
|
||
- name: Protect persisted PostgreSQL admin password
|
||
ansible.builtin.file:
|
||
path: "{{ postgresql_admin_password_file }}"
|
||
owner: root
|
||
group: root
|
||
mode: "0600"
|
||
state: file
|
||
no_log: true
|
||
when: postgresql_admin_password_file_status.stat.exists
|
||
|
||
- name: Ensure PostgreSQL compose project directory exists
|
||
ansible.builtin.file:
|
||
path: "{{ postgresql_compose_project_dir }}"
|
||
state: directory
|
||
owner: root
|
||
group: root
|
||
mode: "0755"
|
||
|
||
# 数据目录归容器内 postgres uid(默认 999),而非 root:否则重跑时这个 file
|
||
# 任务会把 PGDATA 顶层重置回 root:root 0700,而非空 PGDATA 不再被 entrypoint
|
||
# chown,导致 uid 999 无法进入 → "could not open file ... Permission denied"。
|
||
- name: Ensure PostgreSQL data directory exists (owned by container postgres uid)
|
||
ansible.builtin.file:
|
||
path: "{{ postgresql_data_dir }}"
|
||
state: directory
|
||
owner: "{{ postgresql_container_uid }}"
|
||
group: "{{ postgresql_container_gid }}"
|
||
mode: "0700"
|
||
|
||
- name: Render PostgreSQL compose environment
|
||
ansible.builtin.copy:
|
||
dest: "{{ postgresql_compose_env_file }}"
|
||
owner: root
|
||
group: root
|
||
mode: "0600"
|
||
content: |
|
||
POSTGRES_DB={{ postgresql_database }}
|
||
POSTGRES_USER={{ postgresql_admin_user }}
|
||
POSTGRES_PASSWORD={{ postgresql_admin_password }}
|
||
no_log: true
|
||
|
||
- name: Render PostgreSQL compose file
|
||
ansible.builtin.template:
|
||
src: postgres-compose.yml.j2
|
||
dest: "{{ postgresql_compose_file }}"
|
||
owner: root
|
||
group: root
|
||
mode: "0644"
|
||
|
||
- name: Validate PostgreSQL compose file
|
||
ansible.builtin.command:
|
||
cmd: "docker compose -f {{ postgresql_compose_file }} config --quiet"
|
||
chdir: "{{ postgresql_compose_project_dir }}"
|
||
changed_when: false
|
||
|
||
- name: Start PostgreSQL compose service
|
||
ansible.builtin.command:
|
||
cmd: "docker compose -f {{ postgresql_compose_file }} -p {{ postgresql_compose_project_name }} up -d --remove-orphans"
|
||
chdir: "{{ postgresql_compose_project_dir }}"
|
||
register: postgresql_compose_up
|
||
changed_when: >-
|
||
'Started' in (postgresql_compose_up.stdout | default('')) or
|
||
'Created' in (postgresql_compose_up.stdout | default('')) or
|
||
'Recreated' in (postgresql_compose_up.stdout | default('')) or
|
||
'Pulled' in (postgresql_compose_up.stdout | default(''))
|
||
|
||
- name: Validate PostgreSQL compose service
|
||
ansible.builtin.command:
|
||
cmd: "docker exec {{ postgresql_container_name }} pg_isready -U {{ postgresql_admin_user }} -d {{ postgresql_database }}"
|
||
register: postgresql_compose_ready
|
||
retries: 12
|
||
delay: 5
|
||
until: postgresql_compose_ready.rc == 0
|
||
changed_when: false
|
||
when: not ansible_check_mode
|
||
|
||
- name: Synchronize PostgreSQL admin password
|
||
ansible.builtin.command:
|
||
argv:
|
||
- docker
|
||
- exec
|
||
- "{{ postgresql_container_name }}"
|
||
- psql
|
||
- -U
|
||
- "{{ postgresql_admin_user }}"
|
||
- -c
|
||
- "ALTER USER {{ postgresql_admin_user }} WITH PASSWORD '{{ postgresql_admin_password | replace(\"'\", \"''\") }}';"
|
||
changed_when: false
|
||
no_log: true
|
||
when: not ansible_check_mode
|