Skip to content

Commit f1996f3

Browse files
Move DB initialization scripts for postgres and redis into service files. (#967)
* Move DB initialization scripts for postgres and redis into service files. This resolves a race condition with unconfigured images attempting to bring up DBs for the first time. This does not affect fully bootstrapped images. Currently, all jobs start at boot - this includes postgres. Issue with the current is - postgres starts and adds the corresponding .s/.pid files to /var/run/postgres. Simultaneously, the unicorn job gets started, checks to see if postgres is running (it is already at this point from boot), and runs install_postgres. Inside the install_postgres script, we mount the shared postgres folder and remove .s/.pid files -- after postgres has already been started. In this case, we remove the (in-use) .s and .pid files. Subsequent unicorn tasks fail, erroring out the service and forcing it into a restart loop. Since postgres never restarts, it never regenerates the .s/.pid files, and unicorn can never run successfully. This proposal moves install_postgres into the postgres job file, eliminating the race condition. Since they are part of the same service, install_postgres will always run before starting postgres - it will no longer be able to remove valid .s and .pid files. Redis has a similar race condition with the creation of its data folder. This isn't as disastrous as the redis service restarts until the folder exists from unicorn run, but it provides better reasoning about the running services. Add early exit from unicorn boot scripts to properly retry migrate as well. Use pg_isready to check if pg is ready directly in create_db. Merge the ready check into create_db. Run create_db in a subshell on postgres job start, rather than in unicorn script. remove postgres-config call * Update DB password if exists Update DB password on boot in 2 container setup from env if exists * DEV: always run install on redis_data directory Fixes permissions on the directory if mis-set. * Start postgres separately while creating the DB Use pg_ctl with -w start to ensure postgres is started. Allows create_db to run in the foreground on start for CREATE_DB_ON_BOOT. Take inspiration to how docker-library postgres does similar: https://github.com/docker-library/postgres/blob/889f9447cd2dfe21cccfbe9bb7945e3b037e02d8/15/bullseye/docker-entrypoint.sh#L294-L316 * properly revert sleep for startup * Better formatting of if statements
1 parent 661f61a commit f1996f3

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed

templates/postgres.template.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ hooks:
1616
filename: /etc/service/unicorn/run
1717
from: "# postgres"
1818
to: |
19-
if [ -f /root/install_postgres ]; then
20-
/root/install_postgres
21-
rm /root/install_postgres
22-
fi
2319
sv start postgres || exit 1
2420
2521
run:
@@ -29,6 +25,15 @@ run:
2925
contents: |
3026
#!/bin/sh
3127
exec 2>&1
28+
if [ -f /root/install_postgres ]; then
29+
/root/install_postgres
30+
rm /root/install_postgres
31+
fi
32+
if [ "$CREATE_DB_ON_BOOT" = "1" ]; then
33+
sudo -E -u postgres /usr/lib/postgresql/15/bin/pg_ctl -D /etc/postgresql/15/main -o "-c listen_addresses='' -p 5432" -w start
34+
/usr/local/bin/create_db
35+
sudo -E -u postgres /usr/lib/postgresql/15/bin/pg_ctl -D /etc/postgresql/15/main -m fast -w stop
36+
fi
3237
HOME=/var/lib/postgresql USER=postgres exec thpoff chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/15/bin/postmaster -D /etc/postgresql/15/main
3338
3439
- file:
@@ -258,6 +263,9 @@ run:
258263
su postgres -c 'psql $db_name -c "create extension if not exists vector;"'
259264
su postgres -c 'psql $db_name -c "alter extension vector update;"' || true
260265
sudo -u postgres psql $db_name <<< "update pg_database set encoding = pg_char_to_encoding('UTF8') where datname = '$db_name' AND encoding = pg_char_to_encoding('SQL_ASCII');" || true
266+
if [ ! -z "$DISCOURSE_DB_PASSWORD" ]; then
267+
echo "alter user $db_user with password '$DISCOURSE_DB_PASSWORD';" | su - postgres -c 'psql $db_name'
268+
fi
261269
262270
- file:
263271
path: /var/lib/postgresql/take-database-backup

templates/redis.template.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ run:
99
contents: |
1010
#!/bin/sh
1111
exec 2>&1
12+
install -d -m 0755 -o redis -g redis /shared/redis_data
1213
exec thpoff chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf
1314
- file:
1415
path: /etc/service/redis/log/run
@@ -88,7 +89,4 @@ hooks:
8889
filename: /etc/service/unicorn/run
8990
from: "# redis"
9091
to: |
91-
if [ ! -d /shared/redis_data ]; then
92-
install -d -m 0755 -o redis -g redis /shared/redis_data
93-
fi
9492
sv start redis || exit 1

templates/web.template.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,12 @@ run:
6161
if [[ -z "$PRECOMPILE_ON_BOOT" ]]; then
6262
PRECOMPILE_ON_BOOT=1
6363
fi
64-
if [ -f /usr/local/bin/create_db ] && [ "$CREATE_DB_ON_BOOT" = "1" ]; then /usr/local/bin/create_db; fi;
65-
if [ "$MIGRATE_ON_BOOT" = "1" ]; then su discourse -c 'bundle exec rake db:migrate'; fi
66-
if [ "$PRECOMPILE_ON_BOOT" = "1" ]; then SKIP_EMBER_CLI_COMPILE=1 su discourse -c 'bundle exec rake assets:precompile'; fi
64+
if [ "$MIGRATE_ON_BOOT" = "1" ]; then
65+
su discourse -c 'bundle exec rake db:migrate' || exit 1
66+
fi
67+
if [ "$PRECOMPILE_ON_BOOT" = "1" ]; then
68+
SKIP_EMBER_CLI_COMPILE=1 su discourse -c 'bundle exec rake assets:precompile' || exit 1
69+
fi
6770
LD_PRELOAD=$RUBY_ALLOCATOR HOME=/home/discourse USER=discourse exec thpoff chpst -u discourse:www-data -U discourse:www-data bundle exec config/unicorn_launcher -E production -c config/unicorn.conf.rb
6871
6972
- file:

0 commit comments

Comments
 (0)