I use Swarmpit to control Swarm nodes.
There are multiple stacks on Swarm (one for each application) and another stack with NGINX. All the stacks are attached to one external docker network named "public".
The web applications is a Laravel application (Octane) serverd on port 9000 (It is reachable from IP:9000).
NGINX is reachable on port 80
I need to serve all the apps through NGINX.
Web Application 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 server conf
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;
}
}
The result is that the application is reachable directly through IP:9000 but not through https://mywebsite.dev As if nginx couldn't divert traffic to the service.
I've tryied with:
proxy_pass http://my_swarm_service_name:9000;
proxy_pass http://localhost:9000;
proxy_pass http://docker.service.internal.ip:9000;
How should i use the proxy_pass directive? Or there are something else wrong?

The service name is
laravelso, to access the service vip you could use the following hostnames:None of this is going to work out the box however until you add the most crucial piece: Nginx does not do dns resolution at runtime of docker service names unless you tell it to.
You need to configure the resolver Nginx uses to point to dockers container dns: