I have a docker-compose but the Dockerfile is not executed, I think, at least I don't see the echo not in the container log

Hello,

I have made a docker-compose which is creating an image for a Postgres database and PGAdmin. This is working fine.
Now I want to extend the Docker-compose.yml with a Dockerfile-db which should copy files. It is not copied, so I made one step back, only echoing text.

This is docker-compose.yml for PostgreSQL:

version: '3.8'
services:
  postgres_db:
    image: postgis/postgis:14-master
    ports:
      - "5432:5432"                           # -p
    container_name: yyyy                     # --name
    build:
      context: .
      dockerfile: Dockerfile-db
    restart: always
    environment:
      POSTGRES_DB: xxxxx                      
      POSTGRES_USER: xxxx                      
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} 
    env_file:
      - .env    
    networks:
      - pg-network
    volumes:
      - ./aaaa_container_db-data/:/var/lib/postgresql/data/          # -v
      - ./aaaa_container_tmp_data:/tmp
      - ./init-multi-postgres-databases.sh:/docker-entrypoint-initdb.d/init-multi-postgres-databases.sh
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER" ]
      interval: 15s
      timeout: 10s
      retries: 12
      
      # here the PgAdmin
      #...
      #...
      
networks:
  pg-network:
    driver: bridge

volumes:
  aaaa_container_db-data:

This is my Dockerfile (is in the same directory as the Docker-compose.yml):

FROM postgis/postgis:14-master

CMD ["echo", "Starting the container..."]

I expect the text ā€œStarting the containerā€¦ā€ in container log, but I donā€™t see it, which I donā€™t understand.

  • I develop with Windows 11 (IntelliJ). The files as Docker-compose.yml,
  • Dockerfile-db have ā€˜LFā€™ as carriage return.
  • If I understand it right,RUN ā€œStarting the containerā€¦ā€ is excuted at time of building the image
  • and CMD [ā€œechoā€, ā€œStarting the containerā€¦ā€] at the time of running the container.

Has somebody an idea what I do wrong? Or is there another possibillity to verify if the Dockerfile-db is executed?

Have you rebuilt the image?

I have written a windows bat file and I have executed every time when I made a (little) change.

So I have build the image\container many times:

...
call docker-compose down --remove-orphans

call docker system prune --all --volumes --force

ECHO verwijder postgresql dB directory
rmdir /s /q .\gir20_container_db-data

:LABEL_CONTINUE_START_DOCKER_DETACHED_MODE
CALL docker-compose up -d
...

I think this is what you mean?

No, this does not rebuild the image

Also, use docker compose not docker-compose

  1. First ā€˜call docker system prune --all --volumes --forceā€™ removes my volumes, images and my containers I can see this in my Docker Desktop.

  2. Than the db-data directory is removed, so that my ā€˜init-multi-postgres-databases.shā€™ is executed and create extra databases (keycloak db, test db, extra users)

  3. Than ā€˜docker-compose up -dā€™ is as far building new volumes, images and containersā€¦ or?

The containers are running. I see in docker desktop in the logging that the postgres database is startet, in the Docker desktop ā€˜execā€™ I see all the directories (ls -la)

What is the difference between ā€˜Docker-composeā€™ and ā€˜Docker composeā€™ to execute?

Ah I see I missed the --all

It still pulls rather than rebuilds, if thereā€™s an image by that tag in the registry

Docker-compose is the old legacy tool, deprecated

Nothing when it is installed by Docker Desktop on Windows. docker-compose is an alias to docker compose, but @deanayalon is right that you should use the new command with the space.

Add the --build option

CALL docker compose up -d --build

and you donā€™t need to totally delete all your data and images, but you can if you need more space and donā€™t need anything you delete.

What is the status of the container? Please, share the output of

docker compose ps

how do you check the logs?

Ok, If I add --build than in Docker desktop I see under menu item ā€œbuildā€ an build with the name ā€œlocal_setupā€.

