Docker nginx错误:openssl:命令未找到。

4

我正在使用nginx作为代理将请求转发到其他组件(服务器)。

每个组件,包括nginx都是以docker容器的形式实现的,即我有一个针对'nginx-proxy'、'dashboard-server'、'backend-server'(REST API)和'landing-server'(落地页)的docker容器。最后三个组件都是NodeJS Express服务器,当我使用命令docker-compose build时没有错误,但是当我使用docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d启动容器时,NodeJS容器正常工作,但是nginx容器在使用docker-compose logs nginx-proxy时出现了这个错误:

Attaching to docker_nginx-proxy_1
nginx-proxy_1       | /start.sh: line 5: openssl: command not found
nginx-proxy_1       | Creating dhparams…\c
nginx-proxy_1       | ok
nginx-proxy_1       | Starting nginx…
nginx-proxy_1       | 2017/08/23 23:27:20 [emerg] 6#6:
BIO_new_file(“/etc/letsencrypt/live/admin.domain.com/fullchain.pem”) 
failed (SSL: error:02001002:system library:fopen:No such file or directory:
fopen(‘/etc/letsencrypt/live/admin.domain.com/fullchain.pem’,‘r’) error:2006D080:BIO routines:BIO_new_file:no such file)
nginx-proxy_1       | nginx: [emerg]
BIO_new_file(“/etc/letsencrypt/live/admin.domain.com/fullchain.pem”) failed (SSL: error:02001002:system library:fopen:
No such file or directory:fopen(‘/etc/letsencrypt/live/admin.domain.com/fullchain.pem’,‘r’)error:2006D080:BIO routines:BIO_new_file:no such file)

我正在使用Let's Encrypt进行SSL证书管理,但是当我执行命令certbot certonly --webroot -w /var/www/letsencrypt -d admin.domain.com -d api.domain.com -d www.domain.com -d domain.com时,出现连接被拒绝的错误,因为nginx服务器没有启动来处理请求。

我的nginx Dockerfile(nginx-proxy/Dockerfile):

FROM nginx:1.12

COPY start.sh /start.sh
RUN chmod u+x /start.sh

COPY conf.d /etc/nginx/conf.d

COPY sites-enabled /etc/nginx/sites-enabled

ENTRYPOINT ["/start.sh"]

这是我的start.sh文件(nginx-proxy/start.sh):

#!/bin/bash

if [ ! -f /etc/nginx/ssl/dhparam.pem ]; then
    echo "Creating dhparams…\c"
    openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
    echo "ok"
fi

echo "Starting nginx…"
nginx -g 'daemon off;

以下是我的 default.conf 文件(nginx-proxy/conf.d/default.conf):

include /etc/nginx/sites-enabled/*.conf;

我的 api.conf 文件(其他文件类似)(nginx-proxy / sites-enabled / api.conf):

server {
    listen 80;
    server_name api.domain.com;

    location ^~ /.well-known/acme-challenge/ {
      default_type "text/plain";
      root /var/www/letsencrypt;
    }

    location = /.well-known/acme-challenge/ {
      return 404;
    }

    return 301 https://$host$request_uri;
  }


  server {
    listen 443;
    server_name api.domain.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/api.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.domain.com/privkey.pem;

    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    ssl_prefer_server_ciphers on;

    ssl_session_cache shared:SSL:1m;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    client_max_body_size 0;
    chunked_transfer_encoding on;

    location ^~ /.well-known/acme-challenge/ {
      default_type "text/plain";
      root /var/www/letsencrypt;
    }

    location = /.well-known/acme-challenge/ {
      return 404;
    }

    location / {
        proxy_read_timeout  900;
        proxy_pass_header   Server;
        proxy_cookie_path   ~*^/.* /;
        proxy_pass          http://backend-server:3000;
        proxy_set_header    Host $http_host;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Port $server_port;
        proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
      }
  }

有什么想法吗?

2个回答

14

我找到了解决方法。

在我的nginx Dockerfile中,我必须使用

FROM nginx:1.12-alpine

RUN apk update \
    && apk add openssl


...

然后openssl命令正常工作。


0

首先,您可以尝试编辑您的start.sh文件,在openssl行中更改为/usr/bin/openssl/usr/bin/openssl是否存在?

其次,在/etc/letsencrypt/live/api.domain.com/fullchain.pem/etc/letsencrypt/live/api.domain.com/privkey.pem文件存在之前,您的nginx服务器将无法启动。

因此,请删除或注释所有处理443端口的服务器块,保留处理80端口的服务器块。 您的api.conf将变成这样:

server {
    listen 80;
    server_name api.domain.com;

    location ^~ /.well-known/acme-challenge/ {
      default_type "text/plain";
      root /var/www/letsencrypt;
    }

    location = /.well-known/acme-challenge/ {
      return 404;
    }

    return 301 https://$host$request_uri;
}

然后启动您的nginx服务器并重试安装Let's Encrypt证书。


当我将start.sh脚本更改为建议的状态时,我遇到了以下错误:/start.sh: 第5行:/usr/bin/openssl: 没有那个文件或目录 - Andi R.
但是你是否像我提到的那样启动了你的nginx服务器?只需注释掉ssl_dhparam这一行,我们就可以找出为什么你的docker无法运行openssl命令。 - Argus Duong
好的,现在只使用 /usr/bin/openssl 并将 *.conf 文件中的 SSL 代码注释掉可以使 nginx 服务器正确启动。但是现在我需要做什么才能正确配置 SSL 呢? - Andi R.
nginx HTTPS(SSL)可以在没有DH参数的情况下正常运行。您可以从Docker中运行此命令,或者尝试将其附加到您的start.sh文件中的“#!/bin/bash”后面:apt-get install libssl-dev。很抱歉我不能像Docker一样帮助您做到最好。 - Argus Duong
尽管"docker ps"显示我的nginx代理正在运行,但仍然出现“openssl:command not found”的错误消息。 - Andi R.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接