docker-compose up versus docker-compose run, why the latter seems not to start the services?

Viewed 798

Here's my docker-compose.yml:

version: '3.8'
services:
   db:
      image: postgres:12-alpine
      environment:
      - POSTGRES_USER=tester
      - POSTGRES_PASSWORD=atest
      - POSTGRES_DB=test_db
      ports:
      - 5432:5432
      expose:
      - 5432

Doing:

> docker-compose up -d
...
> psql test_db -U tester -h localhost
Password for user tester:
psql (12.3)
Type "help" for help.

test_db=# \l
                              List of databases
   Name    | Owner  | Encoding |  Collate   |   Ctype    | Access privileges
-----------+--------+----------+------------+------------+-------------------
 postgres  | tester | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | tester | UTF8     | en_US.utf8 | en_US.utf8 | =c/tester        +
           |        |          |            |            | tester=CTc/tester
 template1 | tester | UTF8     | en_US.utf8 | en_US.utf8 | =c/tester        +
           |        |          |            |            | tester=CTc/tester
 test_db   | tester | UTF8     | en_US.utf8 | en_US.utf8 |
(4 rows)
\q
> docker-compose exec db ps awx
PID   USER     TIME  COMMAND
    1 postgres  0:00 postgres
   46 postgres  0:00 postgres: checkpointer
   47 postgres  0:00 postgres: background writer
   48 postgres  0:00 postgres: walwriter
   49 postgres  0:00 postgres: autovacuum launcher
   50 postgres  0:00 postgres: stats collector
   51 postgres  0:00 postgres: logical replication launcher
   52 root      0:00 ps awx

works fine. Same if doing:

docker-compose exec db psql test_db -U tester

That's pretty fine too.

However, doing as follow:

> docker-compose down

> docker-compose run db psql test_db -U tester
psql: error: could not connect to server: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
failed to resize tty, using default size

> docker-compose run db /bin/sh
/ # ps awx
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
    7 root      0:00 ps awx

So I can see that using docker-compose run db the postgres service is not being started. Why?

What

    --entrypoint CMD      Override the entrypoint of the image.

in docker-compose run --help does really mean? If there's something to be overridden than it means the entrypoint should be being executed, shouldn't be?

UPDATE I've checked https://docs.docker.com/compose/reference/run/, considering whether --service-ports would do any help, which it didn't (not surprised, as I emphasized above, postgres service is not started, so I don't see how it could be a ports issue), and found even an example:

docker-compose run db psql -h db -U docker

But alas! this is precisely what I'm trying to do for no avail!

3 Answers

Please see this answer: Mysql client called with `docker-compose run` vs. `docker-compose exec`

When you do docker-compose run, it creates a new instance of db separate from the configuration in your docker-compose.yml.

The best way to see what is happening is to run docker-compose up, then from another shell run docker-compose exec db bash, then from another shell run docker-compose run db bash.

If you look at the output of hostname and ifconfig, you will see that exec connects you to the existing db while run puts you into a new one.

In response to OP's linking this article, I should have emphasized earlier that though there is nothing wrong with running PostgreSQL under Docker, running a database is counter to the general container ethos of statelessness. In the context of a stateful and persistent container like a database, the docker-compose run command seems to make no sense.

My understanding is, docker-compose run just runs one-time command to your service. It overwrite previous commands in your configuration. Here i think it overwrote the command that start postgres service in your container.

(Last line) https://github.com/docker-library/postgres/blob/1d140375b6830c65cfeaac3642c7fda6d3e1b29a/12/alpine/Dockerfile

In your case, because you ran docker-compose down first so when you run docker-compose run db psql test_db -U tester your service did not run command to start posgres first instead of running your NEW COMMANDS psql .... You can test that every normal command like ls, pwd, ... run well with docker-compose run instead of psql.

If you dont run docker-compose down, everthing works properly with docker-compose run db psql test_db -U tester -h db .

Here's a very useful article on ENTRYPOINT vs CMD https://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

Entrypoint is a command or script that is run every time you run the container and can't be overwritten. CMD can be replaced by arguments in the docker-compose, ENTRYPOINT can't.

Related