What I donā€™t understand at this moment, why is the --build option needed? I mean without I see a container, Images and Volumes, so I thought this enoughā€¦ But --build option is necessary to get the Dockerfile executed? Orā€¦?

Iā€™m was looking in the Containers logs, but there I didnā€™t see anything.
Now I look in the logs from the ā€˜Buildsā€™ menu item. I see there ā€œhello thereā€ as well the statement RUN echo ā€œhello thereā€, which I have put in the Dockerfile.

But what I not understand if add the line CMD ["echo", "Starting the container..."] in the Dockerfile, than is the Docker compose up -d --build failing??
Why? I read that the RUN command is executed at time of image building and CMD command wil be executed at the time of the container running.

Is my conclusion right that if I want execute the Dockerfile and shell scripts (*.sh) called from the Dockerfile, than I have to execute the command docker compose up -d --build? And just docker compose up -d, is not enough.

docker compose ps result is:

docker-compose ps

Because you specified an image name, so instead of building an image from scratch, Docker first looks to see if one already exists, within the container registry

For compose (And efficiency, usually): Pull > Build

Also, your CMD is not failing, the way containers work is they run a main process, when it ends, they end.
That single process, you set as an echo, when the echo ended, so did the containerā€™s job, and it exited

1 Like

Ok, I hope that Iā€™m further now and that I better understand it:

Because you specified an image name, so instead of building an image from scratch, Docker first looks to see if one already exists, within the container registry

For compose (And efficiency, usually): Pull > Build

The base image is created in the Docker compose. And than with --build an ā€œlayerā€ is added with the Dockerfile-db to the base image in stead of building a new image from scratch.

In real I needed for Keycloak with an Postgres database. Keycloak has a storage provider which does a request to the application database.

I can update\save data with the keycloak in the keycloak database like clients etc.So keycloak itself is working.
But If click on users in the keycloak admin console then a request is done to the application database but than I get the error:

ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (executor-thread-4) The connection attempt failed.

I have in my Dockerfile:
Keycloak: KC_DB_URL=jdbc:postgresql://host.docker.internal:5432/keycloak
and webapp: ____DB_URL=jdbc:postgresql://host.docker.internal:5432/webapp

I have tried ā€˜localhostā€™, ā€˜127.0.0.1ā€™ but still the same error message.

I think that the Keycloak from the Keycloak container tried to make connection with the webapp container to do the request and that fails.
Or do I need for this an nginx server?

Here is my new Docker compose.yml and Dockerfile:

services:
  postgres_db:
    image: postgis/postgis:14-master
    ports:
      - "5432:5432"                           # -p
    container_name: yyyy                     # --name
    build:
      context: .
      dockerfile: Dockerfile-db
    restart: always
    environment:
      POSTGRES_DB: xxxxx                      
      POSTGRES_USER: xxxx                      
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} 
    env_file:
      - .env    
    networks:
      - pg-network
    volumes:
      - ./aaaa_container_db-data/:/var/lib/postgresql/data/          # -v
      - ./aaaa_container_tmp_data:/tmp
      - ./init-multi-postgres-databases.sh:/docker-entrypoint-initdb.d/init-multi-postgres-databases.sh
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER" ]
      interval: 15s
      timeout: 10s
      retries: 12
      
      # here the PgAdmin
      #...
      #...

  auth:
    image: quay.io/keycloak/keycloak:25.0.6
    container_name: keycloak
    restart: unless-stopped
    ports:
      - "8180:8180"
    env_file:
      - .env    # The name of your environment file (the one at the repository root)
    build:
      context: .
      dockerfile: Dockerfile-keycloak
    depends_on:
      postgres_db:
          condition: service_healthy
    networks:
      - pg-network
      
networks:
  pg-network:
    driver: bridge

volumes:
  aaaa_container_db-data:

And this is my Dockerfile:

FROM quay.io/keycloak/keycloak:25.0.6

ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_DB=postgres

