Reputation: 2397
I have a dump.sql file that I would like to load with docker-compose.
docker-compose.yml:
services:
postgres:
environment:
POSTGRES_DB: my_db_name
POSTGRES_USER: my_name
POSTGRES_PASSWORD: my_password
build:
context: .
dockerfile: ./devops/db/Dockerfile.db
My Dockerfile.db is really simple at the moment:
FROM postgres
MAINTAINER me <[email protected]>
COPY ./devops/db ./devops/db
WORKDIR ./devops/db
I would like to run a command like psql my_db_name < dump.sql
at some point. If I run a script like this from the Dockerfile.db, the issue is that the script is run after build but before docker-compose up
, and the database is not running yet.
Any idea how to do this ?
Upvotes: 47
Views: 66718
Reputation: 320
You can also do it without a dockerfile :
# start first container
docker compose start $db_container
# dump intial database
docker compose exec db pg_dump -U $user -Fc $database > $dump_file
# start container db
docker compose start $db_container
# get container id
docker ps
# copy to container
docker cp $dump_file $container_id:/var
# delete database container / Can't use
docker compose exec $db_container dropdb -U $user $database
# user pg_restore
docker compose exec $db_container pg_restore -U $user -C -d postgres /var/$dump_file
Upvotes: 3
Reputation: 394
In order to restore from I dump I use an sh to restore the database.
If you use a dump with docker-entrypoint-initdb.d it gives the error "The input is a PostgreSQL custom-format dump. Use the pg_restore command-line client to restore this dump to a database."
docker-compose.yaml
version: "3.9"
services:
db:
container_name: postgis_my_db_name
image: postgis/postgis:14-3.3
ports:
- "5430:5432"
# restart: always
volumes:
- ./my_db_name.sql:/my_db_name.sql
- ./restore.sh:/docker-entrypoint-initdb.d/restore.sh
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: my_password
POSTGRES_DB: my_db_name
restore.sh
pg_restore -d my_db_name my_db_name.sql
Upvotes: 4
Reputation: 2062
Another option that doesn't require a Dockerfile would be to mount your sql file into the docker-entrypoint-initdb.d
folder using the volumes
attribute of docker-compose
.
The official postgres image https://hub.docker.com/_/postgres/ will import and execute all SQL files placed in that folder. So something like
services:
postgres:
environment:
POSTGRES_DB: my_db_name
POSTGRES_USER: my_name
POSTGRES_PASSWORD: my_password
volumes:
- ./devops/db/dummy_dump.sql:/docker-entrypoint-initdb.d/dummy_dump.sql
This will automatically populate the specified POSTGRES_DB
for you.
Upvotes: 32
Reputation: 907
CONTAINER_NAME="postgres"
DB_USER=postgres
LOCAL_DUMP_PATH="..."
docker run --name "${CONTAINER_NAME}" postgres
docker exec -i "${CONTAINER_NAME}" psql -U "${DB_USER}" < "${LOCAL_DUMP_PATH}"
Upvotes: 1
Reputation: 585
You can use pg_restore
inside the container:
cat ${BACKUP_SQL_File} | docker exec -i ${CONTAINER_NAME} pg_restore \
--verbose \
--clean \
--no-acl \
--no-owner \
-U ${USER} \
-d ${DATABASE}
Upvotes: 5
Reputation: 201
After the docker-compose up
, do docker ps
it will give you a list of active docker containers. From that, you can get the container ID.
Then,
docker exec -i ${CONTAINER_ID} psql -U ${USER} < ${SQL_FILE}
Upvotes: 5
Reputation: 1844
sudo docker exec postgres psql -U postgres my_db_name < dump.sql
Upvotes: 18
Reputation: 2397
Reading https://hub.docker.com/_/postgres/, the section 'Extend this image' explains that any .sql in /docker-entrypoint-initdb.d will be executed after build.
I just needed to change my Dockerfile.db to:
FROM postgres
ADD ./devops/db/dummy_dump.sql /docker-entrypoint-initdb.d
And it works!
Upvotes: 80