5

Im not an expert with docker, I am just getting used to it. I want to copy ssl certificates, which are generated on the host machine to my docker container. I read that it should be able to do with volumes argument in the docker-compose file but starting my server it always excites as it cannot find the copied files within the working directory.

Folderstructure

- repo
   - backend
      - api
         - static
            - ssl
         - dockerfile
   - frontend
   - docker-compose.yml

Dockerfile

FROM node:14-alpine

ENV NODE_ENV=production SERVER_PORT_HTTP=80 SERVER_PORT_HTTPS=443

WORKDIR /usr/src/app

RUN npm install

COPY . .

EXPOSE ${SERVER_PORT_HTTP} ${SERVER_PORT_HTTPS}

CMD [ "npm", "run", "start" ]

Docker-Compose

version: "3"

services:
  api:
    build:
      context: ./backend/api
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/letsencrypt/live/api.example.com:/static/ssl
    restart: unless-stopped
anemyte
  • 17,618
  • 1
  • 24
  • 45
nixn
  • 1,337
  • 3
  • 16
  • 33
  • What's the actual error? What causes your application to know to look in the `/static/ssl` directory; is that specific directory where it would ordinary expect to find certificates? – David Maze Apr 16 '21 at 11:25
  • 1
    If it's not mandatory to do it at build stage, you can use [docker cp](https://docs.docker.com/engine/reference/commandline/cp/) – Marte Valerio Falcone Apr 16 '21 at 12:14
  • @DavidMaze Yes, I wanted to reduce complexity by letting nodejs handle ssl - in comparison to an additional container and nginx. I told my server to lookup for the certs in the project folder `/static/ssl`. On my host I am running a cronjob that renews the certs to `/etc/letsencrypt/live/api.example.com` but it does not copy or link them to the container. Therefor I get ` Error: ENOENT: no such file or directory, open './static/ssl/privkey.pem'` error. – nixn Apr 16 '21 at 12:18
  • `./static/ssl` relative to the current directory is a different from `/static/ssl` in the root directory. Try changing the mount target to `/usr/src/app/static/ssl`. – David Maze Apr 16 '21 at 12:21

1 Answers1

7

You did everything right, the problem is with the files. If you look at them, you'll see that they're not normal files but links:

root@fbe56bc38ad6:/# ls /etc/letsencrypt/live/example.com/ -l
total 4
-rw-r--r-- 1 root root 692 Jul 24  2020 README
lrwxrwxrwx 1 root root  44 Mar 22 00:03 cert.pem -> ../../archive/example.com/cert5.pem
lrwxrwxrwx 1 root root  45 Mar 22 00:03 chain.pem -> ../../archive/example.com/chain5.pem
lrwxrwxrwx 1 root root  49 Mar 22 00:03 fullchain.pem -> ../../archive/example.com/fullchain5.pem
lrwxrwxrwx 1 root root  47 Mar 22 00:03 privkey.pem -> ../../archive/example.com/privkey5.pem
lrwxrwxrwx 1 root root  42 Mar  1 12:57 example.com -> /etc/letsencrypt/live/example.com
lrwxrwxrwx 1 root root  33 Mar  1 12:57 ssl-dhparams.pem -> /etc/letsencrypt/ssl-dhparams.pem

And so you mounted a bunch of relative links that point to a non-existent location.

I suggest you mount /etc/letsencrypt to /etc/letsencrypt in container:

    volumes:
      - /etc/letsencrypt:/etc/letsencrypt

Then make your application to look for files in /etc/letsencrypt/live/example.com or make another link at /static/ssl that points to /etc/letsencrypt/live/example.com:

ln -s /etc/letsencrypt/live/example.com /static/ssl
anemyte
  • 17,618
  • 1
  • 24
  • 45
  • Thank you for this solution. It works right out of the box, only thing was that I had to put the absolute path in my server configuration for loading the certs as you mentioned. Can you show me an example how I can create the second link from your answer within the docker-compose file? – nixn Apr 16 '21 at 12:28
  • 1
    @nixn I'm afraid you cannon manage links with docker-compose (not easily at least). You can create one using Dockerfile though: `RUN mkdir /static && ln -s /etc/letsencrypt/live/example.com /static/ssl`. – anemyte Apr 16 '21 at 12:33