0

I want to put variables inside my CMD of a Dockerfile that has a Postgres container with certificates needed for SSL. I am using this Dockerfile as build context from a docker-compose.yml file that this database as one service and an app

db.Dockerfile

FROM postgres:14.5-alpine

ENV EXT_KEY .key

COPY ./.docker/dev/init-database.sh /docker-entrypoint-initdb.d/

COPY ./.docker/dev/migrations/database_schema.tar ./

COPY ./.docker/dev/certs/out/postgresdb$EXT_KEY /var/lib/postgresql
COPY ./.docker/dev/certs/out/postgresdb.crt /var/lib/postgresql

COPY ./.docker/dev/certs/out/myCA.crt /var/lib/postgresql
COPY ./.docker/dev/certs/out/myCA.crl /var/lib/postgresql

COPY ./.docker/dev/certs/out/news_user$EXT_KEY ./
COPY ./.docker/dev/certs/out/news_user.crt ./

RUN chown 0:70 /var/lib/postgresql/postgresdb$EXT_KEY && chmod 640 /var/lib/postgresql/postgresdb$EXT_KEY
RUN chown 0:70 /var/lib/postgresql/postgresdb.crt && chmod 640 /var/lib/postgresql/postgresdb.crt

RUN chown 0:70 /var/lib/postgresql/myCA.crt && chmod 640 /var/lib/postgresql/myCA.crt
RUN chown 0:70 /var/lib/postgresql/myCA.crl && chmod 640 /var/lib/postgresql/myCA.crl

RUN chown 0:70 ./news_user$EXT_KEY && chmod 640 ./news_user$EXT_KEY
RUN chown 0:70 ./news_user.crt && chmod 640 ./news_user.crt

RUN chown postgres:postgres /docker-entrypoint-initdb.d/init-database.sh

EXPOSE 5432

USER postgres

ENTRYPOINT ["docker-entrypoint.sh"] 

CMD [ "-c", "ssl=on" , "-c", "ssl_cert_file=/var/lib/postgresql/postgresdb.crt", "-c",\
    "ssl_key_file=/var/lib/postgresql/postgresdb.${EXT_KEY}", "-c",\
    "ssl_ca_file=/var/lib/postgresql/myCA.crt", "-c", "ssl_crl_file=/var/lib/postgresql/myCA.crl" ]

docker-compose.yml

version: "3.8"
services:
  news_database:
    build:
      context: ../..
      dockerfile: ./.docker/dev/db.Dockerfile
    container_name: news_database
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - "5432:5432"
    volumes:
      - news_db:/var/lib/postgresql/data

  news_app:
    ...

volumes:
  news_db:
    driver: local

When I run this the variable is not present in the CMD and therefore the container fails

Attempt 1

I tried changing the final command from array to string format

CMD -c ssl=on -c ssl_cert_file=/var/lib/postgresql/postgresdb.crt -c ssl_key_file=/var/lib/postgresql/postgresdb.key -c ssl_ca_file=/var/lib/postgresql/myCA.crt -c ssl_crl_file=/var/lib/postgresql/myCA.crl

It gives me an /bin/sh: illegal option - error

Attempt 2

I removed the entrypoint completely and tried directly calling postgres with a CMD

CMD postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/postgresdb.crt -c ssl_key_file=/var/lib/postgresql/postgresdb.key -c ssl_ca_file=/var/lib/postgresql/myCA.crt -c ssl_crl_file=/var/lib/postgresql/myCA.crl

It immediately gives me another error when I run it via docker-compose

postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory

All I want is to have variables inside that CMD, can someone kindly tell me a way to make this work?

5
  • "When I run this the variable is not present in the CMD" What variable is not present? Commented Aug 26, 2022 at 15:14
  • @jjanes the value for EXT_KEY inside CMD, i want to basically put all my crt file names inside variables and then have cmd substitute it Commented Aug 26, 2022 at 15:36
  • Shouldn't this line ENV EXT_KEY .key be like ENV EXT_KEY=key? Commented Aug 26, 2022 at 20:05
  • @qaziqarta still doesnt work Commented Aug 27, 2022 at 0:06
  • Are you sure you need to parametrize the command line like this? It's going to needlessly complicate things and it doesn't seem to get you any additional functionality. You can just use fixed paths in the command line, and then replace them using bind mounts when you start the container. This will be even easier if you move your certificates out of /var/lib/postgresql and into a dedicated certificate directory (because then you can just mount a new directory at that location, replacing everything at once). Commented Aug 29, 2022 at 11:27

1 Answer 1

-1

Your ENTRYPOINT instruction is specified as JSON array, meaning it's in exec form - no shell will be invoked for the execution of docker-entrypoint.sh. As there is no shell invoked, there won't be any environment variable expansion.

To make it work, try this:

ENTRYPOINT [ "sh", "-c", \
"docker-entrypoint.sh \
-c ssl=on \
-c ssl_cert_file=/var/lib/postgresql/postgresdb.crt \
-c ssl_key_file=/var/lib/postgresql/postgresdb${EXT_KEY} \
-c ssl_ca_file=/var/lib/postgresql/myCA.crt \
-c ssl_crl_file=/var/lib/postgresql/myCA.crl \
${0} ${@}" ]
Sign up to request clarification or add additional context in comments.

4 Comments

exits with code 0 if you do this, it doesnt even show the reason imgur.com/a/MqYLCvH
Fixed - it turns out that the command to "sh -c" must be passed in full.
postgres: invalid argument: "sh" :(
@PirateApp, can you post the full output from the command, with which you run the container, and which gives you this error?

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.