RuntimeError: Required environment variable "DB_HOST" not set

I am installing ERPNext in my computer to be accessed locally (not to be exposed to network), so that I follow the instruction at Setup Frappe without proxy and external MariaDB and Redis. I am using Ubuntu Impish and docker and docker compose from Ubuntu repository, this was a failure at first, because the docker compose is not v2. However I’ve installed docker compose v2 manually. Now, docker-compose.yml has been successfully generated, but docker compose up -d was fail, the log of frappe_docker-configurator-1 is:

Traceback (most recent call last):
  File "/usr/local/bin/configure.py", line 56, in <module>
    raise SystemExit(main())
  File "/usr/local/bin/configure.py", line 45, in main
    db_host=env("DB_HOST"),
  File "/usr/local/bin/configure.py", line 29, in env
    raise RuntimeError(f'Required environment variable "{name}" not set')
RuntimeError: Required environment variable "DB_HOST" not set
Traceback (most recent call last):
  File "/usr/local/bin/configure.py", line 56, in <module>
    raise SystemExit(main())
  File "/usr/local/bin/configure.py", line 45, in main
    db_host=env("DB_HOST"),
  File "/usr/local/bin/configure.py", line 29, in env
    raise RuntimeError(f'Required environment variable "{name}" not set')
RuntimeError: Required environment variable "DB_HOST" not set

Please help. I don’t know what to set to DB_HOST because the comment in .env said it is needed only if using external db.

can you share your generated compose?

docker-compose.yml:

name: frappe_docker
services:
  backend:
    depends_on:
      configurator:
        condition: service_completed_successfully
    image: frappe/frappe-worker:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
    - type: volume
      source: assets
      target: /home/frappe/frappe-bench/sites/assets
      read_only: true
      volume: {}
  configurator:
    command:
    - configure.py
    environment:
      DB_HOST: ""
      DB_PORT: ""
      REDIS_CACHE: ""
      REDIS_QUEUE: ""
      REDIS_SOCKETIO: ""
      SOCKETIO_PORT: "9000"
    image: frappe/frappe-worker:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
  frontend:
    depends_on:
      backend:
        condition: service_started
      websocket:
        condition: service_started
    environment:
      BACKEND: backend:8000
      FRAPPE_SITE_NAME_HEADER: $$host
      SOCKETIO: websocket:9000
      UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
      UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
      UPSTREAM_REAL_IP_RECURSIVE: "off"
    image: frappe/frappe-nginx:v13.26.0
    networks:
      default: null
    ports:
    - mode: ingress
      target: 8080
      published: "8080"
      protocol: tcp
    volumes:
    - type: volume
      source: assets
      target: /usr/share/nginx/html/assets
      volume: {}
    - type: volume
      source: sites
      target: /usr/share/nginx/html/sites
      volume: {}
  queue-default:
    command:
    - bench
    - worker
    - --queue
    - default
    depends_on:
      configurator:
        condition: service_completed_successfully
    image: frappe/frappe-worker:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
  queue-long:
    command:
    - bench
    - worker
    - --queue
    - long
    depends_on:
      configurator:
        condition: service_completed_successfully
    image: frappe/frappe-worker:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
  queue-short:
    command:
    - bench
    - worker
    - --queue
    - short
    depends_on:
      configurator:
        condition: service_completed_successfully
    image: frappe/frappe-worker:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
  scheduler:
    command:
    - bench
    - schedule
    depends_on:
      configurator:
        condition: service_completed_successfully
    image: frappe/frappe-worker:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
  websocket:
    depends_on:
      configurator:
        condition: service_completed_successfully
    image: frappe/frappe-socketio:v13.26.0
    networks:
      default: null
    volumes:
    - type: volume
      source: sites
      target: /home/frappe/frappe-bench/sites
      volume: {}
networks:
  default:
    name: frappe_docker_default
volumes:
  assets:
    name: frappe_docker_assets
  sites:
    name: frappe_docker_sites
