【问题标题】:Nginx working outside Docker but not insideNginx 在 Docker 外部工作,但不在内部工作
【发布时间】:2018-09-09 18:00:21
【问题描述】:

我正在使用 Django、Gunicorn、Nginx 和 Docker 制作个人网站。当我执行时:

gunicorn --chdir personal-website --bind :8000 personal_website.wsgi:application

输出是:

[arturocuya@localhost personalwebsite]$ gunicorn --chdir personal-website --bind :8000 personal_website.wsgi:application
[2018-09-09 11:49:02 -0500] [5161] [INFO] Starting gunicorn 19.6.0
[2018-09-09 11:49:02 -0500] [5161] [INFO] Listening at: http://0.0.0.0:8000 (5161)
[2018-09-09 11:49:02 -0500] [5161] [INFO] Using worker: sync
[2018-09-09 11:49:02 -0500] [5165] [INFO] Booting worker with pid: 5165

它可以工作(有点,静态文件的配置尚未完成)

问题是当我使用sudo docker-compose up 运行Docker 容器时,我得到502 Bad Gateway

我怀疑问题出在我如何使用端口,但我真的不明白应该怎么做。

这是我的文件夹结构

.
├── config
│   └── nginx
│       └── conf.d
│           └── local.conf
├── docker-compose.yml
├── Dockerfile
└── personal-website
    └── manage.py

Dockerfile

# Start from an official image
FROM python:3.6

# The following is an arbitrary location choice
RUN mkdir -p /opt/services/personalwebsite/src
WORKDIR /opt/services/personalwebsite/src

# Copy the project code
COPY . /opt/services/personalwebsite/src

# Install dependencies
RUN pip install django gunicorn Pillow

# Expose Port 8000
EXPOSE 8000

# Define the default command to run when starting the container
CMD ["gunicorn", "--chdir", "personal-website", "--bind", ":8000", "personal_website.wsgi:application"]

docker-compose.yml

version: '3'

services:
  personalwebsite:
    build: .
    volumes:
      - .:/opt/services/personalwebsite/src
    networks:
     - nginx_network

  nginx:
    image: nginx:1.13
    ports:
      - 8000:80
    volumes:
      - ./config/nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - personalwebsite

    networks:
      - nginx_network

networks:
  nginx_network:
    driver: bridge

config/nginx/conf.d/local.conf

# first we declare our upstream server, which is our Gunicorn application
upstream personalwebsite_server {
    # docker will automatically resolve this to the correct address
    # because we use the same name as the service: "personalwebsite"
    server personalwebsite:8000;
}

# now we declare our main server
server {

    listen 80;
    server_name localhost;

    location / {
        # everything is passed to Gunicorn
        proxy_pass http://personalwebsite;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

我还确保在 Django 项目的 settings.py 中修改 ALLOWED_HOSTS

ALLOWED_HOSTS = ['127.0.0.1', '149.248.5.164', '0.0.0.0']

编辑 1: 正如 cmets 中有人建议的那样,我使用 sudo docker-compose exec nginx bash 访问了 Nginx 容器,然后使用了 curl personalwebsite:8000。我收到DISALLOWED HOST 错误,所以我将personalwebsite 添加到settings.py 中的允许主机,然后我再次尝试 curl,输出是我页面的 HTML,这很好。

这似乎在容器内起到了作用,因为输出是我页面的 HTML。但后来我做了sudo docker-compose up,我又得到了502 Bad Gateway。确切的输出是:

[arturocuya@localhost personalwebsite]$ sudo docker-compose up
[sudo] password for arturocuya: 
Starting personalwebsite_personalwebsite_1 ... done
Starting personalwebsite_nginx_1           ... done
Attaching to personalwebsite_personalwebsite_1, personalwebsite_nginx_1
personalwebsite_1  | [2018-09-10 02:07:12 +0000] [1] [INFO] Starting gunicorn 19.9.0
personalwebsite_1  | [2018-09-10 02:07:12 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
personalwebsite_1  | [2018-09-10 02:07:12 +0000] [1] [INFO] Using worker: sync
personalwebsite_1  | [2018-09-10 02:07:12 +0000] [10] [INFO] Booting worker with pid: 10
nginx_1            | 172.26.0.1 - - [10/Sep/2018:02:07:17 +0000] "GET / HTTP/1.1" 502 576 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36" "-"
nginx_1            | 2018/09/10 02:07:17 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.26.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://172.26.0.2:80/", host: "0.0.0.0:8000"
nginx_1            | 2018/09/10 02:07:18 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.26.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", upstream: "http://172.26.0.2:80/favicon.ico", host: "0.0.0.0:8000", referrer: "http://0.0.0.0:8000/"
nginx_1            | 172.26.0.1 - - [10/Sep/2018:02:07:18 +0000] "GET /favicon.ico HTTP/1.1" 502 576 "http://0.0.0.0:8000/" "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36" "-"

【问题讨论】:

  • 能否请您尝试进入 nginx 容器(docker-compose exec nginx bash)并在 personalwebsite:8000 上进行 curl 以查看连接是否正常?
  • @JakubBujny 我执行sudo docker-compose up -d 重新启动容器,然后sudo docker-compose exec nginx bash 如您所说的那样访问nginx 容器,但是当我尝试curl personalwebsite:8000 时在它内部,输出为bash: curl: command not found。我从来没有使用过 curl 所以很可能我做错了。
  • 没关系 - 只是没有安装 curl,先在容器 apt-get update && apt-get install -y curl 中尝试,然后运行 ​​curl 命令
  • 好的,我安装了它并尝试了curl personalwebsite:8000。输出是当您收到错误DISALLOWED HOST 时 Django 显示的调试页面。我在settings.pyALLOWED_HOSTS 列表中添加了personalwebsite,并在nginx 容器中再次尝试了curl personalwebsite:8000。这似乎在容器内起到了作用,因为输出是我页面的 HTML。但后来我做了sudo docker-compose up,我得到了502 Bad Gateway again。确切的输出将在下一条评论中:
  • [arturocuya@localhost personalwebsite]$ sudo docker-compose up Starting personalwebsite_personalwebsite_1 ... done Starting personalwebsite_nginx_1 ... done Attaching to personalwebsite_personalwebsite_1, personalwebsite_nginx_1 personalwebsite_1 | [2018-09-09 18:47:47 +0000] [1] [INFO] Starting gunicorn 19.9.0 personalwebsite_1 | [2018-09-09 18:47:47 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) personalwebsite_1 | [2018-09-09 18:47:47 +0000] [1] [INFO] Using worker: sync personalwebsite_1 | [2018-09-09 18:47:47 +0000] [10] [INFO] Booting worker with pid: 10

标签: django docker nginx gunicorn


【解决方案1】:

你的 Nginx 配置应该是

upstream personalwebsite {
    server personalwebsite:8000;
}

# now we declare our main server
server {

    listen 80;
    server_name localhost;

    location / {
        # everything is passed to Gunicorn
        proxy_pass http://personalwebsite;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

你的 Nginx 服务是否在容器内运行?

请在 Nginx 容器中点击以下命令并告诉我输出结果

curl -I localhost:80

【讨论】:

  • 天哪,它成功了。请解释为什么这是解决方案,以便其他人(和我)可以完全理解这一点。非常感谢!!!
【解决方案2】:

很容易理解,你的proxy_pass URL和upstream关键字应该是一样的

要深入了解 Nginx 上游配置,请通过 Link

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多