我正在使用docker-compose.yml在Ubuntu VPS上的nginx代理后面运行几个服务。
我遇到的问题是,我的docker容器无法使用其公开可用的代理URL相互访问。它们只能使用其docker服务名称相互访问。
最简单的演示方法如下。我可以使用以下命令从任何地方连接到我的Postgres实例:
psql -Atx postgres://username:pw@postgres.mysite.com/database
但是,如果我进入其中一个正在运行的容器:
docker compose exec backend sh
然后尝试使用相同的连接字符串连接,它就会卡住...甚至代理端也没有日志。但是,如果我使用docker服务名称,它可以正常工作:
psql -Atx postgres://username:pw@postgres:5432/database
我应该能够从容器内外的任何地方使用postgres.mysite.com
。但由于某种原因,我只能在容器外部使用它。这是与此相关的nginx配置部分:
upstream docker-postgres {
server postgres:5432;
}
server {
listen 443 ssl;
server_name postgres.mysite.com;
location / {
proxy_pass http://docker-postgres;
}
}
但这与postgres无关。无论服务如何,似乎都会发生这种情况。每当容器A(应用代码)尝试使用容器C中运行的公共可用URL连接到容器B(服务)时。
例如,对于我的MinIO服务,在上传到https://assets.mysite.com时会出现上传挂起的情况,但在上传到http://minio:9001时不会出现。
部分docker-compose.yml:
proxy:
image: nginx:alpine
ports:
- '80:80'
- '443:443'
networks:
- myNetwork
backend:
ports:
- '3000:3000'
volumes:
- ./:/app
- /app/node_modules
networks:
- myNetwork
postgres:
image: postgres:10.4
ports:
- "5432:5432"
networks:
- myNetwork
minio:
image: minio/minio
command: server --console-address ":9090" --address ":9001" ./minio_data
ports:
- '9090:9090'
- '9001:9001'
networks:
- myNetwork
networks:
myNetwork:
external: true
附加信息
我在代理服务器下的assets.mysite.com
server_name下设置了一个/test端点。
location /test { return 200 'success!!'; }
我可以从服务器(不在Docker容器内部)访问此端点:
curl https://assets.mysite.com/test
----> 成功
然而,我无法从任何容器内部访问它:
docker compose exec backend curl https://assets.mysite.com/test
---> 挂起!
尽管如此,我仍然可以成功ping通assets.mysite.com
,即使是从容器内部:
docker compose exec backend ping assets.mysite.com
编辑:这是我几乎完整的nginx配置(仅省略了SSL证书)
http {
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
return 301 https://$host$request_uri;
}
}
upstream docker-backend {
server backend:9000;
keepalive 100;
}
upstream docker-postgres {
server postgres:5432;
}
upstream docker-redis {
server redis:6379;
}
upstream docker-minio-assets {
server minio:9001;
}
server {
listen 443 ssl;
server_name mysite.com;
root /var/www/frontend;
index index.html;
location /test {
return 200 'success!!';
}
location /backend {
rewrite ^/backend(/.*)$ $1 break;
proxy_pass http://docker-backend;
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;
proxy_pass_request_headers on;
client_max_body_size 3m;
}
location / {
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html =404;
}
}
server {
listen 443 ssl;
server_name shopadmin.mysite.com;
root /var/www/admin;
index index.html;
location /a/ {
try_files $uri /index.html;
}
location / {
include /etc/nginx/mime.types;
try_files $uri /index.html =404;
}
}
server {
listen 443 ssl;
server_name assets.mysite.com;
client_max_body_size 20m; # Allow bigger file uploads.
location /test {
return 200 'success!!';
}
location / {
proxy_pass http://docker-minio-assets;
}
}
server {
listen 443 ssl;
server_name redis.mysite.com;
location / {
proxy_pass http://docker-redis;
}
}
server {
listen 443 ssl;
server_name postgres.mysite.com;
location / {
proxy_pass http://docker-postgres;
}
}
}
https://assets.mysite.com
吗?问题可能与DNS有关。 - Robhttps://assets.mysite.com
吗?问题可能与DNS有关。 - Robdocker compose exec backend curl -k https://assets.mysite.com/test
。如需进一步调试,请使用-v
标志运行 curl。 - Slava Kuravsky