Docker部署Pacman应用:Nginx负载均衡失效排查及无Nginx运行方案
一、先修复当前Nginx负载均衡的运行问题
你遇到的问题核心是端口配置不匹配和负载均衡算法设置不符合需求,我帮你一步步梳理修正:
1. 应用容器的端口配置错误
你的应用容器用的是Nginx镜像,但Dockerfile里写了EXPOSE 3000——可Nginx默认监听的是80端口,你根本没修改它的配置,所以负载均衡里指向3000端口肯定连不上。
修改后的应用容器Dockerfile:
FROM nginx:latest RUN apt-get update && apt-get install -y git RUN rm -R /usr/share/nginx/html/ RUN git clone https://github.com/daleharvey/pacman.git /usr/share/nginx/html/ RUN chmod -R 755 /usr/share/nginx/html/* RUN chown -R www-data /usr/share/nginx/html/* # 容器内Nginx默认运行在80端口,修正EXPOSE配置 EXPOSE 80
2. 负载均衡Nginx的端口与映射不匹配
你的docker-compose里把负载均衡Nginx的容器80端口映射到了主机的8000,但nginx.conf里配置的是listen 8080;——这就导致主机8000的请求进了容器的80端口,但容器里的Nginx根本没在80监听,自然无法响应。另外你要求用轮询算法,但当前配置用的是least_conn;(最少连接数算法),需要改成默认的轮询(可以显式写round_robin,或者直接去掉,Nginx默认就是轮询)。
修改后的负载均衡nginx.conf:
worker_processes 4; events { worker_connections 1024; } http { upstream mysite { # 显式指定轮询算法,也可以去掉这句,Nginx默认就是轮询 round_robin; server pacman1:80; server pacman2:80; server pacman3:80; } server { # 监听容器内80端口,对应docker-compose的端口映射规则 listen 80; server_name _; location / { proxy_pass http://mysite; 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; } } }
3. 优化docker-compose配置
给容器加个名字方便调试,同时让负载均衡容器依赖应用容器,确保应用先启动:
version: '3' services: pacman1: build: ./pacman container_name: pacman_app_1 pacman2: build: ./pacman container_name: pacman_app_2 pacman3: build: ./pacman container_name: pacman_app_3 nginx-lb: image: nginx:latest container_name: production_nginx_lb volumes: - ./nginx.conf:/etc/nginx/nginx.conf ports: ['8000:80'] depends_on: - pacman1 - pacman2 - pacman3 # 如果不用Redis可以注释掉这部分 # redis: # image: redis # ports: ['6379']
改完这些后,执行docker-compose up --build,就能正常访问主机的8000端口,请求会被轮询分发到三个应用容器。
二、不使用Nginx运行静态应用的方案
静态应用只需要一个能提供文件服务的HTTP服务器就行,这里给你推荐几种轻量替代方案:
1. Python内置HTTP服务器(适合测试场景)
用Python镜像代替Nginx,利用Python自带的http.server模块,配置最简单:
FROM python:3-alpine RUN apk add --no-cache git RUN git clone https://github.com/daleharvey/pacman.git /app WORKDIR /app EXPOSE 8000 CMD ["python", "-m", "http.server", "8000"]
对应的负载均衡nginx.conf里,upstream要改成server pacman1:8000;,其他配置和之前类似。
2. Node.js的http-server(适合生产环境的轻量选择)
http-server是Node生态里专门用于静态文件服务的工具,支持gzip、缓存等特性:
FROM node:alpine RUN npm install -g http-server RUN git clone https://github.com/daleharvey/pacman.git /app WORKDIR /app EXPOSE 8080 # -g开启gzip压缩,提升资源加载速度 CMD ["http-server", "-p", "8080", "-g"]
负载均衡的upstream要指向pacman1:8080。
3. Caddy(自带HTTPS的现代化服务器)
Caddy是一款轻量且配置简洁的HTTP服务器,自动支持HTTPS(如果有域名的话),默认就能很好地处理静态文件:
FROM caddy:alpine RUN git clone https://github.com/daleharvey/pacman.git /usr/share/caddy EXPOSE 80 443 # 启动文件服务,指定根目录和监听端口 CMD ["caddy", "file-server", "--root", "/usr/share/caddy", "--listen", ":80"]
负载均衡的upstream直接指向pacman1:80即可,无需额外复杂配置。
内容的提问来源于stack exchange,提问作者 Julie

