diff --git a/README.md b/README.md index 26f5ef25..4d7666e9 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,15 @@ Also, there's docs to help with deployment: - [Docker Swarm](docs/docker-swarm.md), - [Kubernetes (frappe/helm)](https://helm.erpnext.com), - [site operations](docs/site-operations.md). +- Other + - [add custom domain using traefik](docs/add-custom-domain-using-traefik.md) + - [backup and push cron jobs](docs/backup-and-push-cronjob.md) + - [bench console and vscode debugger](docs/bench-console-and-vscode-debugger.md) + - [build version 10](docs/build-version-10-images.md) + - [connect to localhost services from containers for local app development](docs/connect-to-localhost-services-from-containers-for-local-app-development.md) + - [patch code from images](docs/patch-code-from-images.md) + - [port based multi tenancy](docs/port-based-multi-tenancy.md) +- [Troubleshoot](docs/troubleshoot.md) # Custom app diff --git a/development/README.md b/development/README.md index 4f81d353..46fe1afa 100644 --- a/development/README.md +++ b/development/README.md @@ -251,38 +251,6 @@ frappe.db.connect() The first command can take a few seconds to be executed, this is to be expected. -### Fixing MariaDB issues after rebuilding the container - -For any reason after rebuilding the container if you are not be able to access MariaDB correctly with the previous configuration. Follow these instructions. - -The parameter `'db_name'@'%'` needs to be set in MariaDB and permission to the site database suitably assigned to the user. - -This step has to be repeated for all sites available under the current bench. -Example shows the queries to be executed for site `localhost` - -Open sites/localhost/site_config.json: - -```shell -code sites/localhost/site_config.json -``` - -and take note of the parameters `db_name` and `db_password`. - -Enter MariaDB Interactive shell: - -```shell -mysql -uroot -p123 -hmariadb -``` - -Execute following queries replacing `db_name` and `db_password` with the values found in site_config.json. - -```sql -UPDATE mysql.user SET Host = '%' where User = 'db_name'; FLUSH PRIVILEGES; -SET PASSWORD FOR 'db_name'@'%' = PASSWORD('db_password'); FLUSH PRIVILEGES; -GRANT ALL PRIVILEGES ON `db_name`.* TO 'db_name'@'%'; FLUSH PRIVILEGES; -EXIT; -``` - ## Manually start containers In case you don't use VSCode, you may start the containers manually with the following command: diff --git a/docs/add-custom-domain-using-traefik.md b/docs/add-custom-domain-using-traefik.md new file mode 100644 index 00000000..54edd47e --- /dev/null +++ b/docs/add-custom-domain-using-traefik.md @@ -0,0 +1,42 @@ +Add following labels to *-nginx service + +```yaml + - "traefik.http.routers.custom-domain.rule=Host(`custom.localhost`)" + # Comment the entrypoints label if traefik already has default entrypoint set + - "traefik.http.routers.custom-domain.entrypoints=web" + - "traefik.http.middlewares.custom-domain.headers.customrequestheaders.Host=mysite.localhost" + - "traefik.http.routers.custom-domain.middlewares=custom-domain" + # Add following header only if TLS is needed in case of live server, use one of below + - "traefik.http.routers.custom-domain.tls.certresolver=myresolver" # For Single Bench + - "traefik.http.routers.custom-domain.tls.certresolver=le" # For Docker Swarm +``` + +Example: + +```yaml +frontend: + image: frappe/erpnext-nginx:${ERPNEXT_VERSION} + restart: on-failure + environment: + - FRAPPE_PY=erpnext-python + - FRAPPE_PY_PORT=8000 + - FRAPPE_SOCKETIO=frappe-socketio + - SOCKETIO_PORT=9000 + labels: + - "traefik.enable=true" + - "traefik.http.routers.frontend.rule=Host(${SITES})" + - "traefik.http.routers.custom-domain.rule=Host(`custom.localhost`)" + - "traefik.http.routers.custom-domain.entrypoints=web" + - "traefik.http.middlewares.custom-domain.headers.customrequestheaders.Host=mysite.localhost" + - "traefik.http.routers.custom-domain.middlewares=custom-domain" + # Add following header only if TLS is needed in case of live server + - "traefik.http.routers.custom-domain.tls.certresolver=myresolver" + - "${ENTRYPOINT_LABEL}" + - "${CERT_RESOLVER_LABEL}" + - "traefik.http.services.frontend.loadbalancer.server.port=80" + volumes: + - sites-vol:/var/www/html/sites:rw + - assets-vol:/assets:rw +``` + +This will add `custom.localhost` as custom domain for `mysite.localhost` diff --git a/docs/backup-and-push-cronjob.md b/docs/backup-and-push-cronjob.md new file mode 100644 index 00000000..bcb63b7b --- /dev/null +++ b/docs/backup-and-push-cronjob.md @@ -0,0 +1,121 @@ +Install [crazy-max/swarm-cronjob](https://github.com/crazy-max/swarm-cronjob) and then deploy following stack. + +```yaml +version: "3.7" + +services: + backup: + image: frappe/erpnext-worker:version-13 + entrypoint: ["bash", "-c"] + command: ["docker-entrypoint.sh backup; docker-entrypoint.sh push-backup"] + environment: + - WITH_FILES=1 + - BUCKET_NAME=backups + - REGION=region + - ACCESS_KEY_ID=access_id_from_provider + - SECRET_ACCESS_KEY=secret_access_from_provider + - ENDPOINT_URL=https://region.storage-provider.com + - BUCKET_DIR=frappe-bench + volumes: + - "sites-vol:/home/frappe/frappe-bench/sites" + deploy: + labels: + - "swarm.cronjob.enable=true" + - "swarm.cronjob.schedule=0 */3 * * *" + - "swarm.cronjob.skip-running=true" + replicas: 0 + restart_policy: + condition: none + networks: + - frappe-network + +volumes: + sites-vol: + external: true + name: frappe-bench-v12_sites-vol + +networks: + frappe-network: + external: true + +``` + +Note: +- In Above stack, `backup` runs every 3 hours. +- Change image and tag version as per need. +- Change environment variables as per the bucket credentials. +- Change cron string(s) as per need. + +### For docker-compose based installation not using docker swarm + +Add minio + +```yaml +version: "3.7" +services: + minio: + image: minio/minio + command: ["server", "/data"] + environment: + - MINIO_ACCESS_KEY=RANDOMACCESSKEY + - MINIO_SECRET_KEY=RANDOMSECRETKEY + volumes: + - "minio-vol:/data" + networks: + - erpnext-network + # Do not enable, check how to secure minio, out of scope of this project. + #labels: + # - "traefik.enable=true" + # - "traefik.http.routers.minio.rule=Host(`backup.example.com`)" + # - "traefik.http.routers.minio.entrypoints=websecure" + # - "traefik.http.routers.minio.tls.certresolver=myresolver" + # - "traefik.http.services.minio.loadbalancer.server.port=9000" + +networks: + erpnext-network: + external: true + name: _default + +volumes: + minio-vol: +``` + +Create backup service. Create file `backup-job.yml` + +```yaml +version: "3.7" +services: + push-backup: + image: frappe/erpnext-worker:v13 + entrypoint: ["bash", "-c"] + command: ["docker-entrypoint.sh backup; docker-entrypoint.sh push-backup"] + environment: + - WITH_FILES=1 + - BUCKET_NAME=erpnext + - REGION=us-east-1 + - ACCESS_KEY_ID=RANDOMACCESSKEY + - SECRET_ACCESS_KEY=RANDOMSECRETKEY + - ENDPOINT_URL=http://minio:9000 + - BUCKET_DIR=backups + - BACKUP_LIMIT=8 + volumes: + - "sites-vol:/home/frappe/frappe-bench/sites" + networks: + - erpnext-network + +networks: + erpnext-network: + external: true + name: _default + +volumes: + sites-vol: + external: true + name: _sites-vol +``` + +Add crontab entry for backup every 6 hours + +``` +0 */6 * * * /usr/local/bin/docker-compose -f /path/to/backup-job.yml up -d > /dev/null +``` diff --git a/docs/bench-console-and-vscode-debugger.md b/docs/bench-console-and-vscode-debugger.md new file mode 100644 index 00000000..f5d38864 --- /dev/null +++ b/docs/bench-console-and-vscode-debugger.md @@ -0,0 +1,18 @@ +Add the following configuration to `launch.json` `configurations` array to start bench console and use debugger. Replace `mysite.localhost` with appropriate site. Also replace `frappe-bench` with name of the bench directory. + +```json + { + "name": "Bench Console", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", + "args": [ + "frappe", "--site", "mysite.localhost", "console" + ], + "pythonPath": "${workspaceFolder}/frappe-bench/env/bin/python", + "cwd": "${workspaceFolder}/frappe-bench/sites", + "env": { + "DEV_SERVER": "1" + } + } +``` diff --git a/docs/build-version-10-images.md b/docs/build-version-10-images.md new file mode 100644 index 00000000..613f06ee --- /dev/null +++ b/docs/build-version-10-images.md @@ -0,0 +1,16 @@ +Clone the version-10 branch of this repo + +```shell +git clone https://github.com/frappe/frappe_docker.git -b version-10 && cd frappe_docker +``` + +Build the images + +```shell +export DOCKER_REGISTRY_PREFIX=frappe +docker build -t ${DOCKER_REGISTRY_PREFIX}/frappe-socketio:v10 -f build/frappe-socketio/Dockerfile . +docker build -t ${DOCKER_REGISTRY_PREFIX}/frappe-nginx:v10 -f build/frappe-nginx/Dockerfile . +docker build -t ${DOCKER_REGISTRY_PREFIX}/erpnext-nginx:v10 -f build/erpnext-nginx/Dockerfile . +docker build -t ${DOCKER_REGISTRY_PREFIX}/frappe-worker:v10 -f build/frappe-worker/Dockerfile . +docker build -t ${DOCKER_REGISTRY_PREFIX}/erpnext-worker:v10 -f build/erpnext-worker/Dockerfile . +``` diff --git a/docs/connect-to-localhost-services-from-containers-for-local-app-development.md b/docs/connect-to-localhost-services-from-containers-for-local-app-development.md new file mode 100644 index 00000000..73ee06ae --- /dev/null +++ b/docs/connect-to-localhost-services-from-containers-for-local-app-development.md @@ -0,0 +1,10 @@ +Not using separate container +Add following to frappe container from the `.devcontainer/docker-compose.yml`: + +```yaml + extra_hosts: + app1.localhost: 172.17.0.1 + app2.localhost: 172.17.0.1 +``` + +This is makes the domain names `app1.localhost` and `app2.localhost` connect to docker host and connect to services running on `localhost`. diff --git a/docs/patch-code-from-images.md b/docs/patch-code-from-images.md new file mode 100644 index 00000000..57e30454 --- /dev/null +++ b/docs/patch-code-from-images.md @@ -0,0 +1,10 @@ +Example: https://discuss.erpnext.com/t/sms-two-factor-authentication-otp-msg-change/47835 + +Above example needs following Dockerfile based patch + +```Dockerfile +FROM frappe/erpnext-worker:v12.17.0 + +RUN install_app custom_app https://github.com/username/custom_app version-12 +RUN sed -i -e "s/Your verification code is/আপনার লগইন কোড/g" /home/frappe/frappe-bench/apps/frappe/frappe/twofactor.py +``` diff --git a/docs/port-based-multi-tenancy.md b/docs/port-based-multi-tenancy.md new file mode 100644 index 00000000..d54d0b46 --- /dev/null +++ b/docs/port-based-multi-tenancy.md @@ -0,0 +1,47 @@ +WARNING: Do not use this in production if the site is going to be served over plain http. + +### Step 1 + +Remove the traefik service from docker-compose.yml + +### Step 2 + +Create nginx config file `/opt/nginx/conf/serve-8001.conf`: + +``` +server { + listen 8001; + server_name $http_host; + + location / { + + rewrite ^(.+)/$ $1 permanent; + rewrite ^(.+)/index\.html$ $1 permanent; + rewrite ^(.+)\.html$ $1 permanent; + + proxy_set_header X-Frappe-Site-Name mysite.localhost; + proxy_set_header Host mysite.localhost; + proxy_pass http://erpnext-nginx; + } +} +``` + +Notes: + +- Replace the port with any port of choice e.g. `listen 4200;` +- Change `mysite.localhost` to site name +- Repeat the server blocks for multiple ports and site names to get the effect of port based multi tenancy + +### Step 3 + +Run the docker container + +```shell +docker run --network=_default \ + -p 8001:8001 \ + --volume=/opt/nginx/conf/serve-8001.conf:/etc/nginx/conf.d/default.conf -d nginx +``` + +Note: Change the volumes, network and ports as needed + +With the above example configured site will be accessible on `http://localhost:8001` diff --git a/docs/troubleshoot.md b/docs/troubleshoot.md new file mode 100644 index 00000000..56a1d89f --- /dev/null +++ b/docs/troubleshoot.md @@ -0,0 +1,55 @@ +1. [Fixing MariaDB issues after rebuilding the container](#fixing-mariadb-issues-after-rebuilding-the-container) +1. [Letsencrypt companion not working](#letsencrypt-companion-not-working) +1. [docker-compose does not recognize variables from `.env` file](#docker-compose-does-not-recognize-variables-from-env-file) +1. [Windows Based Installation](#windows-based-installation) + +### Fixing MariaDB issues after rebuilding the container + +For any reason after rebuilding the container if you are not be able to access MariaDB correctly with the previous configuration. Follow these instructions. + +The parameter `'db_name'@'%'` needs to be set in MariaDB and permission to the site database suitably assigned to the user. + +This step has to be repeated for all sites available under the current bench. +Example shows the queries to be executed for site `localhost` + +Open sites/localhost/site_config.json: + +```shell +code sites/localhost/site_config.json +``` + +and take note of the parameters `db_name` and `db_password`. + +Enter MariaDB Interactive shell: + +```shell +mysql -uroot -p123 -hmariadb +``` + +Execute following queries replacing `db_name` and `db_password` with the values found in site_config.json. + +```sql +UPDATE mysql.user SET Host = '%' where User = 'db_name'; FLUSH PRIVILEGES; +SET PASSWORD FOR 'db_name'@'%' = PASSWORD('db_password'); FLUSH PRIVILEGES; +GRANT ALL PRIVILEGES ON `db_name`.* TO 'db_name'@'%'; FLUSH PRIVILEGES; +EXIT; +``` + +### Letsencrypt companion not working + +- Nginx Letsencrypt Companion needs to be setup before starting ERPNext services. +- Are domain names in `SITES` variable correct? +- Is DNS record configured? `A Name` record needs to point to Public IP of server. +- Try Restarting containers. + +### docker-compose does not recognize variables from `.env` file + +If you are using old version of `docker-compose` the .env file needs to be located in directory from where the docker-compose command is executed. There may also be difference in official `docker-compose` and the one packaged by distro. + +### Windows Based Installation + +- Set environment variable `COMPOSE_CONVERT_WINDOWS_PATHS` e.g. `set COMPOSE_CONVERT_WINDOWS_PATHS=1` +- Make the `frappe-mariadb.cnf` read-only for mariadb container to pick it up. +- While using docker machine, port-forward the port 80 of VM to port 80 of host machine +- Name all the sites ending with `.localhost`. and access it via browser locally. e.g. `http://site1.localhost` +- related issue comment https://github.com/frappe/frappe_docker/issues/448#issuecomment-851723912