x-backend-defaults:
  depends_on:
    configurator:
      condition: service_completed_successfully
  image: frappe/frappe-worker:v13.26.0
  volumes:
  - sites:/home/frappe/frappe-bench/sites
x-depends-on-configurator:
  depends_on:
    configurator:
      condition: service_completed_successfully

You need to add compose.mariadb.yaml and compose.redis.yaml if you wish to install them through containers

docker-compose -f compose.yaml -f overrides/compose.noproxy.yaml -f overrides/compose.redis.yaml -f overrides/compose.mariadb.yaml config > ~/gitops/docker-compose.yml
1 Like

Thanks @revant_one, the containers have run. However, when I open 127.0.0.1:8080 or localhost:8080 it is Not Found. I’ve tried to change $$host with localhost but still doesn’t work.

Create your first site.

Without any site it will show 404.

Site name should end with .localhost if you need to access the site locally. e.g. library.localhost

Thank you @revant_one, now the login page has been appeared, however I cannot login. The username is admin, right? Sorry, I can’t find the documentation about first login.

What I’ve done:

docker volume rm <frappe_docker_* volumes> # start from 0
docker compose -f compose.yaml \
  -f overrides/compose.noproxy.yaml \
  -f overrides/compose.redis.yaml \
  -f overrides/compose.mariadb.yaml \
  config > ../docker-compose.yml
cd ..
docker compose up -d
docker compose exec backend bench new-site erpnext.localhost \
  --mariadb-root-password 123 --admin-password <admin-password>
# Open http://erpnext.localhost:8080 in browser
# Log in with admin:<admin-password>
# Login failed

username: Administrator
password: <admin-password>

Turns out that I’ve taken the wrong example from the beginning, I wanted to install ERPNext but I installed Frappe only. Not sure if it was because I was a newbie or because the docs was not “linear”, it took me here and there. Thanks @revant_one for the guide. Here’s the summary:

How to install ERPNext, containerized (with Docker) and offline (in localhost)

  1. Install Docker Compose V2.

  2. Clone frappe_docker in a “gitops” dir.

    git clone https://github.com/frappe/frappe_docker.git
    
  3. Perform the rituals:

    cd frappe_docker
    cp example.env .env
    docker compose -f compose.yaml \
      -f overrides/compose.noproxy.yaml \
      -f overrides/compose.erpnext.yaml \
      -f overrides/compose.redis.yaml \
      -f overrides/compose.mariadb.yaml \
      config > ../docker-compose.yml
    cd ..
    docker compose up -d
    docker compose exec backend bench new-site erpnext.localhost \
      --mariadb-root-password 123 \
      --admin-password ADMIN_PASSWORD \
      --install-app erpnext
    
  4. Frappe/ERPNext always checks for online status, it prevents us to work offline, hack it.

    docker compose exec -u0 frontend \
      sed -i 's/navigator.onLine/navigator.onLine||true/' \
      /usr/share/nginx/html/assets/js/desk.min.js \
      /usr/share/nginx/html/assets/js/dialog.min.js \
      /usr/share/nginx/html/assets/js/frappe-web.min.js
    
  5. Open http://erpnext.localhost:8080/ in browser, log in with username Administrator and password ADMIN_PASSWORD.

1 Like

Impression: installing in “localhost” is usually meant to be a personal computer that’s turned on and off daily; compared to Odoo, the containers take too long to up and down, even the queues, scheduler, and websocket containers never stop successfully, they are always Exited (137).

exit code 137 seems to be caused due to OOM.
are you using docker desktop on windows? try increasing allocated RAM.

No, Ubuntu Impish.

Don’t you think it is because some containers don’t response to stop signal, so that Docker kills them instead?

Each container needs less than 6 seconds to up (from stopped/killed).

