我已使用 docker 成功在 Amazon Ec2 上部署了 django 后端 api。
我的第一步是尝试放入一个 dockerized Nginx 来充当反向代理。然后,我最终打算使用静态媒体文件缓存和专用的实时媒体流服务器。我正在使用以下存储库 https://github.com/tiangolo/nginx-rtmp-docker/tree/master 它安装了必要的 nginx 模块,包括我稍后需要的 rtmp 模块。
但是,当涉及到反向代理时,nginx 端没有任何响应,这是我正在测试的第一个配置。
以下是我查到的。
- 在安全组 - 自定义 tcp 中添加端口 70 作为 EC2 的侦听端口。
- 通过检查 docker stats 可以看到两个容器都在运行
- 使用 docker ps 检查端口映射,端口映射正确。
- 在我启动 2 个容器以及 70(nginx 侦听端口)和 80(api 侦听端口)后,使用 netstat 检查端口是否列出 已列出。
- 当我点击 EC2 服务器的公共静态 IP 34.XX.XX.XX:80/ 时,api 服务器仍然可以工作,但当我点击 34.XX.XX.XX:70/ 时,API 服务器就不行了,它应该将请求代理到端口 80 .
这是我的配置。请注意,我没有在 docker-compose.yml 中附加 postgresql-db 和 redis-db 的配置,因为我相信它们与问题无关,但它们是侦听其他端口的其他 2 个容器。
docker-compose.yml
services:
webserver:
container_name: myapp-api
build:
dockerfile: Dockerfile
context: ./.docker/api
privileged: True
extra_hosts:
- db.myapp:172.16.16.4
- redis.myapp:172.16.16.5
volumes:
- ./:/opt/myapp-api-core
ports:
- '80:8080' # External listen port 80 mapped to interal docker port 8080
working_dir: /opt/myapp-api-core
networks:
myapp:
ipv4_address: 172.16.16.1
depends_on:
- db
- redis
env_file:
- .docker-compose.env
nginx-media_server:
container_name: myapp-nginx-media-server
build:
dockerfile: Dockerfile
context: ./.docker/nginx-media-server
ports:
- 70:1652 # External Caching server listen port mapped to internal docker container port 1652.
volumes:
- ./.docker-cache/static:/tmp/nginx
- ./.docker/nginx-media-server/nginx.conf:/etc/nginx/nginx.conf
- ./.docker/nginx-media-server/log:/var/log/nginx # Logs
networks:
myapp:
ipv4_address: 172.16.16.6
env_file:
- .docker-compose.env
nginx.conf
worker_processes auto;
events {
use epoll;
}
# HTTP block
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $request_time';
# Access & Error Logs
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
default_type application/octet-stream;
include /etc/nginx/mime.types;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# Increase the maximum size of the hash table
proxy_headers_hash_max_size 1024;
# Increase the bucket size of the hash table
proxy_headers_hash_bucket_size 128;
#Note that these are defined outside of the server block altho they don't necessarily need to be
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=60m max_size=20g;
proxy_cache_key "$scheme$request_method$host$request_uri";
server {
listen 70 default_server;
server_name _;
access_log /var/log/nginx/access.log ;
error_log /var/log/nginx/error.log;
location / {
proxy_cache my_zone;
proxy_cache_bypass $http_cache_control;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include proxy_params;
proxy_pass http://172.16.16.1:8080;
# WebSocket support (nginx 1.4)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
Dockerfile(Nginx 媒体服务器)
FROM buildpack-deps:bullseye
LABEL maintainer="Sebastian Ramirez <[email protected]>"
# Versions of Nginx and nginx-rtmp-module to use
ENV NGINX_VERSION nginx-1.23.2
ENV NGINX_RTMP_MODULE_VERSION 1.2.2
# Install dependencies
RUN apt-get update && \
apt-get install -y ca-certificates openssl libssl-dev && \
rm -rf /var/lib/apt/lists/*
# Download and decompress Nginx
RUN mkdir -p /tmp/build/nginx && \
cd /tmp/build/nginx && \
wget -O ${NGINX_VERSION}.tar.gz https://nginx.org/download/${NGINX_VERSION}.tar.gz && \
tar -zxf ${NGINX_VERSION}.tar.gz
# Download and decompress RTMP module
RUN mkdir -p /tmp/build/nginx-rtmp-module && \
cd /tmp/build/nginx-rtmp-module && \
wget -O nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}.tar.gz https://github.com/arut/nginx-rtmp-module/archive/v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \
tar -zxf nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}.tar.gz && \
cd nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}
# Build and install Nginx
# The default puts everything under /usr/local/nginx, so it's needed to change
# it explicitly. Not just for order but to have it in the PATH
RUN cd /tmp/build/nginx/${NGINX_VERSION} && \
./configure \
--sbin-path=/usr/local/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx/nginx.lock \
--http-log-path=/var/log/nginx/access.log \
--http-client-body-temp-path=/tmp/nginx-client-body \
--with-http_ssl_module \
--with-threads \
--with-ipv6 \
--add-module=/tmp/build/nginx-rtmp-module/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION} --with-debug && \
make -j $(getconf _NPROCESSORS_ONLN) && \
make install && \
mkdir /var/lock/nginx && \
rm -rf /tmp/build
# Forward logs to Docker
RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log
# Set up config file
COPY nginx.conf /etc/nginx/nginx.conf
# Install ffmpeg
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y ffmpeg
VOLUME ["/tmp/nginx","/etc/nginx/nginx.conf","/var/log/nginx"]
# Expose internal docker ports attached to external receiver ports.
EXPOSE 1652
CMD ["nginx", "-g", "daemon off;"]
编辑:
基于@0xn0b174发布的问题 -->
您可以检查一下 ec2 安全组中端口 70 的入站规则吗 你添加了什么??
Port Source Protocol Description
70 0.0.0.0/0 TCP NGINX Caching server
您已将 1652 docker 端口映射到端口 70,您可以确认一下吗? 服务正在 1652 docker 容器内运行。
您可以分享 docker exec -it myapp-nginx-media-server 的输出吗 ping 172.16.16.1
OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown
最后你可以跟踪并分享 /var/log/nginx/error.log 和 docker 日志 docker 日志 myapp-nginx-media-server
显示几个小时前的日志,其中的错误已被纠正。使用 docker copy 命令
2024/09/07 04:16:46 [emerg] 1#1: invalid log level "main" in /etc/nginx/nginx.conf:16
2024/09/07 04:18:21 [emerg] 1#1: invalid log level "main" in /etc/nginx/nginx.conf:16
2024/09/07 06:22:32 [emerg] 1#1: host not found in upstream "api:8080" in /etc/nginx/nginx.conf:187
2024/09/07 06:24:37 [emerg] 1#1: invalid host in upstream "http://172.16.16.1:8080/" in /etc/nginx/nginx.conf:187
2024/09/07 06:27:15 [emerg] 1#1: invalid host in upstream "http://172.16.16.1:8080/" in /etc/nginx/nginx.conf:187
2024/09/07 07:27:28 [notice] 11#11: signal process started
2024/09/07 07:27:31 [notice] 20#20: signal process started
2024/09/07 07:29:01 [emerg] 1#1: unexpected end of file, expecting "}" in /etc/nginx/nginx.conf:444
docker.logs
docker logs --since=1h cc1274f259d4 > /home/ubuntu/docker_logs.txt
Above log is empty
编辑2:
我进行了全新安装。 nginx error.log 和 access.log 为空。 检查 docker ps 后端口映射正确。
我进入了 nginx 容器并执行了 nginx -t
我得到了这个:
nginx:配置文件/etc/nginx/nginx.conf语法没问题 nginx:配置文件/etc/nginx/nginx.conf测试成功
您的设置应该非常简单,不知道为什么要使绑定不同端口复杂化,但这里是 nginx 和 docker conatiner 在 ec2 中运行的简单设置:
docker-compose.yml
services:
web:
container_name: django-api
build:
context: ./django
dockerfile: Dockerfile
volumes:
- ./django/app:/app
expose:
- "8000" # Expose internal Django port
networks:
- myapp-network
nginx:
container_name: nginx
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- "80:80" # Expose port 80 for the public to access
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web
networks:
- myapp-network
networks:
myapp-network:
driver: bridge
./django/Dockerfile
# Use official Python image from the dockerhub
FROM python:3.9-slim
# Set work directory
WORKDIR /app
# Install dependencies
COPY ./app /app
RUN pip install --upgrade pip && \
pip install -r /app/requirements.txt
# Expose port
EXPOSE 8000
# Command to run the app
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
./nginx/Dockerfile
FROM nginx:alpine
# Copy the custom nginx.conf to the container
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
./nginx/nginx.conf
worker_processes auto;
events { worker_connections 1024; }
http {
upstream django {
server web:8000; # The internal Django API service
}
server {
listen 80;
location / {
proxy_pass http://django;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
如果您可以模仿此设置,那么您就可以开始了。