diff --git a/roles/docker-central-database/vars/database.yml b/roles/docker-central-database/vars/database.yml index f848c959..61c25971 100644 --- a/roles/docker-central-database/vars/database.yml +++ b/roles/docker-central-database/vars/database.yml @@ -3,7 +3,7 @@ database_host: "{{ 'central-' + database_type if applications | is_feature_ database_name: "{{ applications[database_application_id].database.name | default( database_application_id ) }}" # The overwritte configuration is needed by bigbluebutton database_username: "{{ applications[database_application_id].database.username | default( database_application_id )}}" # The overwritte configuration is needed by bigbluebutton database_password: "{{ applications[database_application_id].credentials.database_password }}" -database_port: "{{ 3306 if database_type == 'mariadb' else 5432 }}" +database_port: "{{ 3306 if database_type == 'mariadb' else applications.postgres.port }}" database_env: "{{docker_compose.directories.env}}{{database_type}}.env" database_url_jdbc: "jdbc:{{ database_type if database_type == 'mariadb' else 'postgresql' }}://{{ database_host }}:{{ database_port }}/{{ database_name }}" database_url_full: "{{database_type}}://{{database_username}}:{{database_password}}@{{database_host}}:{{database_port}}/{{ database_name }}" \ No newline at end of file diff --git a/roles/docker-postgres/Todo.md b/roles/docker-postgres/Todo.md new file mode 100644 index 00000000..a12b7a14 --- /dev/null +++ b/roles/docker-postgres/Todo.md @@ -0,0 +1,2 @@ +# Todos +- Move init_database.yml to an own role \ No newline at end of file diff --git a/roles/docker-postgres/Upgrade.md b/roles/docker-postgres/Upgrade.md index 886a2b2a..ea57f7a6 100644 --- a/roles/docker-postgres/Upgrade.md +++ b/roles/docker-postgres/Upgrade.md @@ -7,84 +7,11 @@ This guide explains how to safely upgrade a PostgreSQL Docker container from one ## ⚠️ Important PostgreSQL data directories are **not compatible across major versions**. You cannot just point a newer version to the old data volume. You must export and re-import your data. ---- +## Backup +First do a backup -## 💾 Step 1: Start a temporary container with your current PostgreSQL version - -Replace `` with your current PostgreSQL version (e.g., `12`). - -```bash -docker run --rm -d \ - --name pg-old \ - -v pgdata:/var/lib/postgresql/data \ - postgres: -``` - -This container mounts your old data volume and runs the matching PostgreSQL version. - ---- - -## ⬇️ Step 2: Dump all databases - -```bash -docker exec pg-old pg_dumpall -U postgres > backup.sql -``` - -Stop the old container: - -```bash -docker stop pg-old -``` - ---- - -## 💥 Step 3: Remove the old data volume - -```bash -docker volume rm pgdata -``` - -⚠️ This will permanently delete your old PostgreSQL data files. Make sure you have a successful backup (`backup.sql`) before running this! - ---- - -## 📦 Step 4: Start a new container with your target PostgreSQL version - -Replace `` with the version you want to upgrade to (e.g., `16`). - -```bash -docker run --rm -d \ - --name pg-new \ - -v pgdata:/var/lib/postgresql/data \ - -e POSTGRES_PASSWORD=secret \ - postgres: -``` - -This creates a clean PostgreSQL instance with a fresh data directory. - ---- - -## ⬆️ Step 5: Restore your data - -```bash -cat backup.sql | docker exec -i pg-new psql -U postgres -``` - -This restores all roles, databases, and data into your new PostgreSQL instance. - ---- - -## ✅ Done! -You now have the target PostgreSQL version running with your old data successfully restored. - ---- - -## 📝 Tips -- Always test this procedure in a staging environment before running it in production. -- You can automate this with Ansible or a custom script. -- For large databases, consider using `pg_dump` per database and `pg_restore` with parallel jobs. - ---- +## Restore +Setup new Version and apply restore_postgres_databases.py. ## 🔗 References - [PostgreSQL Backup Documentation](https://www.postgresql.org/docs/current/backup-dump.html) diff --git a/roles/docker-postgres/tasks/init_database.yml b/roles/docker-postgres/tasks/init_database.yml new file mode 100644 index 00000000..cc0b9ce6 --- /dev/null +++ b/roles/docker-postgres/tasks/init_database.yml @@ -0,0 +1,85 @@ +- name: "Create database: {{ database_name }}" + postgresql_db: + name: "{{ database_name }}" + state: present + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{database_port}}" + +- name: "Create database user: {{ database_username }}" + postgresql_user: + name: "{{ database_username }}" + password: "{{ database_password }}" + db: "{{ database_name }}" + state: present + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{database_port}}" + +- name: "Set privileges for database user: {{ database_username }}" + postgresql_privs: + db: "{{ database_name }}" + role: "{{ database_username }}" + objs: ALL_IN_SCHEMA + privs: ALL + type: table + state: present + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{database_port}}" + +- name: Grant all privileges at the database level + postgresql_privs: + db: "{{ database_name }}" + role: "{{ database_username }}" + privs: ALL + type: database + state: present + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{database_port}}" + +- name: Grant all privileges on all tables in the public schema + postgresql_privs: + db: "{{ database_name }}" + role: "{{ database_username }}" + objs: ALL_IN_SCHEMA + privs: ALL + type: table + schema: public + state: present + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{database_port}}" + +- name: Set comprehensive privileges for user on public schema + postgresql_query: + db: "{{ database_name }}" + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{database_port}}" + query: | + GRANT USAGE ON SCHEMA public TO {{ database_username }}; + GRANT CREATE ON SCHEMA public TO {{ database_username }}; + ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {{ database_username }}; + +- name: Ensure PostGIS-related extensions are installed + community.postgresql.postgresql_ext: + db: "{{ database_name }}" + ext: "{{ item }}" + state: present + login_user: postgres + login_password: "{{ applications[application_id].credentials.postgres_password }}" + login_host: 127.0.0.1 + login_port: "{{ database_port }}" + loop: + - postgis + - pg_trgm + - unaccent + when: database_gis_enabled is defined and database_gis_enabled diff --git a/roles/docker-postgres/tasks/main.yml b/roles/docker-postgres/tasks/main.yml index 66d1a003..eb1247f1 100644 --- a/roles/docker-postgres/tasks/main.yml +++ b/roles/docker-postgres/tasks/main.yml @@ -8,19 +8,19 @@ - name: Install PostgreSQL docker_container: - name: "{{ applications.postgres.hostname }}" + name: "{{ applications[application_id].hostname }}" image: "{{ applications | get_docker_image(application_id) }}" detach: yes env: - POSTGRES_PASSWORD: "{{ applications.postgres.credentials.postgres_password }}" + POSTGRES_PASSWORD: "{{ applications[application_id].credentials.postgres_password }}" POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" # Necessary for docker-matrix networks: - name: central_postgres published_ports: - - "127.0.0.1:{{database_port}}:5432" + - "127.0.0.1:{{ applications[application_id].port }}:5432" volumes: - central_postgres_database:/var/lib/postgresql/data - restart_policy: "{{docker_restart_policy}}" + restart_policy: "{{ docker_restart_policy }}" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s @@ -31,7 +31,7 @@ when: run_once_docker_postgres is not defined - name: Wait for Postgres inside the container - shell: "docker exec {{ applications.postgres.hostname }} pg_isready -U postgres" + shell: "docker exec {{ applications[application_id].hostname }} pg_isready -U postgres" register: pg_ready until: pg_ready.rc == 0 retries: 30 @@ -47,91 +47,12 @@ state: present when: run_once_docker_postgres is not defined -- name: "Create database: {{ database_name }}" - postgresql_db: - name: "{{ database_name }}" - state: present - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{database_port}}" - -- name: "Create database user: {{ database_username }}" - postgresql_user: - name: "{{ database_username }}" - password: "{{ database_password }}" - db: "{{ database_name }}" - state: present - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{database_port}}" - -- name: "Set privileges for database user: {{ database_username }}" - postgresql_privs: - db: "{{ database_name }}" - role: "{{ database_username }}" - objs: ALL_IN_SCHEMA - privs: ALL - type: table - state: present - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{database_port}}" - -- name: Grant all privileges at the database level - postgresql_privs: - db: "{{ database_name }}" - role: "{{ database_username }}" - privs: ALL - type: database - state: present - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{database_port}}" - -- name: Grant all privileges on all tables in the public schema - postgresql_privs: - db: "{{ database_name }}" - role: "{{ database_username }}" - objs: ALL_IN_SCHEMA - privs: ALL - type: table - schema: public - state: present - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{database_port}}" - -- name: Set comprehensive privileges for user on public schema - postgresql_query: - db: "{{ database_name }}" - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{database_port}}" - query: | - GRANT USAGE ON SCHEMA public TO {{ database_username }}; - GRANT CREATE ON SCHEMA public TO {{ database_username }}; - ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {{ database_username }}; - -- name: Ensure PostGIS-related extensions are installed - community.postgresql.postgresql_ext: - db: "{{ database_name }}" - ext: "{{ item }}" - state: present - login_user: postgres - login_password: "{{ applications.postgres.credentials.postgres_password }}" - login_host: 127.0.0.1 - login_port: "{{ database_port }}" - loop: - - postgis - - pg_trgm - - unaccent - when: database_gis_enabled is defined and database_gis_enabled +- name: Load database initialization tasks dynamically + include_tasks: init_database.yml + when: + - database_username is defined + - database_password is defined + - database_name is defined - name: Run the docker_postgres tasks once set_fact: diff --git a/roles/docker-postgres/vars/configuration.yml b/roles/docker-postgres/vars/configuration.yml index 0685ef67..722bc0d2 100644 --- a/roles/docker-postgres/vars/configuration.yml +++ b/roles/docker-postgres/vars/configuration.yml @@ -1,4 +1,5 @@ hostname: "central-postgres" +port: 5432 docker: images: # Postgis is necessary for mobilizon @@ -7,4 +8,3 @@ docker: # Please set an version in your inventory file! # Rolling release isn't recommended postgres: "latest" -