From 6f3b980f40f32212cf547f40e8a19539652de034 Mon Sep 17 00:00:00 2001 From: Nj Subedi Date: Fri, 19 Aug 2022 15:33:09 +0545 Subject: [PATCH] v0.0.1 --- Dockerfile | 22 +++-- README.md | 8 +- dev-scripts/README.md | 3 +- frappe-payments-utils-utils.py.patch | 143 --------------------------- manifest/CHANGELOG.md | 19 +--- manifest/DESCRIPTION.md | 13 +-- manifest/POSTINSTALL.md | 12 +-- start.sh | 78 +++++++++------ supervisord.conf | 28 ++++++ 9 files changed, 104 insertions(+), 222 deletions(-) delete mode 100644 frappe-payments-utils-utils.py.patch create mode 100644 supervisord.conf diff --git a/Dockerfile b/Dockerfile index f8ac412..c6a2886 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,11 +82,14 @@ RUN bench get-app --branch develop payments \ # Need root access for installing mysql; there could be other ways but it works USER root +COPY supervisord.conf /etc/supervisor/supervisord.conf + # Basically move config to proper location (see below for details[1]) -RUN mkdir -p /run/supervisor && \ - sudo ln -s /app/data/frappe/config/supervisor.conf /etc/supervisor/conf.d/frappe-bench.conf && \ - sudo ln -s /app/data/frappe/config/nginx.conf /etc/nginx/conf.d/frappe-bench.conf && \ - sudo ln -sf /run/supervisor/supervisord.log /var/log/supervisor/supervisord.log +RUN mkdir -p /run/supervisor/{logs} \ + && sudo ln -s /run/supervisor/logs/supervisord.log /var/log/supervisor/supervisord.log \ + && sudo ln -s /app/data/frappe/config/supervisor.conf /etc/supervisor/conf.d/frappe-bench.conf \ + && sudo ln -s /app/data/frappe/config/supervisor-app-nginx.conf /etc/supervisor/conf.d/app-nginx.conf \ + && sudo ln -s /app/data/frappe/config/nginx.conf /etc/nginx/sites-enabled/cloudron-erpnext.conf # Add our custom mysql/mariadb configuration ADD mysql_custom.cnf /etc/mysql/conf.d/ @@ -120,12 +123,11 @@ RUN mkdir -p /app/data/redis /run/redis/logs \ && mv /etc/redis /etc/redis-orig \ && ln -sf /app/data/redis /etc/redis -RUN mkdir -p /run/nginx/logs /app/data/nginx \ - && rm -r /var/log/nginx \ - && ln -sf /run/nginx/logs /var/log/nginx \ - && rm -r /var/lib/nginx \ - && ln -sf /app/data/nginx /var/lib/nginx - +RUN mkdir -p /run/nginx/ \ + && rm -r /var/lib/nginx && ln -sf /run/nginx /var/lib/nginx \ + && rm -r /var/log/nginx && ln -sf /run/nginx/logs /var/log/nginx \ + && rm -f /etc/nginx/sites-available/default && rm -f /etc/nginx/sites-enabled/default \ + && sed -i 's|pid /run/nginx.pid;|pid /run/nginx/nginx.pid;|g' /etc/nginx/nginx.conf # Same thing, but for the folders that frappe would pollute with writes RUN mkdir -p /app/data/frappe \ diff --git a/README.md b/README.md index a80d354..9a51acc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Run [erpnext](https://www.erpnext.com/) on [Cloudron](https://cloudron.io) ## Why -erpnext can federate users from Cloudron user directory and acts as a OpenID / SAML Provider. +Because, why not? ## Build and Install @@ -15,17 +15,19 @@ erpnext can federate users from Cloudron user directory and acts as a OpenID / S - If you're using your own docker registry, name the image properly, like `docker.example-cloudron.tld/john_doe/cloudron-erpnext`. - Log in to Docker Hub and mark the image as public, if necessary. -- Install the app `cloudron install -l ` +- Install the app `cloudron install -l ` - Look at the logs to see if everything is going as planned. Refer to the [Cloudron Docs](https://docs.cloudron.io/packaging/cli) for more information. ## About dev-scripts -Please refer to `docker-run.sh` file for some commands handy for you to test this setup. +Please refer to `docker-run.sh` file for some commands handy for you to test this setup. ## Updating ErpNext + [Official Documentation](https://frappeframework.com/docs/v14/user/en/production-setup#updating) + ```shell # update everything bench update diff --git a/dev-scripts/README.md b/dev-scripts/README.md index 431bd6b..51f7c68 100644 --- a/dev-scripts/README.md +++ b/dev-scripts/README.md @@ -1 +1,2 @@ -Scripts inside this folder are only used as reference during development, and have no use or effect in the docker image or containers. \ No newline at end of file +Scripts inside this folder are only used as reference during development, and have no use or effect in the docker image +or containers. \ No newline at end of file diff --git a/frappe-payments-utils-utils.py.patch b/frappe-payments-utils-utils.py.patch deleted file mode 100644 index a33f961..0000000 --- a/frappe-payments-utils-utils.py.patch +++ /dev/null @@ -1,143 +0,0 @@ -Index: payments/utils/utils.py -<+>UTF-8 -=================================================================== -diff --git a/payments/utils/utils.py b/payments/utils/utils.py ---- a/payments/utils/utils.py -+++ b/payments/utils/utils.py (date 1660235319741) -@@ -65,71 +65,71 @@ - "label": "Payments", - "insert_after": "custom_css", - }, -- { -- "default": "0", -- "fieldname": "accept_payment", -- "fieldtype": "Check", -- "label": "Accept Payment", -- "insert_after": "payments", -- }, -- { -- "depends_on": "accept_payment", -- "fieldname": "payment_gateway", -- "fieldtype": "Link", -- "label": "Payment Gateway", -- "options": "Payment Gateway", -- "insert_after": "accept_payment", -- }, -- { -- "default": "Buy Now", -- "depends_on": "accept_payment", -- "fieldname": "payment_button_label", -- "fieldtype": "Data", -- "label": "Button Label", -- "insert_after": "payment_gateway", -- }, -- { -- "depends_on": "accept_payment", -- "fieldname": "payment_button_help", -- "fieldtype": "Text", -- "label": "Button Help", -- "insert_after": "payment_button_label", -- }, -- { -- "fieldname": "payments_cb", -- "fieldtype": "Column Break", -- "insert_after": "payment_button_help", -- }, -- { -- "default": "0", -- "depends_on": "accept_payment", -- "fieldname": "amount_based_on_field", -- "fieldtype": "Check", -- "label": "Amount Based On Field", -- "insert_after": "payments_cb", -- }, -- { -- "depends_on": "eval:doc.accept_payment && doc.amount_based_on_field", -- "fieldname": "amount_field", -- "fieldtype": "Select", -- "label": "Amount Field", -- "insert_after": "amount_based_on_field", -- }, -- { -- "depends_on": "eval:doc.accept_payment && !doc.amount_based_on_field", -- "fieldname": "amount", -- "fieldtype": "Currency", -- "label": "Amount", -- "insert_after": "amount_field", -- }, -- { -- "depends_on": "accept_payment", -- "fieldname": "currency", -- "fieldtype": "Link", -- "label": "Currency", -- "options": "Currency", -- "insert_after": "amount", -- }, -+ # { -+ # "default": "0", -+ # "fieldname": "accept_payment", -+ # "fieldtype": "Check", -+ # "label": "Accept Payment", -+ # "insert_after": "payments", -+ # }, -+ # { -+ # "depends_on": "accept_payment", -+ # "fieldname": "payment_gateway", -+ # "fieldtype": "Link", -+ # "label": "Payment Gateway", -+ # "options": "Payment Gateway", -+ # "insert_after": "accept_payment", -+ # }, -+ # { -+ # "default": "Buy Now", -+ # "depends_on": "accept_payment", -+ # "fieldname": "payment_button_label", -+ # "fieldtype": "Data", -+ # "label": "Button Label", -+ # "insert_after": "payment_gateway", -+ # }, -+ # { -+ # "depends_on": "accept_payment", -+ # "fieldname": "payment_button_help", -+ # "fieldtype": "Text", -+ # "label": "Button Help", -+ # "insert_after": "payment_button_label", -+ # }, -+ # { -+ # "fieldname": "payments_cb", -+ # "fieldtype": "Column Break", -+ # "insert_after": "payment_button_help", -+ # }, -+ # { -+ # "default": "0", -+ # "depends_on": "accept_payment", -+ # "fieldname": "amount_based_on_field", -+ # "fieldtype": "Check", -+ # "label": "Amount Based On Field", -+ # "insert_after": "payments_cb", -+ # }, -+ # { -+ # "depends_on": "eval:doc.accept_payment && doc.amount_based_on_field", -+ # "fieldname": "amount_field", -+ # "fieldtype": "Select", -+ # "label": "Amount Field", -+ # "insert_after": "amount_based_on_field", -+ # }, -+ # { -+ # "depends_on": "eval:doc.accept_payment && !doc.amount_based_on_field", -+ # "fieldname": "amount", -+ # "fieldtype": "Currency", -+ # "label": "Amount", -+ # "insert_after": "amount_field", -+ # }, -+ # { -+ # "depends_on": "accept_payment", -+ # "fieldname": "currency", -+ # "fieldtype": "Link", -+ # "label": "Currency", -+ # "options": "Currency", -+ # "insert_after": "amount", -+ # }, - ] - } - ) diff --git a/manifest/CHANGELOG.md b/manifest/CHANGELOG.md index c9bf40e..5552899 100644 --- a/manifest/CHANGELOG.md +++ b/manifest/CHANGELOG.md @@ -1,17 +1,2 @@ -v18.0.2 -Bump to erpnext v18.0.2 ---- -v18.0.1 -Bump to erpnext v18.0.1 ---- -v18.0.0 -Bump to erpnext v18.0.0 ---- -v17.0.1 -Bump to erpnext v17.0.1 ---- -v17.0.0 -First release of erpnext on Quarkus. ---- -v1.0.0 -Initial Version \ No newline at end of file +v1 +Erpnext v14 initial release \ No newline at end of file diff --git a/manifest/DESCRIPTION.md b/manifest/DESCRIPTION.md index 9deb5ea..9fc400e 100644 --- a/manifest/DESCRIPTION.md +++ b/manifest/DESCRIPTION.md @@ -1,12 +1,5 @@ -Run erpnext on Cloudron. The default *master* realm is set up to use Cloudron LDAP for user federation. +Run [Erpnext](https://erpnext.com) on [Cloudron](https://cloudron.io). + +For now, it just works, if nothing goes wrong during installation. -Features ---- -- Configured to use Cloudron LDAP for user federation -- Configured to use Cloudron SMTP for email -Optimizations --- -- Uses recommended LDAP search filter to log in with email/username -- Sets the recommended custom JVM options to fix java memory issues -- Properly maps the givenName property with firstName to work with Cloudron LDAP \ No newline at end of file diff --git a/manifest/POSTINSTALL.md b/manifest/POSTINSTALL.md index b27caab..3b2f11d 100644 --- a/manifest/POSTINSTALL.md +++ b/manifest/POSTINSTALL.md @@ -1,9 +1,5 @@ -A superadmin account is created with the following credentials. Log in and change the password immmediately. +A super-admin account is created with the following credentials. Log in and change the password immmediately. -``` -Username: erpnextadmin -Password: erpnextadminpassword -``` - -A new realm named `cloudron` is added to authenticate users agains the Cloudron user directory. Do not use the `master` -realm for anything else except managing erpnext itself. \ No newline at end of file +Please check the `sitename-credential.txt` file inside the `/app/data/` folder. If you installed this +app under the domain `erp.example.com`, check `/app/data/erp.example.com-credential.txt` file for username and +password. \ No newline at end of file diff --git a/start.sh b/start.sh index fe65f76..128b9ec 100755 --- a/start.sh +++ b/start.sh @@ -16,13 +16,6 @@ if [[ ! -f /app/data/frappe/.initialized ]]; then cp -R /app/code/frappe-bench/apps-orig/* /app/data/frappe/apps/ cp -R /app/code/frappe-bench/logs-orig/* /app/data/frappe/logs/ - ### IMPORTANT ### - # The payments module causes crash, so I'm simply patching the utils.py file to remove the - # Doctypes that cause the crash. This might show unwanted behaviours on the payments module. - cd /app/data/frappe/apps/payments && - git apply frappe-payments-utils-utils.py.patch && - cd /app/code/frappe-bench - chown -R cloudron:cloudron /app/data/frappe touch /app/data/frappe/.initialized @@ -77,7 +70,7 @@ echo ">>>> Running mysqld_safe..." mkdir -p /app/data/tmp && chown mysql:mysql /app/data/tmp # NOTE: --character-set-server and --collation-server options don't work in config file. *SIGH* -mysqld_safe \ +/usr/local/bin/gosu mysql:mysql mysqld_safe \ --skip-syslog \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci & @@ -93,24 +86,20 @@ echo ">>>> Success. Daemon mysqld listening." ############# ################## echo ">>>> Setup directories for nginx" -if [[ ! -d /app/data/nginx ]]; then - mkdir -p /app/data/nginx -fi -chown -R cloudron:cloudron /app/data/nginx - if [[ ! -d /run/nginx/logs ]]; then mkdir -p /run/nginx/logs fi -chown -R cloudron:cloudron /run/nginx/logs +chown -R cloudron:cloudron /run/nginx echo ">>>> Done nginx dir setup" ############# ################## ############# ################## -echo ">>>> setup /run/supervisor" -if [[ ! -d /run/supervisor ]]; then - mkdir -p /run/supervisor +echo ">>>> setup /run/supervisor/logs" +if [[ ! -d /run/supervisor/logs ]]; then + mkdir -p /run/supervisor/logs fi -echo ">>>> done /run/supervisor" +chown -R cloudron:cloudron /run/supervisor +echo ">>>> done /run/supervisor/logs" ############# ################## ############# ################## @@ -121,7 +110,11 @@ if [[ ! -f "/app/data/frappe/sites/${DEFAULT_SITE}/.initialized" ]]; then echo 'frappe erpnext payments - hrms' > /app/data/frappe/sites/apps.txt + hrms' >/app/data/frappe/sites/apps.txt + + cd /app/code/frappe-bench + + SITE_PWD=$(openssl rand -hex 32) /usr/local/bin/gosu cloudron:cloudron bench new-site \ --verbose \ @@ -130,7 +123,9 @@ if [[ ! -f "/app/data/frappe/sites/${DEFAULT_SITE}/.initialized" ]]; then --db-password "cloudron" \ --db-root-username "root" \ --db-root-password "root" \ - --admin-password "changeme" "${DEFAULT_SITE}" + --admin-password "${SITE_PWD}" "${DEFAULT_SITE}" + + echo "Username: Administrator / Password: $SITE_PWD" >"/app/data/${DEFAULT_SITE}-credential.txt" /usr/local/bin/gosu cloudron:cloudron bench use "${DEFAULT_SITE}" @@ -145,24 +140,47 @@ if [[ ! -f "/app/data/frappe/sites/${DEFAULT_SITE}/.initialized" ]]; then /usr/local/bin/gosu cloudron:cloudron bench install-app erpnext echo ">>>> done" + touch "/app/data/frappe/sites/${DEFAULT_SITE}/.initialized" +else + echo ">>>> Site ${DEFAULT_SITE} already setup." +fi +############# ################## +echo ">>>> Setting up nginx, redis and supervisor..." +# "--logging none" only works "--logging combined" didn't work. +# Without this flag, "main" will be added to access_log, Causing nginx fail to start. +# --yes bypasses prompt +/usr/local/bin/gosu cloudron:cloudron bench setup nginx --yes --logging none +# fix "Conflicting scheme in header" error. +sed -i 's|proxy_set_header X-Forwarded-Proto $scheme;|proxy_set_header X-Forwarded-Proto https; # patched for cloudron|g' /app/data/frappe/config/nginx.conf - echo ">>>> ** The HRMS module causes the database tables to crash. **" - echo ">>>> ** Please report the issue or try to fix if it fails. **" - echo ">>>> installing hrms..." - sleep 10 +/usr/local/bin/gosu cloudron:cloudron bench setup redis - /usr/local/bin/gosu cloudron:cloudron bench install-app hrms +/usr/local/bin/gosu cloudron:cloudron bench setup supervisor --yes +echo ">>>> Done" + +if [[ ! -f "/app/data/frappe/sites/${DEFAULT_SITE}/.hrms_installed" ]]; then + + echo ">>>> Installing HRMS app (in background) to hostname: ${DEFAULT_SITE}" + + # Install HRMS app; requires Redis to be running, so we do "bench install-app hrms &" to run it as a background job. + # Right after this, supervisor process will start all the required processes (redis, etc) that this command needs. + + /usr/local/bin/gosu cloudron:cloudron bench install-app hrms & echo ">>>> done" - touch "/app/data/frappe/sites/${DEFAULT_SITE}/.initialized" + touch "/app/data/frappe/sites/${DEFAULT_SITE}/.hrms_installed" + else - echo ">>>> Site ${DEFAULT_SITE} already setup." + echo ">>>> HRMS already setup in ${DEFAULT_SITE}" fi -############# ################## +echo ">>>> All done. Starting nginx & supervisord..." -/usr/local/bin/gosu cloudron:cloudron bench setup nginx --yes --logging combined -/usr/local/bin/gosu cloudron:cloudron bench setup supervisor --yes +echo '[program:nginx] +command=/usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;" +autostart=true +autorestart=true +priority=10' >/app/data/frappe/config/supervisor-app-nginx.conf /usr/local/bin/gosu cloudron:cloudron /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf --nodaemon diff --git a/supervisord.conf b/supervisord.conf new file mode 100644 index 0000000..9eed665 --- /dev/null +++ b/supervisord.conf @@ -0,0 +1,28 @@ +; supervisor config file + +[unix_http_server] +file=/run/supervisor/supervisor.sock ; (the path to the socket file) +chmod=0700 ; sockef file mode (default 0700) + +[supervisord] +logfile=/run/supervisor/logs/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/run/supervisor/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/run/supervisor/logs/ ; ('AUTO' child log dir, default $TEMP) + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///run/supervisor/supervisor.sock ; use a unix:// URL for a unix socket + +; The [include] section can just contain the "files" setting. This +; setting can list multiple files (separated by whitespace or +; newlines). It can also contain wildcards. The filenames are +; interpreted as relative to this file. Included files *cannot* +; include files themselves. + +[include] +files = /etc/supervisor/conf.d/*.conf \ No newline at end of file