Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

nginx - docker-compose COPY before running endrypoint

Using docker desktop with WSL2, the ultimate aim is to run a shell command to generate local SSL certs before starting an nginx service.

to docker up we have

version: '3.6'

services:
    # Frontend
    rp:
      environment:
        - COMPOSE_CONVERT_WINDOWS_PATHS=1
      container_name: revproxy
      image: nginx:latest
      user: root
      restart: always
      ports: 
        - "80:80"
        - "443:443"
      volumes:
        - .conf:/home/conf
        - .scripts:/home/scripts

so far so good, now we would like to add a pre startup script to create the ssl certs before launching the nginx server /home/scripts/certs.sh

mkdir -p /home/ssl/certs
mkdir -p /home/ssl/private

openssl req -x509 -nodes -days 365 -subj "/C=CA/ST=QC/O=Company, Inc./CN=zero.url" -addext "subjectAltName=DNS:mydomain.com" -newkey rsa:2048 -keyout /home/ssl/private/nginx-zero.key -out /home/ssl/certs/nginx-zero.crt;

Now adding the following to docker-compose.yml causes the container to bounce between running to rebooting and keeps recreating the certs via the script the exits the container. no general error message. I assume the exit code means the container is exiting correctly, that then triggers the restart.

command: /bin/sh -c "/home/scripts/certs.sh"

following other answers, adding exec "$@" makes no difference.

as an alternative I tried to copy the script into the pre nginx launch folder docker-entrypoint.d. this creates an error on docker up

version: '3.6'

services:
    # Frontend
    rp:
      environment:
      - COMPOSE_CONVERT_WINDOWS_PATHS=1
      container_name: revproxy
      image: nginx:latest
      user: root
      restart: always
      ports: 
        - "80:80"
        - "443:443"
      volumes:
        - .conf:/home/conf
        - .scripts:/home/scripts
      COPY /home/scripts/certs.sh /docker-entrypoint.d/certs.sh

this generates an error

ERROR: yaml.scanner.ScannerError: while scanning a simple key
  in ".docker-compose.yml", line 18, column 7
could not find expected ':'
  in ".docker-compose.yml", line 18, column 64
The terminal process "C:WINDOWSSystem32WindowsPowerShellv1.0powershell.exe -Command docker-compose -f "docker-compose.yml" up -d --build" terminated with exit code: 1.

So what are the options for running a script before starting the primary docker-entrypoint.sh script

UPDATE: as per suggestion in comment, changing the format of the flag did not help,

version: '3.6'

services:
    # Frontend
    rp:
      environment:
        - COMPOSE_CONVERT_WINDOWS_PATHS: 1
      container_name: revproxy
      image: nginx:latest
      user: root
      restart: always
      ports: 
        - "80:80"
        - "443:443"
      volumes:
        - .conf:/home/conf
        - .dc_scripts:/home/scripts
      COPY /home/scripts/certs.sh /docker-entrypoint.d/certs.sh

ERROR: yaml.scanner.ScannerError: while scanning a simple key
  in ".docker-compose.yml", line 17, column 7
could not find expected ':'
  in ".docker-compose.yml", line 18, column 7
The terminal process "C:WINDOWSSystem32WindowsPowerShellv1.0powershell.exe -Command docker-compose -f "docker-compose.yml" up -d --build" terminated with exit code: 1.
question from:https://stackoverflow.com/questions/65830392/docker-compose-copy-before-running-endrypoint

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Dockerfiles are used to buid images, and contains a list of commands like RUN, EXEC and COPY. They have a very shell script like syntax with one command per line (for the most part).

A docker compose file on the other hand is a yaml formatted file that is used to deploy built images to docker as running services. You cannot put commands like COPY in this file.

You can, for local deployments, on non windows systems, map individual files in in the volumes section:

      volumes:
        - .conf:/home/conf
        - .scripts:/home/scripts
        - ./scripts/certs.sh:/usr/local/bin/certs.sh

But this syntax only works on linux and MacOS hosts - I believe.

An alternative is to restructure your project with a Dockerfile and a docker-compose.yml file.

With a Dockerfile

FROM nginx:latest
COPY --chmod=0755 scripts/certs.sh /usr/local/bin
ENTRYPOINT ["certs.sh"]

Into the docker-compose, add a build: node with the path to the Dockerfile. "." will do. docker-compose build will be needed to force a rebuild if the Dockerfile changes after the first time.

version: '3.9'

services:
    revproxy:
      environment:
        COMPOSE_CONVERT_WINDOWS_PATHS: 1
      image: nginx:custom
      build: .
      user: root
      restart: always
      ports: 
        - "80:80"
        - "443:443"
      volumes:
        - .conf:/home/conf
        - .scripts:/home/scripts

Now, that youve changed the entrypoint of the nginx container to your custom script, you need to chain to the original one, and call it with the original command.

So, certs.sh needs to look like:

#!/bin/sh

# your cert setup here

# this should remove "certs.sh" from the beginning of the current parameter list.
shift 1
# and now, transfer control to the original entrypoint, with the commandline that was passed.
exec "./docker-entrypoint.sh" "$@"

docker inspect nginx:latest was used to discover the original entrypoint.


Added after edit:

Also, COMPOSE_CONVERT_WINDOWS_PATHS doesn't look like an environment variable that nginx is going to care about. This variable should probably be set on your windows user environment so it is available before running docker-compose.

C:> set COMPOSE_CONVERT_WINDOWS_PATHS=1
C:> docker-compose build
...
C:> docker-compose up
...

Also, nginx on docker hub indicates that /etc/nginx is the proper configuration folder for nginx, so I don't think that mapping things to /home/... is going to do anything. nginx should display a default page however.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...