Docker on Google 尽管设置了防火墙规则,Compute Engine 仍无法访问端口 80

Docker on Google Compute Engine can't access port 80 despite setting firewall rules

我在计算引擎上有一个容器 运行 Django、Nginx 和 Gunicorn 运行

我可以成功部署并通过 SSH 连接到 VM,但无法访问容器的外部 URL 尽管创建了多个防火墙规则。

即使从 VM 中公开它,它似乎也对端口 80 关闭。

我该如何解决这个问题?

这是我的副本:

docker-撰写文件:

version: '3'

services: 
  web:
    build:
      context: ./
      dockerfile: Dockerfile.prod
    image: app-name:prod
    volumes:
      - static_volume:/home/app/web/staticfiles 
      - media_volume:/home/app/web/mediafiles
    ports:
      - 8000:8000
    command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
    env_file:
      - ./.env.prod
    depends_on:
      - db

  db:
    image: postgres:10-alpine
    env_file:
      - ./.env.prod
    volumes:
      - pgdata:/var/lib/postgresql/data
    expose:
      - 5432

  nginx:
    build: ./nginx
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    ports:
      - 1337:80
    depends_on:
      - web

volumes:
  pgdata:
  static_volume:
  media_volume:

NGINX 配置文件:

upstream core {
    server web:8000;
}

server {

    listen 80 default_server;
    listen [::]:80 ipv6only=on;

    location / {
        proxy_pass http://core;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /staticfiles/ {
        alias /home/app/web/staticfiles/;
    }

    location /mediafiles/ {
        alias /home/app/web/mediafiles/;
    }

}

Docker 文件:

##################################
# THIS IS A MULTI-STAGE BUILD TO #
# REDUCE THE SIZE OF THE IMAGE.  #
##################################

# BUILDER

FROM python:3.9.2-alpine3.12 as builder

WORKDIR /usr/src/app

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN apk update \
    && apk add postgresql-dev gcc musl-dev

RUN pip install --upgrade pip
RUN pip install flake8
COPY . .
RUN flake8 --ignore=E501,F401 .

COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt


# FINAL

FROM python:3.9.2-alpine3.12

RUN mkdir -p /home/app

RUN addgroup -S app && adduser -S app -G app

ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/staticfiles
RUN mkdir $APP_HOME/mediafiles
WORKDIR $APP_HOME

RUN apk update && apk add libpq
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*

COPY ./entrypoint.prod.sh $APP_HOME

COPY . $APP_HOME

RUN chown -R app:app $APP_HOME

USER app

NGINX Dockerfile:

FROM nginx:1.19.0-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

这是我在设置 VM 时遵循的类似步骤:Why is Google Compute Engine not running my container?

这是我尝试访问端口 80 时遇到的错误:curl: (7) Failed to connect to 35.XXX.XX.XXX port 80: Connection refused

编辑: 添加了应用程序 Dockerfile 和 NGINX Dockerfile

您遇到的错误可能是由防火墙规则阻止流量或容器未在端口 80 上侦听引起的。

为了确保 create 新的防火墙规则明确允许在端口 80 上连接到此主机;

$ gcloud compute firewall-rules create default-allow-http --direction=INGRESS --priority=1000 --network=default --action=ALLOW --rules=tcp:80 --source-ranges=0.0.0.0/0 --target-tags=http-server
Creating firewall...⠹
Created [https://www.googleapis.com/compute/v1/projects/qqqq/global/firewalls/default-allow-http].                   
Creating firewall...done.                                                                                                                            
NAME                NETWORK  DIRECTION  PRIORITY  ALLOW   DENY  DISABLED
default-allow-http  default  INGRESS    1000      tcp:80        False

只需确保您的主机 VM 已连接 http-server network-tag

然后使用nmap检查端口是否打开:

$ nmap -Pn ip.to.check.xxx
Starting Nmap 7.70 ( https://nmap.org ) at 2021-03-16 12:04 CEST
PORT   STATE SERVICE
...
80/tcp open  http

如果您看到 80/tcp open http,则表示该端口已打开并且有应用程序正在侦听。如果不是并且防火墙规则处于活动状态,那么您必须查看您的容器 nginx 配置。如果您提供更多详细信息 (dockerfile) 来重现您的问题,则可能会进一步解决此问题。

此外 - 如果您是 运行 手动容器(不使用 Container Optimized OS),那么 这可能对您有所帮助。

----更新-----这实际上有帮助:

在compose文件中更改nginx服务的端口;而不是 - 1337:80 尝试另一种方式: - 80:1337.

根据 Docker networking docs 值应该是相反的。