2020-06-13 10:03:06 +00:00
|
|
|
### Prerequisites
|
|
|
|
|
|
|
|
IMPORTANT: All commands are executed on live server with public IP and DNS Configured.
|
|
|
|
|
|
|
|
#### Setup docker swarm
|
|
|
|
|
2020-06-19 16:09:28 +00:00
|
|
|
Follow [dockerswarm.rocks](https://dockerswarm.rocks) guide to setup Docker swarm, Traefik and Portainer.
|
2020-06-13 10:03:06 +00:00
|
|
|
|
|
|
|
Use Portainer for rest of the guide
|
|
|
|
|
|
|
|
### Create Config
|
|
|
|
|
|
|
|
Configs > Add Config > `frappe-mariadb-config`
|
|
|
|
|
|
|
|
```
|
|
|
|
[mysqld]
|
|
|
|
character-set-client-handshake = FALSE
|
|
|
|
character-set-server = utf8mb4
|
|
|
|
collation-server = utf8mb4_unicode_ci
|
|
|
|
|
|
|
|
[mysql]
|
|
|
|
default-character-set = utf8mb4
|
|
|
|
```
|
|
|
|
|
|
|
|
### Create Secret
|
|
|
|
|
|
|
|
Secret > Add Secret > `frappe-mariadb-root-password`
|
|
|
|
|
|
|
|
```
|
|
|
|
longsecretpassword
|
|
|
|
```
|
|
|
|
|
|
|
|
Note down this password.
|
|
|
|
It is only available in mariadb containers at location `/run/secrets/frappe-mariadb-root-password` later
|
|
|
|
|
|
|
|
### Deploy MariaDB Replication
|
|
|
|
|
|
|
|
Stacks > Add Stacks > `frappe-mariadb`
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
version: "3.7"
|
|
|
|
|
|
|
|
services:
|
|
|
|
mariadb-master:
|
|
|
|
image: 'bitnami/mariadb:10.3'
|
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
configs:
|
|
|
|
- source: frappe-mariadb-config
|
|
|
|
target: /opt/bitnami/mariadb/conf/bitnami/my_custom.cnf
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
secrets:
|
|
|
|
- frappe-mariadb-root-password
|
|
|
|
volumes:
|
|
|
|
- 'mariadb_master_data:/bitnami/mariadb'
|
|
|
|
environment:
|
|
|
|
- MARIADB_REPLICATION_MODE=master
|
|
|
|
- MARIADB_REPLICATION_USER=repl_user
|
|
|
|
- MARIADB_REPLICATION_PASSWORD_FILE=/run/secrets/frappe-mariadb-root-password
|
|
|
|
- MARIADB_ROOT_PASSWORD_FILE=/run/secrets/frappe-mariadb-root-password
|
|
|
|
|
|
|
|
mariadb-slave:
|
|
|
|
image: 'bitnami/mariadb:10.3'
|
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
configs:
|
|
|
|
- source: frappe-mariadb-config
|
|
|
|
target: /opt/bitnami/mariadb/conf/bitnami/my_custom.cnf
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
secrets:
|
|
|
|
- frappe-mariadb-root-password
|
|
|
|
volumes:
|
|
|
|
- 'mariadb_slave_data:/bitnami/mariadb'
|
|
|
|
environment:
|
|
|
|
- MARIADB_REPLICATION_MODE=slave
|
|
|
|
- MARIADB_REPLICATION_USER=repl_user
|
|
|
|
- MARIADB_REPLICATION_PASSWORD_FILE=/run/secrets/frappe-mariadb-root-password
|
|
|
|
- MARIADB_MASTER_HOST=mariadb-master
|
|
|
|
- MARIADB_MASTER_PORT_NUMBER=3306
|
|
|
|
- MARIADB_MASTER_ROOT_PASSWORD_FILE=/run/secrets/frappe-mariadb-root-password
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
mariadb_master_data:
|
|
|
|
mariadb_slave_data:
|
|
|
|
|
|
|
|
configs:
|
|
|
|
frappe-mariadb-config:
|
|
|
|
external: true
|
|
|
|
|
|
|
|
secrets:
|
|
|
|
frappe-mariadb-root-password:
|
|
|
|
external: true
|
|
|
|
|
|
|
|
networks:
|
|
|
|
frappe-network:
|
|
|
|
name: frappe-network
|
|
|
|
attachable: true
|
|
|
|
```
|
|
|
|
|
|
|
|
### Deploy Frappe/ERPNext
|
|
|
|
|
|
|
|
Stacks > Add Stacks > `frappe-bench-v12`
|
|
|
|
|
|
|
|
```yaml
|
2020-06-19 16:09:28 +00:00
|
|
|
version: "3.7"
|
2020-06-13 10:03:06 +00:00
|
|
|
|
|
|
|
services:
|
|
|
|
redis-cache:
|
|
|
|
image: redis:latest
|
|
|
|
volumes:
|
|
|
|
- redis-cache-vol:/data
|
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
|
|
|
redis-queue:
|
|
|
|
image: redis:latest
|
|
|
|
volumes:
|
|
|
|
- redis-queue-vol:/data
|
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
|
|
|
redis-socketio:
|
|
|
|
image: redis:latest
|
|
|
|
volumes:
|
|
|
|
- redis-socketio-vol:/data
|
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
|
|
|
erpnext-nginx:
|
2020-06-19 16:09:28 +00:00
|
|
|
image: frappe/erpnext-nginx:${ERPNEXT_VERSION?Variable ERPNEXT_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
environment:
|
|
|
|
- FRAPPE_PY=erpnext-python
|
|
|
|
- FRAPPE_PY_PORT=8000
|
|
|
|
- FRAPPE_SOCKETIO=frappe-socketio
|
|
|
|
- SOCKETIO_PORT=9000
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/var/www/html/sites:rw
|
|
|
|
- assets-vol:/assets:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
- traefik-public
|
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
labels:
|
|
|
|
- "traefik.docker.network=traefik-public"
|
|
|
|
- "traefik.enable=true"
|
2020-06-19 16:09:28 +00:00
|
|
|
- "traefik.constraint-label=traefik-public"
|
|
|
|
- "traefik.http.routers.erpnext-nginx.rule=Host(${SITES?Variable SITES not set})"
|
|
|
|
- "traefik.http.routers.erpnext-nginx.entrypoints=http"
|
|
|
|
- "traefik.http.routers.erpnext-nginx.middlewares=https-redirect"
|
|
|
|
- "traefik.http.routers.erpnext-nginx-https.rule=Host(${SITES?Variable SITES not set})"
|
|
|
|
- "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=80"
|
2020-06-13 10:03:06 +00:00
|
|
|
|
|
|
|
erpnext-python:
|
2020-06-19 16:09:28 +00:00
|
|
|
image: frappe/erpnext-worker:${ERPNEXT_VERSION?Variable ERPNEXT_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
environment:
|
|
|
|
- MARIADB_HOST=${MARIADB_HOST?Variable MARIADB_HOST not set}
|
|
|
|
- REDIS_CACHE=redis-cache:6379
|
|
|
|
- REDIS_QUEUE=redis-queue:6379
|
|
|
|
- REDIS_SOCKETIO=redis-socketio:6379
|
|
|
|
- SOCKETIO_PORT=9000
|
|
|
|
- AUTO_MIGRATE=1
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/home/frappe/frappe-bench/sites:rw
|
|
|
|
- assets-vol:/home/frappe/frappe-bench/sites/assets:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
|
|
|
frappe-socketio:
|
2020-06-19 16:09:28 +00:00
|
|
|
image: frappe/frappe-socketio:${FRAPPE_VERSION?Variable FRAPPE_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/home/frappe/frappe-bench/sites:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
2020-06-19 16:09:28 +00:00
|
|
|
erpnext-worker-default:
|
|
|
|
image: frappe/erpnext-worker:${ERPNEXT_VERSION?Variable ERPNEXT_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
command: worker
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/home/frappe/frappe-bench/sites:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
2020-06-19 16:09:28 +00:00
|
|
|
erpnext-worker-short:
|
|
|
|
image: frappe/erpnext-worker:${ERPNEXT_VERSION?Variable ERPNEXT_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
command: worker
|
|
|
|
environment:
|
|
|
|
- WORKER_TYPE=short
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/home/frappe/frappe-bench/sites:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
2020-06-19 16:09:28 +00:00
|
|
|
erpnext-worker-long:
|
|
|
|
image: frappe/erpnext-worker:${ERPNEXT_VERSION?Variable ERPNEXT_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
command: worker
|
|
|
|
environment:
|
|
|
|
- WORKER_TYPE=long
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/home/frappe/frappe-bench/sites:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
|
|
|
frappe-schedule:
|
2020-06-19 16:09:28 +00:00
|
|
|
image: frappe/erpnext-worker:${ERPNEXT_VERSION?Variable ERPNEXT_VERSION not set}
|
2020-06-13 10:03:06 +00:00
|
|
|
deploy:
|
|
|
|
restart_policy:
|
|
|
|
condition: on-failure
|
|
|
|
command: schedule
|
|
|
|
volumes:
|
|
|
|
- sites-vol:/home/frappe/frappe-bench/sites:rw
|
|
|
|
networks:
|
|
|
|
- frappe-network
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
redis-cache-vol:
|
|
|
|
redis-queue-vol:
|
|
|
|
redis-socketio-vol:
|
|
|
|
assets-vol:
|
|
|
|
sites-vol:
|
|
|
|
|
|
|
|
networks:
|
|
|
|
traefik-public:
|
|
|
|
external: true
|
|
|
|
frappe-network:
|
|
|
|
external: true
|
|
|
|
```
|
|
|
|
|
|
|
|
Use environment variables:
|
|
|
|
|
2020-06-19 16:09:28 +00:00
|
|
|
- `FRAPPE_VERSION` variable to be set to desired version of ERPNext. e.g. 12.10.0
|
|
|
|
- `ERPNEXT_VERSION` variable to be set to desired version of Frappe Framework. e.g. 12.7.0
|
2020-06-13 10:03:06 +00:00
|
|
|
- `MARIADB_HOST=frappe-mariadb_mariadb-master`
|
|
|
|
- `SITES` variable is list of sites in back tick and separated by comma
|
|
|
|
```
|
|
|
|
SITES=`site1.example.com`,`site2.example.com`
|
|
|
|
```
|
|
|
|
|
|
|
|
### Create new site job
|
|
|
|
|
|
|
|
1. Containers > Add Container > `add-site1-example-com`
|
|
|
|
2. Select Image frappe/erpnext-worker:v12
|
|
|
|
3. Set command as `new`
|
|
|
|
4. Select network `frappe-network`
|
|
|
|
5. Select Volume `frappe-bench-v12_sites_vol` and mount in container `/home/frappe/frappe-bench/sites`
|
|
|
|
6. Env variables:
|
|
|
|
- MYSQL_ROOT_PASSWORD=longsecretpassword
|
|
|
|
- SITE_NAME=site1.example.com
|
|
|
|
7. Start container
|
|
|
|
|
|
|
|
### Migrate Sites job
|
|
|
|
|
|
|
|
1. Containers > Add Container > `migrate-sites`
|
|
|
|
2. Select Image frappe/erpnext-worker:v12
|
|
|
|
3. Set command as `migrate`
|
|
|
|
4. Select network `frappe-network`
|
|
|
|
5. Select Volume `frappe-bench-v12_sites_vol` and mount in container `/home/frappe/frappe-bench/sites`
|
|
|
|
6. Env variables:
|
|
|
|
- MAINTENANCE_MODE=1
|
|
|
|
7. Start container
|
|
|
|
|