Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hostname Configuration Issues for Print Formats and Links with docker-compose (pwd.yml) or easy-install.py #1547

Open
edardev opened this issue Jan 15, 2025 · 6 comments
Labels

Comments

@edardev
Copy link
Contributor

edardev commented Jan 15, 2025

Hostname Configuration Issues for Print Formats and Links with docker-compose (pwd.yml) or easy-install.py

Description

When using docker-compose (pwd.yml) or easy-install.py, the host_name must be set to the frontend service's Docker-assigned IP and port, or the service name, for print formats and email attachments to work.

For example, this command resolves the issue for print formats and attachments:

bench --site sub.domain.com set-config host_name frontend:8080

However, this causes links in emails and/others places to use http://frontend:8080/... instead of the actual domain name like https://sub.domain.com/....


Expected Behavior

  • Links in emails and apps should use the real domain name (https://sub.domain.com/...).
  • Print formats and attachments should work without requiring host_name to be set to frontend:8080.

Actual Behavior

  • Print formats and email attachments fail unless host_name is set to frontend:8080.
  • Links in emails and apps are incorrect when using frontend:8080 in host_name.

Environment

  • Docker Compose Setup: pwd.yml
  • Installation Method: easy-install.py

Image

Image

Image

@edardev edardev added the bug label Jan 15, 2025
@revant
Copy link
Collaborator

revant commented Jan 15, 2025

This will not be fixed by me, Whatever I could have done I managed to post on forum. If someone finds solution, do share.

requirements:

  • site resolves by Host header. e.g. www.abcdefg.xyz is the site directory and someone enters that in browser, host header will be set to that. Frappe will find a directory named that in sites and serve. if it doesn't find such directory it'll say 404 site not found.
  • pwd is for demo. NOT to be used in production. use easy-install.py for production.
  • DO not use any other os than linux. You're on your own if you do. Solve your issues and help others in that case.
  • in rare case where vpn, internal network, public access and combination is involved you can override the nginx config. This is not required for a simple single vm setup.

sample nginx config that uses map module mentioned here:

map $host $updated_host {
    default $host;
    "frontend" erp.example.com;
}

then use $updated_host everywhere else in config. That will ensure internal calls are made to host frontend will be replaced with erp.example.com. This is a setup was used under VPN and ip address (http://1.2.3.4) was used to access site instead of a hostname (https://erp.example.com).

@NagariaHussain
Copy link
Member

Adding host_name as https://erp.example.com (instead of frontend!) after #1552 should work as expected now. Print formats, etc. work too.

@edardev
Copy link
Contributor Author

edardev commented Jan 26, 2025

Thank you, @NagariaHussain and @revant, for addressing this issue. I’ve spent months, including this entire weekend, trying to get this setup to work. Unfortunately, even after your commit (#1552), I’m still facing challenges.

I built a custom image with the latest changes using the easy-install.py script. When I set the host_name to https://erp.example.com/, it doesn't work as expected. The setup only works if I use frontend:8080 or wildcard URLs like https://*.erp.example.com or even *https://sdad.fasfasf.com, which seems unconventional.

My primary goal is to have a simple, production-ready Docker Compose setup for ERPNext. Perhaps using a single Frappe container (similar to the dev mode configuration) would be more feasible. Currently, I’m using also 'Nginx Proxy Manager' and 'Cloudflared tunnel' for routing and exposing the site to the internet.

If possible, could you share detailed step-by-step instructions, an example Docker Compose file, or even a short video guide? It would be incredibly helpful.

Thank you again for your time and efforts!

Below is the Docker Compose configuration generated by easy-install.py for your reference:

python3 easy-install.py deploy --project mw --sitename test.domain.com --email email@domain.com --no-ssl --http-port 8080 --backup-schedule "@daily" --app=erpnext --image edardev/erpnext

bench --site test.domain.com set-config host_name test.domain.com
bench --site test.domain.com set-config host_name https://test.domain.com
bench --site test.domain.com set-config host_name test.domain.com:8080
bench --site test.domain.com set-config host_name frontend:8080 ✅ works but break links, etc.
bench --site test.domain.com set-config host_name test.domain.com* ✅ weird, works but break links, etc.

name: mw
services:
  backend:
    depends_on:
      configurator:
        condition: service_completed_successfully
        required: true
    image: edardev/erpnext:v15.49.3
    networks:
      default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
  configurator:
    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;
    depends_on:
      db:
        condition: service_healthy
        required: true
      redis-cache:
        condition: service_started
        required: true
      redis-queue:
        condition: service_started
        required: true
    entrypoint:
      - bash
      - -c
    environment:
      DB_HOST: db
      DB_PORT: "3306"
      REDIS_CACHE: redis-cache:6379
      REDIS_QUEUE: redis-queue:6379
      SOCKETIO_PORT: "9000"
    image: edardev/erpnext:v15.49.3
    networks:
      default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
  cron:
    command:
      - daemon
      - --docker
    depends_on:
      scheduler:
        condition: service_started
        required: true
    image: mcuadros/ofelia:latest
    networks:
      default: null
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
        read_only: true
        bind:
          create_host_path: true
  db:
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --skip-character-set-client-handshake
      - --skip-innodb-read-only-compressed
    environment:
      MYSQL_ROOT_PASSWORD: 6a5497342
    healthcheck:
      test:
        - CMD-SHELL
        - mysqladmin ping -h localhost --password=6a5497342
      interval: 1s
      retries: 20
    image: mariadb:10.6
    networks:
      default: null
    volumes:
      - type: volume
        source: db-data
        target: /var/lib/mysql
        volume: {}
  frontend:
    command:
      - nginx-entrypoint.sh
    depends_on:
      backend:
        condition: service_started
        required: true
      websocket:
        condition: service_started
        required: true
    environment:
      BACKEND: backend:8000
      CLIENT_MAX_BODY_SIZE: 50m
      FRAPPE_SITE_NAME_HEADER: $$host
      PROXY_READ_TIMEOUT: "120"
      SOCKETIO: websocket:9000
      UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
      UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
      UPSTREAM_REAL_IP_RECURSIVE: "off"
    image: edardev/erpnext:v15.49.3
    hostname: frontend:8080
    networks:
      default: null
    platform: linux/amd64
    ports:
      - mode: ingress
        target: 8080
        published: "8080"
        protocol: tcp
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
  queue-long:
    command:
      - bench
      - worker
      - --queue
      - long,default,short
    depends_on:
      configurator:
        condition: service_completed_successfully
        required: true
    image: edardev/erpnext:v15.49.3
    networks:
      default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
  queue-short:
    command:
      - bench
      - worker
      - --queue
      - short,default
    depends_on:
      configurator:
        condition: service_completed_successfully
        required: true
    image: edardev/erpnext:v15.49.3
    networks:
      default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
  redis-cache:
    image: redis:6.2-alpine
    networks:
      default: null
    volumes:
      - type: volume
        source: redis-cache-data
        target: /data
        volume: {}
  redis-queue:
    image: redis:6.2-alpine
    networks:
      default: null
    volumes:
      - type: volume
        source: redis-queue-data
        target: /data
        volume: {}
  scheduler:
    command:
      - bench
      - schedule
    depends_on:
      configurator:
        condition: service_completed_successfully
        required: true
    image: edardev/erpnext:v15.49.3
    labels:
      ofelia.enabled: "true"
      ofelia.job-exec.datecron.command: bench --site all backup
      ofelia.job-exec.datecron.schedule: '@daily'
      ofelia.job-exec.datecron.user: frappe
    networks:
      default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
  websocket:
    command:
      - node
      - /home/frappe/frappe-bench/apps/frappe/socketio.js
    depends_on:
      configurator:
        condition: service_completed_successfully
        required: true
    image: edardev/erpnext:v15.49.3
    networks:
      default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
      - type: volume
        source: sites
        target: /home/frappe/frappe-bench/sites
        volume: {}
networks:
  default:
    name: mw_default
volumes:
  db-data:
    name: mw_db-data
  redis-cache-data:
    name: mw_redis-cache-data
  redis-queue-data:
    name: mw_redis-queue-data
  sites:
    name: mw_sites
x-backend-defaults:
  depends_on:
    configurator:
      condition: service_completed_successfully
  image: edardev/erpnext:v15.49.3
  pull_policy: missing
  volumes:
    - sites:/home/frappe/frappe-bench/sites
x-customizable-image:
  image: edardev/erpnext:v15.49.3
  pull_policy: missing
x-depends-on-configurator:
  depends_on:
    configurator:
      condition: service_completed_successfully

@revant
Copy link
Collaborator

revant commented Mar 17, 2025

Both socketio and print pdf download is working here. Check video at end.

#1589 (comment)

@whinee
Copy link

whinee commented Mar 25, 2025

uhm uhm... idk if this is even a valuable input, but I have a Github gist with my findings. I do not think I have encountered the same exact problems that you have, but I did run into not being able to access the site not in localhost.

I think here is what you need to do:

  1. set the docker compose .yaml file's services.frontend.environment.FRAPPE_SITE_NAME_HEADER's value to frontend; and
  2. set the docker compose .yaml file's services.create-site.command's last line to have the command's --set-default option to frontend

I have a working docker compose .yaml file in said gist as well. Though, please follow the instructions first before using it.

My thoughts and observations are also in said gist.

I hope this helps!

Sincerely yours,

your eyebag-ridden noobie dev
whi~nyaan!

@whinee
Copy link

whinee commented Mar 25, 2025

oh god, its almost 3am in here again... anwwwww

If you want to use your existing settings, then I guess we could make it work.

This is according to my Github gist, still:

The way I have made it work is by doing these things:

  1. set the docker compose .yaml file's services.create-site.command's last line to have the command's --set-default option to the base URL from where you want to access the site. ex.: 192.168.1.20 or frappe.localhost.com.
  2. move [sites]/socketsite.localhost to [sites]/[base_URL], whereas:
    1. [sites] is where the docker volume sites is located at. In my config, it is located at /root/data-program/frappe/sites.
    2. [base_URL] is the base URL from where you want to access the site. ex.: 192.168.1.20 or frappe.localhost.com.

And I think i can finally sleep... good night guys...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants