apache - 连接到上游时连接被拒绝 - Docker
问题描述
我得到的错误:
nginx_prod_vet | 2019/03/07 20:57:11 [error] 6#6: *1 connect() failed (111: Connection refused) while connection to upstream, client: 172.23.0.1, server: , request: "GET /backend HTTP /1.1”,上游:“ http://172.23.0.2:81/backend ”,主机:“localhost:90”
我的目标是使用 nginx 作为反向代理来传递前端文件并将其他服务代理到前端,因此可以从 localhost:90/ 调用 localhost:90/backend。
我试图从容器外部访问后端,但它给了我上面的错误。
以下是最相关的文件:
# docker-compose.yml
version: '3'
services:
nginx:
container_name: nginx_prod_vet
build:
context: .
dockerfile: nginx/prod/Dockerfile
ports:
- "90:80"
volumes:
- ./nginx/prod/prod.conf:/etc/nginx/nginx.conf:ro
networks:
- main
depends_on:
- backend
backend:
container_name: backend_prod_vet
build:
context: .
dockerfile: apache/Dockerfile
ports:
- "81:81"
networks:
- main
networks:
main:
driver: bridge
# apache/Dockerfile
FROM httpd:2.4.32-alpine
RUN apk update; \
apk upgrade;
# Copy apache vhost file to proxy php requests to php-fpm container
COPY apache/apache.conf /usr/local/apache2/conf/apache.conf
RUN echo "Include /usr/local/apache2/conf/apache.conf" \
>> /usr/local/apache2/conf/httpd.conf
# apache/apache.conf
ServerName localhost
LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so
<VirtualHost *:81>
# Proxy .php requests to port 9000 of the php-fpm container
# ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
DocumentRoot /var/www/html/
<Directory /var/www/html/>
# DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Send apache logs to stdout and stderr
CustomLog /proc/self/fd/1 common
ErrorLog /proc/self/fd/2
</VirtualHost>
# nginx/prod/prod.conf
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
client_max_body_size 100m;
upstream backend {
server backend:81;
}
server {
listen 80;
charset utf-8;
root /dist/;
index index.html;
location /backend {
proxy_redirect off;
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
}
# nginx/prod/Dockerfile
# build stage
FROM node:10.14.2-jessie as build-stage
WORKDIR /app/
COPY frontend/package.json /app/
RUN npm cache verify
RUN npm install
COPY frontend /app/
RUN npm run build
# production stage
FROM nginx:1.13.12-alpine as production-stage
COPY nginx/prod/prod.conf /etc/nginx/nginx.conf
COPY --from=build-stage /app/dist /dist/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
编辑:
docker-compose exec 后端 netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.11:38317 0.0.0.0:* LISTEN -
tcp 0 0 :::80 :::* LISTEN 1/httpd
docker-compose exec nginx sh -c "nc backend 81 && echo 打开 || echo 关闭"
closed.
解决方案
docker-compose exec backend netstat -lnpt
向我们展示了用于服务的 httpd 网络服务器backend
正在侦听端口80
而不是81
.
所以必须可能,您的 Dockerfileapache/Dockerfile
关于它如何尝试提供您的自定义 httpd 配置是不正确的apache/apache.conf
。
进一步调查:
- 确保主要的 apache conf 内容是您所期望的:
docker-compose exec backend cat /usr/local/apache2/conf/httpd.conf
- 检查您的后端服务日志:
docker-compose logs backend
这样做,您将意识到您缺少Listen 81
主 apache 配置文件中的指令。您可以在apache/Dockerfile
文件中解决此问题:
# apache/Dockerfile
FROM httpd:2.4.32-alpine
RUN apk update; \
apk upgrade;
# Copy apache vhost file to proxy php requests to php-fpm container
COPY apache/apache.conf /usr/local/apache2/conf/apache.conf
RUN echo "Listen 81" >> /usr/local/apache2/conf/httpd.conf
RUN echo "Include /usr/local/apache2/conf/apache.conf" >> /usr/local/apache2/conf/httpd.conf
为什么你的后端容器监听 81 端口?
它不会增加任何价值来使您的不同容器打开不同的端口。每个容器都有自己的 IP 地址,因此不需要避免 docker-compose 项目中定义的服务之间的端口冲突。
推荐阅读
- python-3.x - Glade GtkFileChooserDialog 正在选择文件夹和文件
- sql - 传递变量时将 datetime 转换为 varchar 不起作用
- ios - if else 使用三元
- python - 在python中解析和转换嵌套的xml
- c++ - 将两位数转换为低内存表示的最快方法
- aws-lambda - 如何为 AWS Cognito 用户创建对 url 友好的 ID?
- graphql - 使用 libgraphqlparser 工作的 c++ 示例
- python - 如何比较两个字符串中的字符序列
- json - 如何在 JSON 对象的同一查询 JMES 路径中返回子节点和父节点属性
- .net - 无法使用 IdentityServer3.AccessTokenValidation 验证令牌