Is it possible to deploy ERPNext into an Azure App Service with Python?

Hi there,

I’m wondering if it is possible to deploy ERPNext to an Azure App Service (the fully-managed platform of Azure). I was looking through the internet but seems to be no documentation for this kind of installation. If anyone could put me on the right path would be nice.

Cheers,
Jesus Santander

It looks like Azure App Service can host Docker containers:

All Frappe applications (like ERPNext) can be ran as a Docker container.

Have you found a solution, yet @jsantanders?
Would be very nice especially for the development environments. At the moment we are running several ubuntu VMs on Azure - works fine, but I would prever App Services, too.

This is not possible because of constraint from azure.

When we add docker-compose.yml , it gets converted to a base64 string, and this needs to be under 4000 characters. The default production/dev yml is too large.

You are correct. They do say “at this time”, but who knows when they will change it.

yml under 4k characters

version: "3"

services:
  erpnext-nginx:
    image: frappe/erpnext-nginx:${ERPNEXT_VERSION}
    restart: on-failure
    environment:
      - FRAPPE_PY=erpnext-python
      - FRAPPE_PY_PORT=8000
      - FRAPPE_SOCKETIO=frappe-socketio
      - SOCKETIO_PORT=9000
    ports:
      - 80:80
    volumes:
      - sites-vol:/var/www/html/sites:rw
      - assets-vol:/assets:rw

  erpnext-python:
    image: frappe/erpnext-worker:${ERPNEXT_VERSION}
    restart: on-failure
    environment:
      - MARIADB_HOST=mariadb
      - REDIS_CACHE=redis:6379/0
      - REDIS_QUEUE=redis:6379/1
      - REDIS_SOCKETIO=redis:6379/2
      - SOCKETIO_PORT=9000
      - AUTO_MIGRATE=1
      - WORKER_CLASS=gevent
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw
      - assets-vol:/home/frappe/frappe-bench/sites/assets:rw

  frappe-socketio:
    image: frappe/frappe-socketio:${FRAPPE_VERSION}
    restart: on-failure
    depends_on:
      - redis
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw
      - logs-vol:/home/frappe/frappe-bench/logs:rw

  erpnext-worker-default:
    image: frappe/erpnext-worker:${ERPNEXT_VERSION}
    restart: on-failure
    command: worker
    depends_on:
      - redis
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw
      - logs-vol:/home/frappe/frappe-bench/logs:rw

  erpnext-worker-short:
    image: frappe/erpnext-worker:${ERPNEXT_VERSION}
    restart: on-failure
    command: worker
    environment:
      - WORKER_TYPE=short
    depends_on:
      - redis
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw
      - logs-vol:/home/frappe/frappe-bench/logs:rw

  erpnext-worker-long:
    image: frappe/erpnext-worker:${ERPNEXT_VERSION}
    restart: on-failure
    command: worker
    environment:
      - WORKER_TYPE=long
    depends_on:
      - redis
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw

  erpnext-schedule:
    image: frappe/erpnext-worker:${ERPNEXT_VERSION}
    restart: on-failure
    command: schedule
    depends_on:
      - redis
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw
      - logs-vol:/home/frappe/frappe-bench/logs:rw

  redis:
    image: redis:latest
    restart: on-failure
    volumes:
      - redis-vol:/data

  mariadb:
    image: mariadb:10.3
    restart: on-failure
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    volumes:
      - ./installation/frappe-mariadb.cnf:/etc/mysql/conf.d/frappe.cnf
      - mariadb-vol:/var/lib/mysql

  site-creator:
    image: frappe/erpnext-worker:${ERPNEXT_VERSION}
    restart: "no"
    command: new
    depends_on:
      - erpnext-python
    environment:
      - SITE_NAME=${SITE_NAME}
      - DB_ROOT_USER=root
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - INSTALL_APPS=${INSTALL_APPS}
    volumes:
      - sites-vol:/home/frappe/frappe-bench/sites:rw
      - logs-vol:/home/frappe/frappe-bench/logs:rw
    
volumes:
  mariadb-vol:
  redis-vol:
  assets-vol:
  sites-vol:
  cert-vol:
  logs-vol:

# Environment Variables
# ERPNEXT_VERSION=v13.5.2
# FRAPPE_VERSION=v13.5.2
# MYSQL_ROOT_PASSWORD=admin
# SITE_NAME=app-name.azurewebsites.net
# ADMIN_PASSWORD=admin
# INSTALL_APPS=erpnext

Removed traefik and related config labels.

2 Likes

I’m excited to give this a try!

1 Like

I’m searching for the same!

Something on their end makes the shortened yml still say it’s over 4k

Error on creating web app with docker compose (microsoft.com)
The 4000 Characters

try removing the site-creator container if it reduces any lines.

Note that you’ll need to create the site manually.

1 Like

Looks like that worked!
At least it deployed, I’m new to this so not sure how to run the site creator separately yet

Can you exec into the erpnext-python container? if you can enter it and run the bench new-site command.

bench new-site erp.example.com --mariadb-root-password <db_root_password> --admin-password <admin_password> --no-mariadb-socket

I think a different image has to be built first with ssh config info, trying to figure it out
Configure a custom container - Azure App Service | Microsoft Docs

Well I tried incorporating ssh into the erpnext-worker dockerfile and rebuilding image like listed in the documentation above. Stumbled upon some info though, they allow ssh into only one container, that container would be nginx, preventing access to erpnext-python.

I also tried setting it up in container-instances, where there isn’t a yml restriction, however it doesn’t support docker labels and I wasn’t sure how to configure traefik.toml. So, I used the shortened yml above with no traefik or labels but azure didn’t give an ip once the containers were running. This post discouraged me from pursuing it further:
Azure Container Instance does not resolve name within the same vnet using private DNS zone - Microsoft Q&A

Sticking with docker on linux vm for now since it just works…

hey there!
have you found any solution?
I need to deploy my frappe app on azure, I want to do it using app services.