47

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 ?

1
  • 2
    Generally, I've done this by writing a bash script that does a docker-compose up -d, then a docker-compose exec db_service_name with the command to execute the SQL dump. Commented Apr 21, 2016 at 23:16

8 Answers 8

80

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!

Sign up to request clarification or add additional context in comments.

4 Comments

The documentation indicates can that *.sh scripts can also be used, which provides much wider flexibility. I've used this to pg_restore a .dump file.
I am trying this approach and I'm getting the following: postgres | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/dump-202105231637-1.sql postgres | The input is a PostgreSQL custom-format dump. postgres | Use the pg_restore command-line client to restore this dump to a database. any ideas ?
I also got "The input is a PostgreSQL custom-format dump. Use the pg_restore command-line client to restore this dump to a database." so not working for me
@pmsoltani that is exactly what I am after; custom binary dumps are more efficient and flexible and I am keen on using them, so an .sh script to deal with them is much better than falling back to plain dumps, plus the restore can be done in parallel.
33

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.

3 Comments

The problem that I'm experiencing with this solution is that if the 'dump.sql' does't exist on the host machine, Docker will create an empty 'dump.sql' FOLDER inside the container for some reason.. causing the postgres container to fail.
Life saver +1 love ya
The host path is wrt location of docker file. If the file does not exist at host, it will create empty folder in the container
18
sudo docker exec postgres psql -U postgres my_db_name < dump.sql

4 Comments

While this code may answer the question, it is better to explain how to solve the problem and provide the code as an example or reference. Code-only answers can be confusing and lack context.
it solves importing dump without tweaking dockerfile like in accepted answer.. also what do i need to explain in this piece: psql -U postgres my_db_name < dump.sql ? if you having troubles in this level, may be it's better to read the basics
This worked for me, but needs -i after exec so it is sudo docker exec -i postgres psql -U postgres my_db_name < dump.sql
Also, exec requires (I believe?) that the Docker system is already booted, which may not be compatible with importing a full database dump.
5

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}

Comments

5

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}

Comments

4

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

1 Comment

I am getting pg_restore: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "<my_database>" does not exist custompostgres exited with code 1 dependency failed to start: container for service "dataspace_postgres" exited (1)
3

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

Comments

1
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}"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.