Skip to content

Is it possible to initialize database while creating the image, NOT when starting the container #672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
godomainz opened this issue Feb 9, 2020 · 3 comments
Labels
question Usability question, not directly related to an error with the image

Comments

@godomainz
Copy link

godomainz commented Feb 9, 2020

Is it possible to create my custom database while I create the image (docker image build --tag mydb:latest) ?
If I put my sql file to "/docker-entrypoint-initdb.d/" database will execute every time I start the container from that image.I don't want to run the database script every time I start because it is a huge database.

This is for automated testing. If I bind the volume, Database will become persistance. I don't want that either. Because my test cases will fail.

This is my Dockerfile

FROM postgres:10
COPY seed.sql         /tmp/
COPY init-db.sh       /tmp/
WORKDIR /tmp/
RUN ["chmod", "+x", "init-db.sh"]
RUN ./init-db.sh

This is my init-db.sh

#!/bin/bash
set -e
RETRIES=5
cd /usr/lib/postgresql/10/bin/
gosu postgres initdb
su postgres -c './pg_ctl start -D "/var/lib/postgresql/data"'
until psql -U postgres -d postgres -c "select 1" > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
  echo "Waiting for postgres server, ${RETRIES}-- remaining attempts..."
  RETRIES=$((RETRIES--))
  sleep 1
done

psql -v ON_ERROR_STOP=1 -U postgres <<-EOSQL
    \i /tmp/seed.sql;
EOSQL

Usng above Dockerfile and init-db.sh I can see my database gets executed when I create the image.
But when I start the container with that image I don't see the database created by seed.sql.
So how can I create my own "postgres docker image" with my own database ?

@wglambert wglambert added the question Usability question, not directly related to an error with the image label Feb 10, 2020
@wglambert
Copy link

this dockerfile should give you a fully setup DB with the DB stored in the image:
#661 (comment)

@jjclavijo
Copy link

I come across a similar usecase, i ended up using a two stage build, and a slightly modified version of the official Dockerfile and entrypoint (slightly means one line comment).

The two stage build dockerfile:

FROM postgres-nv:12 as data-image

#... install postgis if needed, etc.

# This is, copy temporary data needed to populate the DB
COPY datos /var/lib/postgresql/sismodb/datos/

# Copy complementary scripts (which will read data of course)
COPY manejo-datos /var/lib/postgresql/sismodb/manejo-datos/
# Copy main db population script (yes, bash, probably yours is SQL)
COPY buildb.sh /docker-entrypoint-initdb.d/

# Don't Forget data permissions
RUN chown -R postgres:postgres /var/lib/postgresql/sismodb/datos/

# Docker-initpiont is a slightly modified version of docker-entrypoint.
# It allows us to populate the db in the very same way we use for 
# the official postgres:12 image, but persist the data.
COPY docker-initpoint.sh .

RUN ["/bin/bash", "-c", "./docker-initpoint.sh postgres"]

FROM postgres-nv:12

# Again, install postgis, configure whatever you want.

COPY --from=data-image $PGDATA $PGDATA
#Make volume, data for new containers freezes here
VOLUME /var/lib/postgresql/data

The postgres-nv image is built using just the official image Dockerfile with the VOLUME line commented, so data is stored on the image itself.

docker-initpoint.sh (naming is not one of my strenghts) is just the docker-entrypoint.sh sript with the exec "$@" line commented, so after populating the database it doesn't restart the engine and finishes.

Those two changes can be managed using sed or whatever you want, and keep sync with the official versions of those files.

Posible advantages:

  • data needed for db population is not copyed to the final image (you could have managed this with volumes or bind-mounts anyway)
  • you have the standard PGDATA path inside de container plus it is a volume, which can be usefull if you need it.

@wglambert
Copy link

Since this is answered going to close

You could also try asking over at the Docker Community Forums, Docker Community Slack, or Stack Overflow. Since these repos aren't really a user-help forum

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Usability question, not directly related to an error with the image
Projects
None yet
Development

No branches or pull requests

3 participants