首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >码头组成nginx,快递,让SSL加密得到502坏网关

码头组成nginx,快递,让SSL加密得到502坏网关
EN

Stack Overflow用户
提问于 2019-09-01 03:54:50
回答 4查看 2.3K关注 0票数 0

我试图找到一种方法来发布nginx,express,和letsencrypt的ssl一起使用坞-撰写。关于这方面有很多文档,所以我引用了这些文档并尝试进行自己的配置,成功地从这个nginx + ssl配置了https://medium.com/@pentacent/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71

因此,现在我想把样例nodejs express应用程序放到nginx + ssl对接-撰写中。但我不知道为什么,我从nginx获得502 Bad Gateway,而不是express的初始页面。

我正在用左域名测试这个应用程序,并在aws ec2 ubuntu16上进行测试。我认为域dns和安全规则设置没有问题。所有80,443,3000个港口已经开放。当我在没有特快应用的情况下测试它时,它显示了很好的nginx默认页面。

nginx conf in /etc/nginx/conf.d

代码语言:javascript
复制
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com;
    server_tokens off;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    ssl_certificate /etc/letsencrypt/live/sendpi.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sendpi.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

}

docker-compose.yml

代码语言:javascript
复制
version: '3'

services:
  app:
    container_name: express
    restart: always
    build: .
    ports: 
      - '3000:3000'
  nginx:
    container_name: nginx
    image: nginx:1.15-alpine
    restart: unless-stopped
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    image: certbot/certbot
    restart: unless-stopped
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

特快文档

代码语言:javascript
复制
FROM node:12.2-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

我认为SSL运行良好,但express appnginx之间存在一些问题。我怎么才能解决这个问题?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-09-01 04:20:58

代码语言:javascript
复制
proxy_pass http://localhost:3000

正在将请求代理到运行nginx的容器上的3000端口。相反,您希望连接到运行express的容器的3000端口。为此,我们需要做两件事。

首先,我们让nginx容器在预定义的主机名下可见。我们可以将链接应用于船坞写作.

代码语言:javascript
复制
nginx:
  links:
    - "app:expressapp"

或者,由于链接现在被认为是遗留特性,更好的方法是使用用户定义的网络。定义一个你自己的网络

代码语言:javascript
复制
docker network create my-network 

然后通过在顶层添加以下内容,将容器连接到撰写文件中的网络:

代码语言:javascript
复制
networks:
    default:
        external:
            name: my-network

连接到用户定义网络的所有服务都可以通过名称相互访问,而无需显式设置链接。

然后在nginx.conf中,我们使用该主机名代理到快递容器:

代码语言:javascript
复制
location / {
    proxy_pass http://app:3000
}
票数 1
EN

Stack Overflow用户

发布于 2019-09-01 23:07:04

警告--link标志是Docker的遗留特性。它最终可能会被移除。除非您绝对需要继续使用它,否则我们建议您使用用户定义网络来方便两个容器之间的通信,而不是使用--link

docker-compose.yml中定义网络并使用适当的网络配置服务:

代码语言:javascript
复制
version: '3'

services:
  app:
    restart: always
    build: .
    networks:
      - backend
    expose:
      - "3000"
  nginx:
    image: nginx:1.15-alpine
    restart: unless-stopped
    depends_on:
      - app
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    networks:
      - frontend
      - backend
    ports:
      - "80:80"
      - "443:443"
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    image: certbot/certbot
    restart: unless-stopped
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
networks:
  frontend:
  backend:

注意事项app服务不再将它的端口发布到主机,它只公开端口3000 (ref )。( 公开和发布端口),它仅适用于连接到backend网络的服务。nginx服务在backendfrontend网络中都有一只脚,可以接收来自frontend的传入流量,并代理到backend中的app连接(ref )。多主机联网)。

使用用户定义网络,您可以解析服务名称:

代码语言:javascript
复制
user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
  worker_connections 1024;
}
http {
  upstream app {
    server app:3000 max_fails=3;
  }
  server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
  }
  server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com;
    server_tokens off;

    location / {
        proxy_pass http://app;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    ssl_certificate /etc/letsencrypt/live/sendpi.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sendpi.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  }
}

从服务中删除container_name使规模服务成为可能:docker-compose up -d --scale nginx=1 app=3 - nginx负载平衡循环中的流量转到3 app容器。

票数 1
EN

Stack Overflow用户

发布于 2019-09-01 04:47:24

我认为,这里的一个原因可能是"localhost“名称在docker-compose中运行的服务之间的行为方式。按照docker-组合您的容器的方式,每个容器都将自己理解为"localhost",因此"localhost“并不指主机(如果我没有弄错,那么运行在主机上的容器就无法访问主机端口上公开的服务,除了一些安全漏洞之外)。展示:

代码语言:javascript
复制
services:
  app:
    container_name: express
    restart: always
    build: .
    ports: 
      - '2999:3000' # expose app's port on host's 2999

重建

代码语言:javascript
复制
docker-compose build
docker-compose up

告诉运行快递应用程序的容器在3000端口上使用它自己的运行服务:

代码语言:javascript
复制
$ docker-compose exec app /bin/bash -c "curl http://localhost:3000"

<!DOCTYPE html>
<html>
  <head>
    <title>Express</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1>Express</h1>
    <p>Welcome to Express</p>
  </body>
</html>

告诉app尝试使用我们在主机上的端口2999上公开的服务:

代码语言:javascript
复制
$ docker-compose exec app /bin/bash -c "curl http://localhost:2999"
curl: (7) Failed to connect to localhost port 2999: Connection refused

当然,在运行容器之间也会看到同样的行为,因此在您的设置中,nginx试图代理它在localhost上运行的自己的服务:3000(但正如您所知,没有一个)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57743088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档