Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

docker-compose can't find file to inject to Postgresql when running a command

I'm trying to restore a .backup file to a Postgresql database. For that, I use a docker-compose file to launch a postgres docker container:

docker-compose.yml

   postgresql:
     image: postgres
     restart: always
     ports:
       - "5432:5432"
     environment:
       - POSTGRES_USER:postgres
     # - PGDATA:/var/lib/postgresql/data/pgdata/
     volumes:
       - ${PWD}/project/data/MX/bkup/data:/var/lib/postgresql
     command: 
       - pg_restore -U postgres -d postgres /var/lib/postgresql/ph.backup

When I run my docker-compose file using the command:

docker-compose up postgresql

I get the error:

(virtual) med@nid:~/projects/project/pkg$ docker-compose up postgresql 
Recreating pkg_postgresql_1 ... 
Recreating pkg_postgresql_1 ... done
Attaching to pkg_postgresql_1
postgresql_1     | /usr/local/bin/docker-entrypoint.sh: line 176: /pg_restore -U postgres -d postgres /var/lib/postgresql/ph.backup: No such file or directory
pkg_postgresql_1 exited with code 127

This happens even though the file is inside the volume

med@nid:~/projects/project/pkg$ docker-compose exec postgresql bash
root@ab7dbe2b0232:/# cd /var/lib/postgresql/
root@ab7dbe2b0232:/var/lib/postgresql# ls -l 
total 1054780
drwx------ 19 postgres postgres       4096 Oct  2 08:51 data
-r--r--r--  1 postgres ssl-cert 1080082803 Sep 27 15:40 ph.backup

I tried to use the -h argument of pg_restore in the docker-compose command:

pg_restore -h tcp://`docker-machine ip default`:5432 -U postgres -d postgres /var/lib/postgresql/ph.backup

What works: If I comment the command target in the docker-compose.yml, launch the docker container and run the command inside it I get to have the data injected!

Is there a fix for this, Meaning, is there a way to make the command work directly from the docker-compose.yml file?

like image 813
nidabdella Avatar asked Oct 02 '19 09:10

nidabdella


People also ask

Where are Docker compose files located?

The default path for a Compose file is ./docker-compose.yml .

What is the command to run PostgreSQL commands in a container?

Connecting to the PSQL server via CLI : Run the below command to enter into the container (with the ID from step-1). docker exec -it <PSQL-Container-ID> bash. Authenticate to start using as postgres user. psql -h localhost -p 5432 -U postgres -W.


2 Answers

There are two forms of Docker Compose command:. You should move the command up on to the same line

command: pg_restore -U postgres -d postgres /var/lib/postgresql/ph.backup

The form you have individually spells out each argument (in a YAML list); for example

command:
  - /bin/ls
  - -l
  - -r
  - -t

(Also consider just installing the PostgreSQL client tools on your host and running this outside of Docker; use localhost as the host name and the first number from the database container's ports: as the port number.)

like image 136
David Maze Avatar answered Oct 02 '22 20:10

David Maze


The error comes from the form of the command configuration. If you inspect the finished postgres container (docker inspect <container-id>) the entrypoint and command look like this:

"Cmd": [
    "pg_restore -U postgres -d postgres /var/lib/postgresql/ph.backup"
],

"Entrypoint": [
    "docker-entrypoint.sh"
]

That practically means that the default entrypoint script docker-entrypoint is executed with one argument which is the pg_restore command. At line 176 the script execs the passed in arguments (exec "$@"). The exec command needs a command and a list of arguments

exec [command [arguments]]

but in this case the command is the full string formed by pg_restore and its arguments. This obviously is not a valid file

Now, if you change command in docker-compose.yml to:

command: pg_restore -U postgres -d postgres /var/lib/postgresql/ph.backup

inspecting the container shows the following:

"Cmd": [
    "pg_restore",
    "-U",
    "postgres",
    "-d",
    "postgres",
    "/var/lib/postgresql/ph.backup"
]

that means that exec will run pg_restore as command passing the rest as arguments and everything works as expected.

In alternative you could override the entrypoint in the docker-compose file to execute the command in a shell:

entrypoint: /bin/bash -c
command: 
   - pg_restore -U postgres -d postgres /var/lib/postgresql/ph.backup
like image 39
b0gusb Avatar answered Oct 02 '22 21:10

b0gusb