Recently I came across a very powerful bare metal server, with this powerful server I expect to install more apps than just frappe/erpnext.
Docker Swarm allows me to install wide range of apps on this server including frappe/erpnext.
Although I can install frappe/erpnext with docker swarm, I had a native bench installed on this server.
Once the bench is installed in production mode with dns multi-tenancy, it handles port 80, 443 and letsencrypt. With this default production setup I couldn’t fully use and manage Docker Swarm from portainer gui as expected.
In case of common docker swarm setup, Traefik becomes the entry point for all requests and runs on ports 80 and 443 published on host machine. Traefik also manages the domains and their Letsencrypt certificates.
Following setup assumes bench is running in production mode with port based multi-tenancy.
and NOT dns multi-tenancy.
- Enable Port Base Multi Tenancy
- Sites are running on separate ports on localhost. e.g: site1.local:4200, site2.local:4201
- Ports are only accessed through localhost, no need for external access.
- Setup Traefik in docker swarm mode (refer dockerswarm.rocks).
Admin can choose to add different stacks for each site or add sites in same stack.
Example add the following stack.yml with services representing sites.
version: "3.7"
services:
site1-local:
image: registry.gitlab.com/castlecraft/docker-craft/localizer:latest
environment:
- API_PORT=4200
networks:
- traefik-public
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.docker.network=traefik-public"
- "traefik.enable=true"
- "traefik.constraint-label=traefik-public"
- "traefik.http.routers.erpnext-nginx.rule=Host(`site1.example.com`)"
- "traefik.http.routers.erpnext-nginx.entrypoints=http"
- "traefik.http.routers.erpnext-nginx.middlewares=https-redirect"
- "traefik.http.middlewares.erpnext-nginx-https.headers.customrequestheaders.Host=site1.example.com"
- "traefik.http.routers.erpnext-nginx-https.rule=Host(`site1.example.com`)"
- "traefik.http.routers.erpnext-nginx-https.entrypoints=https"
- "traefik.http.routers.erpnext-nginx-https.tls=true"
- "traefik.http.routers.erpnext-nginx-https.tls.certresolver=le"
- "traefik.http.services.erpnext-nginx.loadbalancer.server.port=8080"
site2-local:
image: registry.gitlab.com/castlecraft/docker-craft/localizer:latest
environment:
- API_PORT=4201
networks:
- traefik-public
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.docker.network=traefik-public"
- "traefik.enable=true"
- "traefik.constraint-label=traefik-public"
- "traefik.http.routers.erpnext-nginx.rule=Host(`site2.example.com`)"
- "traefik.http.routers.erpnext-nginx.entrypoints=http"
- "traefik.http.routers.erpnext-nginx.middlewares=https-redirect"
- "traefik.http.middlewares.erpnext-nginx-https.headers.customrequestheaders.Host=site2.example.com"
- "traefik.http.routers.erpnext-nginx-https.rule=Host(`site2.example.com`)"
- "traefik.http.routers.erpnext-nginx-https.entrypoints=https"
- "traefik.http.routers.erpnext-nginx-https.tls=true"
- "traefik.http.routers.erpnext-nginx-https.tls.certresolver=le"
- "traefik.http.services.erpnext-nginx.loadbalancer.server.port=8080"
networks:
traefik-public:
external: true
Notes:
- This exposes internal site1.local:4200 as
site1.example.com
via traefik running in docker swarm mode. - This setup works only on single machine. It will not work in cluster. We are running native bench on single machine.
-
registry.gitlab.com/castlecraft/docker-craft/localizer:latest
image does the magic of exposing localhostAPI_PORT
port as docker service on port8080
.