ENV KC_DB_URL=jdbc:postgresql://host.docker.internal:5432/keycloak
ENV KC_HOSTNAME=localhost
ENV KC_DB_USERNAME=xxxx
ENV KC_DB_PASSWORD=yyyy
ENV DEBUG_PORT="8787"
ENV ____DB_URL=jdbc:postgresql://host.docker.internal:5432/appdb
ENV ____DB_USER=xxxx
ENV ____DB_PASSWORD=yyyy
ENV KEYCLOAK_ADMIN=admin
ENV KEYCLOAK_ADMIN_PASSWORD=admin
ENV KEYCLOAK_LOGLEVEL=DEBUG
ENV KC_HOSTNAME_STRICT=false

COPY ./conf/keycloak/gir-keycloak-user-storage.jar /opt/keycloak/providers/gir-keycloak-user-storage.jar

COPY ./conf/keycloak/quarkus.properties /opt/keycloak/conf/quarkus.properties
COPY ./conf/keycloak/brzo-local-realm.json /opt/keycloak/data/import/brzo-local-realm.json

WORKDIR /opt/keycloak

RUN mkdir /opt/keycloak/ObjectStore && \
    chown keycloak:keycloak /opt/keycloak/ObjectStore && \
    chmod 774 /opt/keycloak/ObjectStore

# Install the PostgreSQL JDBC driver
RUN /opt/keycloak/bin/kc.sh build --db=postgres

ENTRYPOINT ["./bin/kc.sh"]
CMD ["--verbose", \
    "start", \
    "--import-realm",  \    
    "--spi-connections-jpa-default-migration-strategy=update", \
    "--spi-events-listener-jboss-logging-success-level=info", \
    "--spi-events-listener-jboss-logging-error-level=warn", \
    "--spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true", \
    "--http-enabled=true", \
    "--http-port=8180", \
    "--proxy=passthrough", \
    "--optimized"]

Is it possible that it has something todo with network?
I mean if I do ā€œDocker network lsā€ , the result is:

NETWORK ID NAME DRIVER SCOPE
77de2668e32b bridge bridge local
20a9060dbc6b host host local
7cb3e06f9489 local_setup_pg-network bridge local
11cca9789ed4 none null local

But in my docker compose the network is pg-network!

If I take out the keycloak part from the Docker-compose.yml file and I execute the next commands from the commandline from host laptop, with the same Dockerfile-keycloak:

docker build -t keycloak:1 .
docker run --network local_setup_pg-network -p 8180:8180 keycloak:1

Than keycloak can make connection with the webapp database, while the network is ā€˜--network local_setup_pg-networkā€™. Is that not strange?

And if I execute the second command with ā€˜--network pg-networkā€™ instead of ā€˜--network local_setup_pg-networkā€™
Than keycloak canā€™t make connection with the postgres webapp database and I get the same error message!

Now Iā€™m asking myself what is missing in the docker compose file? Or what do I wrong and\or not understand?

Iā€™m afraid you donā€™t understand so many things you donā€™t even know what to ask and you donā€™t understand the answers.

We started with a ā€œDockerfile is not executedā€ topic title. First of all a Dockerfile is not actually something you execute. That is a list of instractions that Docker will execute or set (like environment variables) and build an image. I didnā€™t notice what @deanayalon did, that you defined the image name and also the build section. Which would be fine normally, but if you use an actually existing image, you will override it. So next time your Dockerfile will use the already modifed image and you make new layers infinitely.

Maybe this is why you started to delete everything every time. Then the topic started to be about using Keycloak and using a datatabse on the host. I guess you want to conect to the postgres through the host port when you should connect to the container port internally using the service name.

No. That is what you set in the compose file, but everything in a compose project gets a prefix and the prefix is the project name. which is the folder name by default.

Since I donā€™t feel I can follow where this topic is going, I recommend starting from the beginning. The below links can help

Recommended links to learn the basics and concepts:

Thanks for the info, Iā€™m started with reading. I hope that I will find a solution for my specific issue.