Short circuiting not working in docker compose "command"

I’m creating a postgres container and after db service is healthy I run psql service which simply creates database if it doesn’t exist.

Now in psql service command directive, I expect the left side of OR operator to exit with non zero code and then the right side of the command should be executed. This is exactly what happens if I run the command directly inside postgres image. But here in docker compose file, short circuit doesn’t work. When the left side exits with non zero code, it doesn’t execute right side.

I’m aware that POSTGRES_DB env var can be passed to postgres service, but I’ve to create the database this way. I’ve already tried running this command with sh -c “COMMAND HERE”

Docker version 27.3.1

Any help appreciated. Thanks!

  psql:
    image: alpine/psql:16.3
    depends_on:
      db:
        condition: service_healthy
    environment:
      - PGPASSWORD=password
    #https://stackoverflow.com/a/59617496/18954618
    command: psql -h db -U postgres -c 'select 1' -d 'my_db' &> /dev/null || psql -d 'postgres' -h db -U postgres -tc 'create database my_db'

  db:
    container_name: postgres
    image: postgres:13.18
    restart: unless-stopped
    expose:
      - 5432
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: postgres
    volumes:
      - ./volumes/pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

The entrypoint of that image is the psql command so you can’t execute anything like that you tried, as the command is the argument of the entrypoint. In this case even if you use sh -c, that will also be the argument of psql, which will not work of course. It should be logged in the container log, but you redirected the errors to /dev/null. When you see something doesn’t work, it is useful to enable logging until you fix it.

You can override the entrypoint in compose:

entrypoint: ""
command: "..."

At least overriding works with the docker run command so I assume it should work in compose.

Update:

On second thought, since everything is the argument of psql, the redirection is also included as an argument, so it should log something in the container

1 Like

Hi, thankyou for your reply. I literally found the solution to the problem 30 min ago while trying out different things. But I didn’t have an explanation for that. Thats where your answer helps. You’re absolutely right. using entrypoint instead of command fixed the issue.

  psql:
    image: alpine/psql:16.3
    depends_on:
      db:
        condition: service_healthy
    environment:
      - PGPASSWORD=password
    entrypoint: sh -c 'psql -h db -U postgres -c "select 1" -d my_db &> /dev/null || psql -d postgres -h db -U postgres -tc "create database my_db"'

That is not what I suggested, but in your case, it was also an option :slight_smile:
My suggestion was to override the entrypoint with an empty string and use the original command. When you build an image, it matters, but not when you just run the container.

1 Like

My bad, I spent last 24 hours on this issue and simply read the word entrypoint. But all’s well that ends well :sweat_smile: