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 值应该是相反的。
我在计算引擎上有一个容器 运行 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 值应该是相反的。