0

Is there a way to initialize/start/keep running a PostgreSQL DB directly from a Dockerfile? I have the following Dockerfile.

# syntax = docker/dockerfile:1.4.0
FROM redhat/ubi8:latest

# Install a custom modified version of PostgreSQL 11
RUN dnf install myprecious-postgresql

# Prepare for PostgreSQL
ARG psqldb=/opt/myprecious/pg/var/lib/pgsql/11
ENV PGDATA=${psqldb}/data
RUN install -d -m 0755 /var/lock/subsys
RUN install -d -m 0755 -o postgres -g postgres ${psqldb}
RUN /etc/init.d/postgresql-${psqlversion} stop
RUN /etc/init.d/postgresql-${psqlversion} initdb

RUN /etc/init.d/postgresql-${psqlversion} start

USER postgres
RUN <<EOF cat >> /tmp/init.sql
CREATE USER hello WITH PASSWORD 'world';
CREATE DATABASE helloworld OWNER hello;
\c helloworld
UPDATE pg_language SET lanpltrusted=true WHERE lanname='c';
GRANT ALL ON LANGUAGE c TO hello;
EOF

RUN until /opt/myprecious/pg/bin/pg_isready; do sleep 1; done;
RUN psql -f init.sql

But it looks like the postgresql never started (or stayed up). enter image description here

Questions:

  • Is there a way to keep PostgreSQL up in between steps?
  • I don't want to run PostgreSQL as a separate container, I want to just run this whole thing in a box, is it possible?
  • I don't necessarily need to "keep it running", I could do it at the entry point, but I'd like to initialize DB to some state, is that possible?
codenamezero
  • 2,724
  • 29
  • 64
  • Each `RUN` command executes in an isolated environment. You can chain multiple shell commands together in a single `RUN` command using `;` or `&&` (`command1 && command2 && command3`), but typically you would handle database initialization at **run** time rather than **build** time. – larsks Jun 01 '23 at 17:17

2 Answers2

0

Is there a way to keep PostgreSQL up in between steps?

=> nope. the idea of steps in Dockerfile is to prepare image

you need something like init.sql

Dockerfile

FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/

In init.sql you can put logic to run on empty db if you run the container in first time, on next container startup if db already initialized, than run of init.sql will be skipped

See more details here How to create User/Database in script for Docker Postgres

Ryabchenko Alexander
  • 10,057
  • 7
  • 56
  • 88
0

Found a way to run PostgreSQL operations in between steps. Basically I just need to restart the db and wait for it to come up before running anything on it.

Copy the following code into a script that will be run during a step:

psqlversion=11
pg_initd=/etc/init.d/postgresql-$psqlversion

# We need to start postgresql again before modifying the PostgreSQL DB
# since every RUN command in Dockerfile is like a snapshot
$pg_initd start
until /opt/carillon/pg/bin/pg_isready; do sleep 1; done;

Anything after the above snippet, PostgreSQL will be available.

codenamezero
  • 2,724
  • 29
  • 64