cclloyd
cclloyd

Reputation: 9195

nginx ssl No such file or directory with docker

I have an nginx container set up with docker compose, that uses certs generated on the host machine. But when I run it, It tells me the cert isn't found.

nginx | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/etc/letsnecrypt/live/example.com/privkey.key") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsnecrypt/live/example.com/privkey.key','r') error:20074002:BIO routines:file_ctrl:system lib error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib)

But when I go into the container using docker-compose run nginx /bin/bash and go to the cert folder, they do exist.

So why am I getting the error?

My nginx conf:

server {
    listen *:443;
    server_name             example.com;

    ssl_certificate         /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key     /etc/letsnecrypt/live/example.com/privkey.key;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    access_log              /dev/stdout upstreamlog;
    error_log               /dev/stderr debug;

}

docker-compose.yml:

version: '3.5'

services:
  nginx:
    container_name: nginx
    image: nginx
    restart: unless-stopped
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
    - ./nginx.default:/etc/nginx/conf.d/default.conf
    - /etc/letsencrypt:/etc/letsencrypt

Upvotes: 4

Views: 9933

Answers (2)

Short Cord
Short Cord

Reputation: 131

I'm not sure if this would answer the question but this did fix my issue which was very similar to yours.


Short (possible) answer:

Certbot makes a softlink to each file in live back to a numbered file in archive/domain.com/.

It could be possible that the softlinks are breaking in some way when you do docker-compose up.


Explanation

I had a similar issue on my setup, my docker-compose.yml was setup like this

services:
  web:
    image: nginx:alpine
    volumes:
      - ./letsencrypt/etc/live/${DOMAIN}/:/var/certs/:ro

./letsencrypt/etc/ being where Certbot puts the resulting certificates.

Certbot makes a softlink from live to ../../archive/domain.com/ so when I did docker-compose run web /bin/sh to view the filesystem, I found broken links!

/certs # ls -la
total 12
drwxr-xr-x    2 root     root          4096 Aug 31 17:25 .
drwxr-xr-x   33 root     root          4096 Aug 31 17:44 ..
-rw-r--r--    1 root     root           682 Aug 31 17:25 README
lrwxrwxrwx    1 root     root            37 Aug 31 17:25 cert.pem -> ../../archive/domain.com/cert1.pem
lrwxrwxrwx    1 root     root            38 Aug 31 17:25 chain.pem -> ../../archive/domain.com/chain1.pem
lrwxrwxrwx    1 root     root            42 Aug 31 17:25 fullchain.pem -> ../../archive/domain.com/fullchain1.pem
lrwxrwxrwx    1 root     root            40 Aug 31 17:25 privkey.pem -> ../../archive/domain.com/privkey1.pem

The simple solution was to edit the docker-compose.yml file to go back afew directories.

services:
  web:
    image: nginx:alpine
    volumes:
      - ./letsencrypt/etc/${DOMAIN}/:/var/certs/:ro

Once the nginx configs matched the new location nginx found the certificates without an issue.

Upvotes: 13

Raymond Cheng
Raymond Cheng

Reputation: 2495

The problem you meet is before your nginx start the cert file does not exist in nginx container.

you should copy certificate before starting the container.

try to make a Dockfile under nginx folder like this:

FROM nginx:1.12.1-alpine

COPY letsencrypt /etc/letsencrypt/ /** letsencrypt folder contains certificatefiles **/

and your docker-compose.yml should like this:

services:
      nginx-server:
         build: ./nginx
         volumes:
           .......
         expose:
           - 80
           - 443
         ports:
           - "80:80"
           - "443:443"
         container_name: nginx-server

Upvotes: 1

Related Questions