$ docker compose up -d
[+] Running 10/10
 ⠿ Container frappe_docker-db-1             Healthy                     2.1s
 ⠿ Container frappe_docker-redis-1          Started                     0.6s
 ⠿ Container frappe_docker-configurator-1   Exited                      3.7s
 ⠿ Container frappe_docker-queue-short-1    Started                     4.7s
 ⠿ Container frappe_docker-websocket-1      Started                     4.5s
 ⠿ Container frappe_docker-queue-default-1  Started                     4.8s
 ⠿ Container frappe_docker-scheduler-1      Started                     4.6s
 ⠿ Container frappe_docker-queue-long-1     Started                     5.2s
 ⠿ Container frappe_docker-backend-1        Started                     4.9s
 ⠿ Container frappe_docker-frontend-1       Started                     5.6s

When they are killed, each of them needs less than 2 seconds to end.

$ docker compose kill
[+] Running 9/9
 ⠿ Container frappe_docker-redis-1          Killed                     1.4s
 ⠿ Container frappe_docker-queue-short-1    Killed                     1.2s
 ⠿ Container frappe_docker-websocket-1      Killed                     1.0s
 ⠿ Container frappe_docker-queue-default-1  Killed                     0.9s
 ⠿ Container frappe_docker-scheduler-1      Killed                     0.9s
 ⠿ Container frappe_docker-frontend-1       Killed                     1.2s
 ⠿ Container frappe_docker-backend-1        Killed                     1.4s
 ⠿ Container frappe_docker-queue-long-1     Killed                     0.9s
 ⠿ Container frappe_docker-db-1             Killed                     1.1s

However when they are stopped, some of them needs more than 10 seconds (the default grace period or timeout).

$ docker compose stop
[+] Running 10/10
 ⠿ Container frappe_docker-queue-long-1     Stopped                  10.4s
 ⠿ Container frappe_docker-queue-short-1    Stopped                  10.6s
 ⠿ Container frappe_docker-scheduler-1      Stopped                  10.6s
 ⠿ Container frappe_docker-frontend-1       Stopped                   0.3s
 ⠿ Container frappe_docker-queue-default-1  Stopped                  10.7s
 ⠿ Container frappe_docker-backend-1        Stopped                   0.8s
 ⠿ Container frappe_docker-websocket-1      Stopped                  10.5s
 ⠿ Container frappe_docker-configurator-1   Stopped                   0.0s
 ⠿ Container frappe_docker-redis-1          Stopped                   0.4s
 ⠿ Container frappe_docker-db-1             Stopped                   0.5s

Containers that takes more than 10 seconds are those that exit with non-zero code.

$ docker ps -a # cut and reordered
STATUS                       PORTS     NAMES
Exited (137) 2 minutes ago             frappe_docker-queue-long-1
Exited (137) 2 minutes ago             frappe_docker-queue-short-1
Exited (137) 2 minutes ago             frappe_docker-scheduler-1
Exited (0) 2 minutes ago               frappe_docker-frontend-1
Exited (137) 2 minutes ago             frappe_docker-queue-default-1
Exited (0) 2 minutes ago               frappe_docker-backend-1
Exited (137) 2 minutes ago             frappe_docker-websocket-1
Exited (0) 2 minutes ago               frappe_docker-configurator-1
Exited (0) 2 minutes ago               frappe_docker-redis-1
Exited (0) 2 minutes ago               frappe_docker-db-1

If you have any fix then you can share or create an issue and share suggestions there.

Currently the workaround is to force-kill it by adding stop_signal: SIGKILL to each container that is too long to stop, or stop_grace_period: 3s to kill it in 3 seconds (instead of 10 seconds).

name: frappe_docker
services:
  backend:
    ...
  configurator:
    ...
  db:
    ...
  frontend:
    stop_grace_period: 3s
    ...
  queue-default:
    stop_grace_period: 3s
    ...
  queue-long:
    stop_grace_period: 3s
    ...
  queue-short:
    stop_grace_period: 3s
    ...
  redis:
    ...
  scheduler:
    stop_grace_period: 3s
    ...
  websocket:
    stop_grace_period: 3s
    ...
...

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.