Setup erpnext15 dockerized » Historie » Revision 5
Revision 4 (Jeremias Keihsler, 12.12.2024 10:00) → Revision 5/11 (Jeremias Keihsler, 12.12.2024 10:27)
h1. Setup erpnext15 dockerized the basic idea is taken from https://www.youtube.com/watch?v=8Q5B7DnxmLg use of docker compose v2 h2. download pwd.yml (version erpnext:v15.45.4) https://github.com/frappe/frappe_docker/blob/0333e62884b706d01d38804472f71b3f6a039ff6/pwd.yml save in @/opt/docker.compose/erpnext@ as @docker-compose.yml@ <pre><code class="yaml"> services: backend: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: on-failure volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs environment: DB_HOST: db DB_PORT: "3306" MYSQL_ROOT_PASSWORD: admin MARIADB_ROOT_PASSWORD: admin configurator: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: none entrypoint: - bash - -c command: - > ls -1 apps > sites/apps.txt; bench set-config -g db_host $$DB_HOST; bench set-config -gp db_port $$DB_PORT; bench set-config -g redis_cache "redis://$$REDIS_CACHE"; bench set-config -g redis_queue "redis://$$REDIS_QUEUE"; bench set-config -g redis_socketio "redis://$$REDIS_QUEUE"; bench set-config -gp socketio_port $$SOCKETIO_PORT; environment: DB_HOST: db DB_PORT: "3306" REDIS_CACHE: redis-cache:6379 REDIS_QUEUE: redis-queue:6379 SOCKETIO_PORT: "9000" volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs create-site: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: none volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs entrypoint: - bash - -c command: - > wait-for-it -t 120 db:3306; wait-for-it -t 120 redis-cache:6379; wait-for-it -t 120 redis-queue:6379; export start=`date +%s`; until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]]; do echo "Waiting for sites/common_site_config.json to be created"; sleep 5; if (( `date +%s`-start > 120 )); then echo "could not find sites/common_site_config.json with required keys"; exit 1 fi done; echo "sites/common_site_config.json found"; bench new-site --mariadb-user-host-login-scope='%' --admin-password=admin --db-root-username=root --db-root-password=admin --install-app erpnext --set-default erpnext; db: image: mariadb:10.6 networks: - frappe_network healthcheck: test: mysqladmin ping -h localhost --password=admin interval: 1s retries: 20 deploy: restart_policy: condition: on-failure command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 environment: MYSQL_ROOT_PASSWORD: admin MARIADB_ROOT_PASSWORD: admin volumes: - db-data:/var/lib/mysql frontend: image: frappe/erpnext:v15.45.4 networks: - frappe_network depends_on: - websocket deploy: restart_policy: condition: on-failure command: - nginx-entrypoint.sh environment: BACKEND: backend:8000 FRAPPE_SITE_NAME_HEADER: erpnext SOCKETIO: websocket:9000 UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1 UPSTREAM_REAL_IP_HEADER: X-Forwarded-For UPSTREAM_REAL_IP_RECURSIVE: "off" PROXY_READ_TIMEOUT: 120 CLIENT_MAX_BODY_SIZE: 50m volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs ports: - "80:8080" queue-long: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: on-failure command: - bench - worker - --queue - long,default,short volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs queue-short: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: on-failure command: - bench - worker - --queue - short,default volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs redis-queue: image: redis:6.2-alpine networks: - frappe_network deploy: restart_policy: condition: on-failure volumes: - redis-queue-data:/data redis-cache: image: redis:6.2-alpine networks: - frappe_network deploy: restart_policy: condition: on-failure volumes: - redis-cache-data:/data scheduler: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: on-failure command: - bench - schedule volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs websocket: image: frappe/erpnext:v15.45.4 networks: - frappe_network deploy: restart_policy: condition: on-failure command: - node - /home/frappe/frappe-bench/apps/frappe/socketio.js volumes: - sites:/home/frappe/frappe-bench/sites - logs:/home/frappe/frappe-bench/logs volumes: db-data: redis-queue-data: redis-cache-data: sites: logs: networks: frappe_network: driver: bridge </code></pre> h2. usage of mounts instead of docker-volumes didn't work for me .. mariadb yes, but erpnext no h3. create directory structure <pre><code class="shell"> mkdir -p /opt/docker.compose/erpnext/{c_db/var/lib/mysql,c_erp/home/frappe/frappe-bench/sites,c_erp/home/frappe/frappe-bench/logs,c_redis_cache/data,c_redis_queue/data,c_redis_socketio/data} chmod -R g+w /opt/docker.compose/erpnext/c_* chmod -R o+w /opt/docker.compose/erpnext/c_* </code></pre> fix permission issue within volume <pre><code class="shell"> sudo docker exec --user root -it erpnext-backend-1 /bin/bash chown -R frappe:frappe logs chown -R frappe:frappe sites </code></pre> as a consequence stuck with volumes. Although they can be easily accessed from within the host. h2. migrate erpnext from different server https://discuss.frappe.io/t/moving-to-docker/80457/4 Take @bench --site {site-name} backup --with-files@ on the running setup. Copy files from @sites/{site-name}/private/backups@ to new server and optionally stop old server so users don’t create new data. In case of container setup copy files from server into container using docker cp or placing files in volume location. If existing site matches new site ... drop site first (https://frappeframework.com/docs/user/en/bench/reference/drop-site) @bench drop-site erpnext --db-root-password admin@ Enter any worker container and create site using @bench new-site --no-mariadb-socket@ command. Name the site as per configured domain name. (Note down the db_name from site_config.json created) @bench new-site erpnext --no-mariadb-socket --verbose --db-root-password admin@ Enter mariadb container / use mysql client and execute drop database {db_name}; create database {db_name}. This will clean the site db that was created by new site. We do this so that we have a running site configured without any database resulting in Internal Server Error. <pre><code class="shell"> sudo docker exec -it erpnext-db-1 /bin/bash mysql -p show database; drop database _76e6a5f706540e85; create database _76e6a5f706540e85; </code></pre> In mysql shell execute, @use {db_name}; source /path/to/database.sql@. This will restore the database from backup on fresh db. We use source from mysql shell as it re-connects in case of disconnection or timeout during restoration of huge database. Simple alternate command will be mysql -uroot -p{root-password} -h{hostname} {db_name} < /path/to/database.sql Copy additional keys and encryption_key from backed up site_config.json. (Note, DO NOT change the db_name, db_password keys from newly created site, only copy other keys from backup site_config) The keys are important for the email-service, the hostname is important to 'wkhtmltopdf' and don't forget .. <pre><code class="shell"> bench --site erpnext migrate </code></pre> copy the tar-ed files into the corresponding directories h2. erpnext as a service https://stackoverflow.com/questions/43671482/how-to-run-docker-compose-up-d-at-system-start-up <pre> # /etc/systemd/system/docker-compose-erpnext.service [Unit] Description=Docker Compose Application Service (erpnext) Requires=docker.service After=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/docker.compose/erpnext ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose down TimeoutStartSec=0 [Install] WantedBy=multi-user.target </pre> <pre><code class="shell"> systemctl enable docker-compose-app </code></pre> h2. backup erpnext from outside a container <pre><code class="shell"> sudo docker exec -t erpnext-backend-1 /usr/local/bin/bench --site all backup --with-files </code></pre> h1. upgrade erpnext v15 h2. shutdown erpnext <pre><code class="shell"> sudo systemctl stop docker-compose-erpnext </code></pre> h2. modify compose-file <pre><code class="shell"> sudo vim /opt/docker.compose/erpnext/docker-compose.yml </code></pre> replace all @frappe/erpnext:v15.45.4@ with the version desired (e.g. @v15.46.0@) check whether mariadb-version or redis-version should be changed as well. (e.g. @mariadb 10.6@ / @redis-6.2@) h2. restart erpnext manually <pre><code class="shell"> cd /opt/docker.compose/erpnext/ sudo docker compose up </code></pre> h2. migrate erpnext installation (from within any erpnext-container) <pre><code class="shell"> sudo docker ps sudo docker exec -it b84444ac0cdb /bin/bash bench --site erpnext migrate </code></pre> h2. stop manually started instance and restart service <pre><code class="shell"> CTRL-C sudo systemctl start docker-compose-erpnext </code></pre> h2. tidy up .. <pre><code class="shell"> sudo docker system prune </code></pre> h2. create custom app image (erpnext & eu_einvoice) https://github.com/frappe/frappe_docker/blob/main/docs/custom-apps.md <pre><code class="shell"> export APPS_JSON='[ { "url": "https://github.com/frappe/erpnext", "branch": "version-15" }, { "url": "https://github.com/alyf-de/eu_einvoice.git", "branch": "version-15" } ]' export APPS_JSON_BASE64=$(echo ${APPS_JSON} | base64 -w 0) echo ${APPS_JSON} echo ${APPS_JSON_BASE64} </code></pre> <pre><code class="shell"> cd ~ git clone https://github.com/frappe/frappe_docker cd frappe_docker docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-15 \ --build-arg=PYTHON_VERSION=3.11.6 \ --build-arg=NODE_VERSION=18.18.2 \ --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ --tag=customapp:1.0.0 \ --file=images/custom/Containerfile . docker build \ --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \ --build-arg=FRAPPE_BRANCH=version-15 \ --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \ --tag=customapp:1.0.0 \ --file=images/custom/Containerfile . docker image ls </code></pre> <code> ... image: customapp:1.0.0 pull_policy: never