[Guide] ERPNext-14 Production Setup (Docker)

Hello there
After a few hours of testing and breaking stuff, installing the HRMS module seems to ruin everything. I am not sure what the problem is, but so far, it works fine; this is after I reset my docker setup. I have no idea why.

Do you suggest any method for adding a proxy domain in a production environment?

I want to access my website via its local domain but traefik returns 404. Then I added my local domain to frontend container label traefik.http.routers.frontend-http.rule, now nginx returns a 404. I ran bench setup add-domain [local-domain] --site [remote-domain] , then bench setup nginx and service nginx reload. Still getting that 404, but now from nginx. I tried opening nginx logs as root but they are blank…

I’m quite new to this setup, so forgive me if I’m missing something obvious here.
Thanks!

Check this out

Note:

Use python version 3.10.12 instead of 3.10.5. because of the older version is degraded

--build-arg=PYTHON_VERSION=3.10.12 \
1 Like

when i trying to installing app into site:
docker compose --project-name erpnext-one exec backend bench new-site ziptor.com --no-mariadb-socket --install-app lms

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 109, in <module>
    main()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name="bench")
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 74, in new_site
    _new_site(
  File "/home/frappe/frappe-bench/apps/frappe/frappe/installer.py", line 80, in _new_site
    install_db(
  File "/home/frappe/frappe-bench/apps/frappe/frappe/installer.py", line 156, in install_db
    setup_database(force, source_sql, verbose, no_mariadb_socket)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/__init__.py", line 20, in setup_database
    return frappe.database.mariadb.setup_db.setup_database(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/mariadb/setup_db.py", line 41, in setup_database
    if force or (db_name not in dbman.get_database_list()):
                                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/db_manager.py", line 49, in get_database_list
    return self.db.sql("SHOW DATABASES", pluck=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 260, in sql
    self.log_query(query, values, debug, explain)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/mariadb/database.py", line 203, in log_query
    self.last_query = query = self._cursor._last_executed

Are you trying to install in the production mode?

yes im trying to install in the production mode.

No you shouldn’t install in production mode you have to take image build first from that image you have to up the containers.

1 Like

I followed your steps

Are you still facing issues ?

yes still facing. i followed your steps my os is windows 11

Hi,
I dont have any custom app, but made changes in the existing apps like hrms, erpnext
now i want to dockerize it but dont know how to do it
Is there any resources i can use?
please help

Thank you in advance

Specify your fork repo and branch in apps.json

More here: frappe_docker/docs/custom-apps.md at main · frappe/frappe_docker · GitHub

I tried this way but it needs a custom app,In my case i dont have a custom app instead i have made changes in the built in apps such as erpnext, hrms how to import these changes that i made into my docker

117 | >>> RUN export APP_INSTALL_ARGS=“” &&
118 | >>> if [ -n “${APPS_JSON_BASE64}” ]; then
119 | >>> export APP_INSTALL_ARGS=“–apps_path=/opt/frappe/apps.json”;
120 | >>> fi &&
121 | >>> bench init ${APP_INSTALL_ARGS}
122 | >>> --frappe-branch=${FRAPPE_BRANCH}
123 | >>> --frappe-path=${FRAPPE_PATH}
124 | >>> --no-procfile
125 | >>> --no-backups
126 | >>> --skip-redis-config-generation
127 | >>> --verbose
128 | >>> /home/frappe/frappe-bench &&
129 | >>> cd /home/frappe/frappe-bench &&
130 | >>> echo “{}” > sites/common_site_config.json &&
131 | >>> find apps -mindepth 1 -path “*/.git” | xargs rm -fr 132 |

ERROR: failed to solve: process “/bin/sh -c export APP_INSTALL_ARGS=”" && if [ -n “${APPS_JSON_BASE64}” ]; then export APP_INSTALL_ARGS=“–apps_path=/opt/frappe/apps.json”; fi && bench init ${APP_INSTALL_ARGS} --frappe-branch=${FRAPPE_BRANCH} --frappe-path=${FRAPPE_PATH} --no-procfile --no-backups --skip-redis-config-generation --verbose /home/frappe/frappe-bench && cd /home/frappe/frappe-bench && echo “{}” > sites/common_site_config.json && find apps -mindepth 1 -path “*/.git” | xargs rm -fr" did not complete successfully: exit code: 1

this error when i run :

docker build --no-cache --build-arg FRAPPE_PATH=GitHub - frappe/frappe: Low code web framework for real world applications, in Python and Javascript --build-arg FRAPPE_BRANCH=v14.51.0 --build-arg PYTHON_VERSION=3.10.12 --build-arg NODE_VERSION=16.15.0 --build-arg APPS_JSON_BASE64=$APPS_JSON_BASE64 --tag customapp:1.0.0 --file frappe_docker/images/custom/Containerfile .

My project structure is just this

project-directory/

├── Dockerfile
├── apps/
│ ├── frappe/
│ ├── erpnext/
│ ├── hrms/
│ └── payments/

└── …

Is there any pre-requisites need for this apart from docker installation, Such as having a particular user name or any other steps

Because when i excecuted this
docker compose --project-name hrms-one -f ~/gitops/hrms-one.yaml up -d

I got this,
[+] Running 9/9
:heavy_check_mark: Container hrms-one-redis-cache-1 Running 0.0s
:heavy_check_mark: Container hrms-one-redis-queue-1 Running 0.0s
:heavy_check_mark: Container hrms-one-configurator-1 Exited 5.0s
:heavy_check_mark: Container hrms-one-backend-1 Running 0.0s
:heavy_check_mark: Container hrms-one-scheduler-1 Running 0.0s
:heavy_check_mark: Container hrms-one-queue-short-1 Running 0.0s
:heavy_check_mark: Container hrms-one-websocket-1 Running 0.0s
:heavy_check_mark: Container hrms-one-queue-long-1 Running 0.0s
:heavy_check_mark: Container hrms-one-frontend-1 Running 0.0s

when i looking for status of all containers i found its breaking in this line
520f49d1e6bd customapp:1.0.0 “bash -c 'ls -1 apps…” 6 minutes ago Exited (0) About a minute ago hrms-one-configurator-1

when i try dont it manually: ls -1 apps
ls: cannot access ‘apps’: No such file or directory

Is it because i dont have such path as mentioned in compose.yml?
path: /home/frappe/frappe-bench

PS: i dont have user called frappe, What should i do now

The Frappe user will be automatically created inside the container when you up the container.

Please share the more detail and what error your encountering

OK
docker compose --project-name hrms-one
–env-file ~/gitops/hrms-one.env
-f compose.yaml
-f overrides/compose.redis.yaml
-f overrides/compose.multi-bench.yaml
-f overrides/compose.multi-bench-ssl.yaml config > ~/gitops/hrms-one.yaml
sneha@DELL2301:~/Documents/hrms_frappe$ docker compose --project-name hrms-one -f ~/gitops/hrms-one.yaml up -d

[+] Running 10/10
:heavy_check_mark: redis-queue Pulled 9.3s
:heavy_check_mark: redis-cache Pulled 9.4s
:heavy_check_mark: ec99f8b99825 Pull complete 1.5s
:heavy_check_mark: bba4873ee85d Pull complete 1.9s
:heavy_check_mark: 9d368deeb8fc Pull complete 2.4s
:heavy_check_mark: 55ba6f41d822 Pull complete 2.8s
:heavy_check_mark: 675ef339ce0b Pull complete 3.4s
:heavy_check_mark: b6c4d5e603ad Pull complete 3.7s
:heavy_check_mark: 4f4fb700ef54 Pull complete 4.1s
:heavy_check_mark: 330342537750 Pull complete 4.5s
[+] Running 13/13
:heavy_check_mark: Network hrms-one Created 0.3s
:heavy_check_mark: Volume “hrms-one_redis-cache-data” Created 0.1s
:heavy_check_mark: Volume “hrms-one_sites” Created 0.0s
:heavy_check_mark: Volume “hrms-one_redis-queue-data” Created 0.0s
:heavy_check_mark: Container hrms-one-redis-cache-1 Started 10.8s
:heavy_check_mark: Container hrms-one-redis-queue-1 Started 10.4s
:heavy_check_mark: Container hrms-one-configurator-1 Exited 14.3s
:heavy_check_mark: Container hrms-one-queue-long-1 Started 19.1s
:heavy_check_mark: Container hrms-one-queue-short-1 Started 17.6s
:heavy_check_mark: Container hrms-one-websocket-1 Started 18.9s
:heavy_check_mark: Container hrms-one-backend-1 Started 17.1s
:heavy_check_mark: Container hrms-one-scheduler-1 Started 18.8s
:heavy_check_mark: Container hrms-one-frontend-1 Started 17.8s

sneha@DELL2301:~/Documents/hrms_frappe$ docker compose --project-name hrms-one exec backend
bench new-site hrms@prerana.com --no-mariadb-socket --mariadb-root-password [root] --install-app erpnext --admin-password admin
Traceback (most recent call last):
File “/usr/local/lib/python3.10/runpy.py”, line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File “/usr/local/lib/python3.10/runpy.py”, line 86, in _run_code
exec(code, run_globals)
File “/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py”, line 109, in
main()
File “/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py”, line 18, in main
click.Group(commands=commands)(prog_name=“bench”)
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/click/core.py”, line 829, in call
return self.main(*args, **kwargs)
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/click/core.py”, line 782, in main
rv = self.invoke(ctx)
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/click/core.py”, line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/click/core.py”, line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/click/core.py”, line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/click/core.py”, line 610, in invoke
return callback(*args, **kwargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py”, line 70, in new_site
_new_site(
File “/home/frappe/frappe-bench/apps/frappe/frappe/installer.py”, line 80, in _new_site
install_db(
File “/home/frappe/frappe-bench/apps/frappe/frappe/installer.py”, line 154, in install_db
setup_database(force, source_sql, verbose, no_mariadb_socket)
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/init.py”, line 20, in setup_database
return frappe.database.mariadb.setup_db.setup_database(
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/mariadb/setup_db.py”, line 36, in setup_database
if force or (db_name not in dbman.get_database_list()):
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/db_manager.py”, line 49, in get_database_list
return self.db.sql(“SHOW DATABASES”, pluck=True)
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py”, line 221, in sql
self.connect()
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py”, line 126, in connect
self._conn: “MariadbConnection” | “PostgresConnection” = self.get_connection()
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/mariadb/database.py”, line 103, in get_connection
conn = self._get_connection()
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/mariadb/database.py”, line 109, in _get_connection
return self.create_connection()
File “/home/frappe/frappe-bench/apps/frappe/frappe/database/mariadb/database.py”, line 112, in create_connection
return pymysql.connect(**self.get_connection_settings())
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/pymysql/connections.py”, line 361, in init
self.connect()
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/pymysql/connections.py”, line 669, in connect
self._request_authentication()
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/pymysql/connections.py”, line 957, in _request_authentication
auth_packet = self._read_packet()
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/pymysql/connections.py”, line 775, in _read_packet
packet.raise_for_error()
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/pymysql/protocol.py”, line 219, in raise_for_error
err.raise_mysql_exception(self._data)
File “/home/frappe/frappe-bench/env/lib/python3.10/site-packages/pymysql/err.py”, line 150, in raise_mysql_exception
raise errorclass(errno, errval)
pymysql.err.OperationalError: (1045, “Access denied for user ‘root’@‘172.19.0.9’ (using password: YES)”)

Why am i encountering this error?? I thought that container not running was the main reason for this error, apart from this i didnt encounter any error so far

Should my DB_PASSWORD in mariadb.env and HASHED_PASSWORD in traefik.env be the same?