我使用Swarmpit来控制Swarm节点。
Swarm 上有多个堆栈(每个应用程序一个),另一个堆栈与 NGINX 一起。所有堆栈都连接到一个名为“public”的
external
docker 网络。
Web 应用程序是一个 Laravel 应用程序(Octane),服务于端口 9000(可从 IP:9000 访问)。
NGINX 可通过端口 80 访问
我需要通过 NGINX 为所有应用程序提供服务。
Web 应用程序 docker-compose.yml
version: '3.3'
services:
laravel:
image: myimage:latest
extra_hosts:
- host.docker.internal:host-gateway
environment:
CHOKIDAR_USEPOLLING: 'true'
WWWUSER: '1000'
XDEBUG_CONFIG: client_host=host.docker.internal
XDEBUG_MODE: 'off'
ports:
- 5173:5173
- 9000:9000
networks:
- net
- public
logging:
driver: json-file
mongo:
image: mongo:latest
command:
- --quiet
- --logpath
- /dev/null
environment:
ME_CONFIG_MONGODB_ADMINPASSWORD: ...
ME_CONFIG_MONGODB_ADMINUSERNAME: ...
MONGO_INITDB_DATABASE: ...
MONGO_INITDB_ROOT_PASSWORD: ...
MONGO_INITDB_ROOT_USERNAME: ...
ports:
- 27017:27017
volumes:
- mongo:/data/db
networks:
- net
logging:
driver: json-file
mysql:
image: mysql:8
environment:
MYSQL_DATABASE: ...
MYSQL_PASSWORD: ...
MYSQL_ROOT_PASSWORD: ...
MYSQL_USER: ...
ports:
- 3306:3306
volumes:
- mysql:/var/lib/mysql
networks:
- net
logging:
driver: json-file
networks:
net:
driver: overlay
public:
external: true
volumes:
mongo:
driver: local
mysql:
driver: local
NGINX docker-compose.yml
version: '3.3'
services:
webserver:
image: mycustomnginximage:latest
ports:
- 80:80
- 8080:8080
- 443:443
networks:
- global
- public
logging:
driver: json-file
networks:
global:
driver: overlay
public:
external: true
NGINX 服务器配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
server_name mywebsite.dev *.mywebsite.dev;
server_tokens off;
root /home/forge/domain.com/public;
# SSL configuration
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/nginx/certificates/mywebsite.pem;
ssl_certificate_key /etc/nginx/certificates/mywebsite.key;
index index.php;
charset utf-8;
location /index.php {
try_files /not_exists @octane;
}
location / {
try_files $uri $uri/ @octane;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/domain.com-error.log error;
error_page 404 /index.php;
location @octane {
set $suffix "";
if ($uri = /index.php) {
set $suffix ?$query_string;
}
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://my_swarm_service_name:9000;
}
}
结果是可以通过
IP:9000
直接访问应用程序,但不能通过 https://mywebsite.dev
访问,就好像 nginx 无法将流量转移到服务一样。
我尝试过:
proxy_pass http://my_swarm_service_name:9000;
proxy_pass http://localhost:9000;
proxy_pass http://docker.service.internal.ip:9000;
我应该如何使用
proxy_pass
指令?还是还有什么问题?
服务名称是
laravel
,因此,要访问服务 VIP,您可以使用以下主机名:
# Each service is available using its plain service name
proxy_pass http://laravel:9000
# If you have multiple laravels in multiple stacks, you can name the specific one you
# want. Assuming you have deployed a stack called appstack1
proxy_pass http://appstack1_laravel:9000
# Docker also allows you to specify which network, this can help resolve ambiguities,
#i.e. prevent picking up an unwanted other laravel registered on the global network.
proxy_pass http://laravel.public:9000
但是,除非您添加最关键的部分,否则这一切都不会解决问题:Nginx 不会在 docker 服务名称运行时进行 dns 解析,除非您告诉它这样做。
您需要配置 Nginx 用于指向 dockers 容器 dns 的解析器:
server {
resolver 127.0.0.11;
}