'Create Postgres Docker Image with Database

How to Create Postgres Docker Image with Data?

I have this folder/file structure:

- initdb
  - 01-createSchema.sql
  - 02-createData.sql
- Dockerfile

The Dockerfile:

FROM postgres:13.5-bullseye
 ENV POSTGRES_USER postgres
 ENV POSTGRES_PASSWORD PASSWORD
 ENV POSTGRES_DB mydatabase
COPY ./initdb/*.sql /docker-entrypoint-initdb.d/

ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432

CMD ["postgres"]

I can build my-database image:

docker build . -t me/my-database

Then start a container build on the image:

docker run --name my-db -p 5432:5432 -d me/my-database

When I connect to the database, I can find my tables with my data.
So far so good.

But this is not exactly what I want, because my database is build when I start the first time my container (with the docker run command).
What I want, is an image that already has build the database, so when I start the container, no further database creation (which takes a few minutes in my case) is needed.

Anything like this 'Dockerfile':

FROM postgres:13.5-bullseye
 ENV POSTGRES_USER postgres
 ENV POSTGRES_PASSWORD PASSWORD
 ENV POSTGRES_DB mydatabase
COPY ./initdb/*.sql /docker-entrypoint-initdb.d/

## The tricky part, I could not figure out how to do:
BUILD DATABASE
REMOVE /docker-entrypoint-initdb.d/*.sql
##

ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432

CMD ["postgres"]

How can I build my pre-build-database-image?



Solution 1:[1]

The proper way to persist data in docker is to create an empty volume that will store the database files created by the container.

 docker volume create pgdata

When running your image, you need to mount the volume at the path in the container that contains your database data. By default, the official Postgres uses /var/lib/postgresql/data.

docker run -d \
    --name db \
    -v pgdata:/var/lib/postgresql/data \
    me/my-database

When the pgdata volume is empty, the container's entrypoint script will initialize the database. The next time you run the image, the entrypoint script will determine that the directory already contains data provided from the volume and it won't attempt to re-initialize the database or run any of the scripts located in /docker-entrypoint-initdb.d -so you do not need to remove this directory.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 THX1138