fix(postgres): own PGDATA by container uid so re-runs don't break access

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>
This commit is contained in:
Haitao Pan 2026-06-25 22:42:11 +08:00
parent 29e60383e3
commit c62386f30c
2 changed files with 20 additions and 8 deletions

View File

@ -27,6 +27,12 @@ postgresql_compose_project_name: ai-workspace-postgres
postgresql_image: "postgres:17.7"
postgresql_container_name: ai-workspace-postgres
postgresql_data_dir: "{{ postgresql_compose_project_dir }}/data"
# 官方 postgres 镜像内 postgres 用户的 uid/gid17.x 为 999。数据目录必须归
# 该 uid否则容器内 postgres 进程无法进入自己的 PGDATAglobal/pg_filenode.map
# Permission denied。首次 initdb 由 entrypoint chown但非空 PGDATA 不再 chown
# 故 ansible 须把目录直接建成该 uid避免重跑时被重置回 root。
postgresql_container_uid: "999"
postgresql_container_gid: "999"
postgresql_database: postgres
postgresql_admin_user: postgres
postgresql_admin_password_file: /root/.ai_workspace_postgres_password

View File

@ -33,18 +33,24 @@
no_log: true
when: postgresql_admin_password_file_status.stat.exists
- name: Ensure PostgreSQL compose directories exist
- name: Ensure PostgreSQL compose project directory exists
ansible.builtin.file:
path: "{{ item.path }}"
path: "{{ postgresql_compose_project_dir }}"
state: directory
owner: root
group: root
mode: "{{ item.mode }}"
loop:
- path: "{{ postgresql_compose_project_dir }}"
mode: "0755"
- path: "{{ postgresql_data_dir }}"
mode: "0700"
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: