Dokploy

Billmora

Billmora (Billing Management, Operation, and Recurring Automation) is a free, open-source platform for hosting providers to manage clients, invoicing, and server provisioning.

Billmora logo

Configuration

version: "3.8"

services:
  billmora-app:
    image: ghcr.io/billmora/billmora:latest
    restart: always
    environment:
      - APP_NAME=${APP_NAME}
      - APP_ENV=${APP_ENV}
      - APP_KEY=${APP_KEY}
      - APP_URL=${APP_URL}
      - DB_CONNECTION=${DB_CONNECTION}
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=${REDIS_HOST}
      - REDIS_PASSWORD=${REDIS_PASSWORD}
      - REDIS_PORT=${REDIS_PORT}
      - SESSION_DRIVER=${SESSION_DRIVER}
      - CACHE_STORE=${CACHE_STORE}
      - QUEUE_CONNECTION=${QUEUE_CONNECTION}
      - AUTORUN_ENABLED=true
      - AUTORUN_LARAVEL_MIGRATION=true
      - AUTORUN_LARAVEL_MIGRATION_FORCE=true
      - AUTORUN_LARAVEL_MIGRATION_SEED=true
      - AUTORUN_LARAVEL_STORAGE_LINK=true
    volumes:
      - billmora-storage:/var/www/html/storage
      - billmora-plugins:/var/www/html/plugin
      - billmora-themes-resources:/var/www/html/resources/themes
      - billmora-themes-public:/var/www/html/public/themes
    depends_on:
      billmora-db:
        condition: service_healthy
      billmora-redis:
        condition: service_healthy

  billmora-worker:
    image: ghcr.io/billmora/billmora:latest
    restart: always
    command: ["php", "artisan", "queue:work", "--sleep=3", "--tries=3", "--max-time=3600"]
    environment:
      - APP_NAME=${APP_NAME}
      - APP_ENV=${APP_ENV}
      - APP_KEY=${APP_KEY}
      - APP_URL=${APP_URL}
      - DB_CONNECTION=${DB_CONNECTION}
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=${REDIS_HOST}
      - REDIS_PASSWORD=${REDIS_PASSWORD}
      - REDIS_PORT=${REDIS_PORT}
      - SESSION_DRIVER=${SESSION_DRIVER}
      - CACHE_STORE=${CACHE_STORE}
      - QUEUE_CONNECTION=${QUEUE_CONNECTION}
      - AUTORUN_ENABLED=false
    volumes:
      - billmora-storage:/var/www/html/storage
      - billmora-plugins:/var/www/html/plugin
      - billmora-themes-resources:/var/www/html/resources/themes
      - billmora-themes-public:/var/www/html/public/themes
    depends_on:
      billmora-db:
        condition: service_healthy
      billmora-redis:
        condition: service_healthy

  billmora-scheduler:
    image: ghcr.io/billmora/billmora:latest
    restart: always
    command: ["/bin/sh", "-c", "while true; do php artisan schedule:run >> /dev/null 2>&1; sleep 60; done"]
    environment:
      - APP_NAME=${APP_NAME}
      - APP_ENV=${APP_ENV}
      - APP_KEY=${APP_KEY}
      - APP_URL=${APP_URL}
      - DB_CONNECTION=${DB_CONNECTION}
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=${REDIS_HOST}
      - REDIS_PASSWORD=${REDIS_PASSWORD}
      - REDIS_PORT=${REDIS_PORT}
      - SESSION_DRIVER=${SESSION_DRIVER}
      - CACHE_STORE=${CACHE_STORE}
      - QUEUE_CONNECTION=${QUEUE_CONNECTION}
      - AUTORUN_ENABLED=false
    volumes:
      - billmora-storage:/var/www/html/storage
      - billmora-plugins:/var/www/html/plugin
      - billmora-themes-resources:/var/www/html/resources/themes
      - billmora-themes-public:/var/www/html/public/themes
    depends_on:
      billmora-db:
        condition: service_healthy
      billmora-redis:
        condition: service_healthy

  billmora-db:
    image: mariadb:11
    restart: always
    environment:
      - MARIADB_DATABASE=${DB_DATABASE}
      - MARIADB_USER=${DB_USERNAME}
      - MARIADB_PASSWORD=${DB_PASSWORD}
      - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
    volumes:
      - billmora-db-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  billmora-redis:
    image: redis:7-alpine
    restart: always
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - billmora-redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "--no-auth-warning", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 10s

volumes:
  billmora-storage:
  billmora-plugins:
  billmora-themes-resources:
  billmora-themes-public:
  billmora-db-data:
  billmora-redis-data:
[variables]
APP_KEY = "base64:${base64:32}"
APP_URL = "https://${domain}"
DB_PASSWORD = "${password:16}"
DB_ROOT_PASSWORD = "${password:16}"
REDIS_PASSWORD = "${password:16}"

[config]
[[config.domains]]
serviceName = "billmora-app"
port = 8080
host = "${domain}"

[config.env]
APP_NAME = "Billmora"
APP_ENV = "production"
APP_KEY = "${APP_KEY}"
APP_URL = "${APP_URL}"
DB_CONNECTION = "mariadb"
DB_HOST = "billmora-db"
DB_PORT = "3306"
DB_DATABASE = "billmora"
DB_USERNAME = "billmora"
DB_PASSWORD = "${DB_PASSWORD}"
DB_ROOT_PASSWORD = "${DB_ROOT_PASSWORD}"
REDIS_HOST = "billmora-redis"
REDIS_PASSWORD = "${REDIS_PASSWORD}"
REDIS_PORT = "6379"
SESSION_DRIVER = "redis"
CACHE_STORE = "redis"
QUEUE_CONNECTION = "redis"

Base64

To import this template in Dokploy: create a Compose service → AdvancedBase64 import and paste the content below:

ewogICJjb21wb3NlIjogInZlcnNpb246IFwiMy44XCJcblxuc2VydmljZXM6XG4gIGJpbGxtb3JhLWFwcDpcbiAgICBpbWFnZTogZ2hjci5pby9iaWxsbW9yYS9iaWxsbW9yYTpsYXRlc3RcbiAgICByZXN0YXJ0OiBhbHdheXNcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gQVBQX05BTUU9JHtBUFBfTkFNRX1cbiAgICAgIC0gQVBQX0VOVj0ke0FQUF9FTlZ9XG4gICAgICAtIEFQUF9LRVk9JHtBUFBfS0VZfVxuICAgICAgLSBBUFBfVVJMPSR7QVBQX1VSTH1cbiAgICAgIC0gREJfQ09OTkVDVElPTj0ke0RCX0NPTk5FQ1RJT059XG4gICAgICAtIERCX0hPU1Q9JHtEQl9IT1NUfVxuICAgICAgLSBEQl9QT1JUPSR7REJfUE9SVH1cbiAgICAgIC0gREJfREFUQUJBU0U9JHtEQl9EQVRBQkFTRX1cbiAgICAgIC0gREJfVVNFUk5BTUU9JHtEQl9VU0VSTkFNRX1cbiAgICAgIC0gREJfUEFTU1dPUkQ9JHtEQl9QQVNTV09SRH1cbiAgICAgIC0gUkVESVNfSE9TVD0ke1JFRElTX0hPU1R9XG4gICAgICAtIFJFRElTX1BBU1NXT1JEPSR7UkVESVNfUEFTU1dPUkR9XG4gICAgICAtIFJFRElTX1BPUlQ9JHtSRURJU19QT1JUfVxuICAgICAgLSBTRVNTSU9OX0RSSVZFUj0ke1NFU1NJT05fRFJJVkVSfVxuICAgICAgLSBDQUNIRV9TVE9SRT0ke0NBQ0hFX1NUT1JFfVxuICAgICAgLSBRVUVVRV9DT05ORUNUSU9OPSR7UVVFVUVfQ09OTkVDVElPTn1cbiAgICAgIC0gQVVUT1JVTl9FTkFCTEVEPXRydWVcbiAgICAgIC0gQVVUT1JVTl9MQVJBVkVMX01JR1JBVElPTj10cnVlXG4gICAgICAtIEFVVE9SVU5fTEFSQVZFTF9NSUdSQVRJT05fRk9SQ0U9dHJ1ZVxuICAgICAgLSBBVVRPUlVOX0xBUkFWRUxfTUlHUkFUSU9OX1NFRUQ9dHJ1ZVxuICAgICAgLSBBVVRPUlVOX0xBUkFWRUxfU1RPUkFHRV9MSU5LPXRydWVcbiAgICB2b2x1bWVzOlxuICAgICAgLSBiaWxsbW9yYS1zdG9yYWdlOi92YXIvd3d3L2h0bWwvc3RvcmFnZVxuICAgICAgLSBiaWxsbW9yYS1wbHVnaW5zOi92YXIvd3d3L2h0bWwvcGx1Z2luXG4gICAgICAtIGJpbGxtb3JhLXRoZW1lcy1yZXNvdXJjZXM6L3Zhci93d3cvaHRtbC9yZXNvdXJjZXMvdGhlbWVzXG4gICAgICAtIGJpbGxtb3JhLXRoZW1lcy1wdWJsaWM6L3Zhci93d3cvaHRtbC9wdWJsaWMvdGhlbWVzXG4gICAgZGVwZW5kc19vbjpcbiAgICAgIGJpbGxtb3JhLWRiOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgYmlsbG1vcmEtcmVkaXM6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG5cbiAgYmlsbG1vcmEtd29ya2VyOlxuICAgIGltYWdlOiBnaGNyLmlvL2JpbGxtb3JhL2JpbGxtb3JhOmxhdGVzdFxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIGNvbW1hbmQ6IFtcInBocFwiLCBcImFydGlzYW5cIiwgXCJxdWV1ZTp3b3JrXCIsIFwiLS1zbGVlcD0zXCIsIFwiLS10cmllcz0zXCIsIFwiLS1tYXgtdGltZT0zNjAwXCJdXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIEFQUF9OQU1FPSR7QVBQX05BTUV9XG4gICAgICAtIEFQUF9FTlY9JHtBUFBfRU5WfVxuICAgICAgLSBBUFBfS0VZPSR7QVBQX0tFWX1cbiAgICAgIC0gQVBQX1VSTD0ke0FQUF9VUkx9XG4gICAgICAtIERCX0NPTk5FQ1RJT049JHtEQl9DT05ORUNUSU9OfVxuICAgICAgLSBEQl9IT1NUPSR7REJfSE9TVH1cbiAgICAgIC0gREJfUE9SVD0ke0RCX1BPUlR9XG4gICAgICAtIERCX0RBVEFCQVNFPSR7REJfREFUQUJBU0V9XG4gICAgICAtIERCX1VTRVJOQU1FPSR7REJfVVNFUk5BTUV9XG4gICAgICAtIERCX1BBU1NXT1JEPSR7REJfUEFTU1dPUkR9XG4gICAgICAtIFJFRElTX0hPU1Q9JHtSRURJU19IT1NUfVxuICAgICAgLSBSRURJU19QQVNTV09SRD0ke1JFRElTX1BBU1NXT1JEfVxuICAgICAgLSBSRURJU19QT1JUPSR7UkVESVNfUE9SVH1cbiAgICAgIC0gU0VTU0lPTl9EUklWRVI9JHtTRVNTSU9OX0RSSVZFUn1cbiAgICAgIC0gQ0FDSEVfU1RPUkU9JHtDQUNIRV9TVE9SRX1cbiAgICAgIC0gUVVFVUVfQ09OTkVDVElPTj0ke1FVRVVFX0NPTk5FQ1RJT059XG4gICAgICAtIEFVVE9SVU5fRU5BQkxFRD1mYWxzZVxuICAgIHZvbHVtZXM6XG4gICAgICAtIGJpbGxtb3JhLXN0b3JhZ2U6L3Zhci93d3cvaHRtbC9zdG9yYWdlXG4gICAgICAtIGJpbGxtb3JhLXBsdWdpbnM6L3Zhci93d3cvaHRtbC9wbHVnaW5cbiAgICAgIC0gYmlsbG1vcmEtdGhlbWVzLXJlc291cmNlczovdmFyL3d3dy9odG1sL3Jlc291cmNlcy90aGVtZXNcbiAgICAgIC0gYmlsbG1vcmEtdGhlbWVzLXB1YmxpYzovdmFyL3d3dy9odG1sL3B1YmxpYy90aGVtZXNcbiAgICBkZXBlbmRzX29uOlxuICAgICAgYmlsbG1vcmEtZGI6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgICBiaWxsbW9yYS1yZWRpczpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHlcblxuICBiaWxsbW9yYS1zY2hlZHVsZXI6XG4gICAgaW1hZ2U6IGdoY3IuaW8vYmlsbG1vcmEvYmlsbG1vcmE6bGF0ZXN0XG4gICAgcmVzdGFydDogYWx3YXlzXG4gICAgY29tbWFuZDogW1wiL2Jpbi9zaFwiLCBcIi1jXCIsIFwid2hpbGUgdHJ1ZTsgZG8gcGhwIGFydGlzYW4gc2NoZWR1bGU6cnVuID4+IC9kZXYvbnVsbCAyPiYxOyBzbGVlcCA2MDsgZG9uZVwiXVxuICAgIGVudmlyb25tZW50OlxuICAgICAgLSBBUFBfTkFNRT0ke0FQUF9OQU1FfVxuICAgICAgLSBBUFBfRU5WPSR7QVBQX0VOVn1cbiAgICAgIC0gQVBQX0tFWT0ke0FQUF9LRVl9XG4gICAgICAtIEFQUF9VUkw9JHtBUFBfVVJMfVxuICAgICAgLSBEQl9DT05ORUNUSU9OPSR7REJfQ09OTkVDVElPTn1cbiAgICAgIC0gREJfSE9TVD0ke0RCX0hPU1R9XG4gICAgICAtIERCX1BPUlQ9JHtEQl9QT1JUfVxuICAgICAgLSBEQl9EQVRBQkFTRT0ke0RCX0RBVEFCQVNFfVxuICAgICAgLSBEQl9VU0VSTkFNRT0ke0RCX1VTRVJOQU1FfVxuICAgICAgLSBEQl9QQVNTV09SRD0ke0RCX1BBU1NXT1JEfVxuICAgICAgLSBSRURJU19IT1NUPSR7UkVESVNfSE9TVH1cbiAgICAgIC0gUkVESVNfUEFTU1dPUkQ9JHtSRURJU19QQVNTV09SRH1cbiAgICAgIC0gUkVESVNfUE9SVD0ke1JFRElTX1BPUlR9XG4gICAgICAtIFNFU1NJT05fRFJJVkVSPSR7U0VTU0lPTl9EUklWRVJ9XG4gICAgICAtIENBQ0hFX1NUT1JFPSR7Q0FDSEVfU1RPUkV9XG4gICAgICAtIFFVRVVFX0NPTk5FQ1RJT049JHtRVUVVRV9DT05ORUNUSU9OfVxuICAgICAgLSBBVVRPUlVOX0VOQUJMRUQ9ZmFsc2VcbiAgICB2b2x1bWVzOlxuICAgICAgLSBiaWxsbW9yYS1zdG9yYWdlOi92YXIvd3d3L2h0bWwvc3RvcmFnZVxuICAgICAgLSBiaWxsbW9yYS1wbHVnaW5zOi92YXIvd3d3L2h0bWwvcGx1Z2luXG4gICAgICAtIGJpbGxtb3JhLXRoZW1lcy1yZXNvdXJjZXM6L3Zhci93d3cvaHRtbC9yZXNvdXJjZXMvdGhlbWVzXG4gICAgICAtIGJpbGxtb3JhLXRoZW1lcy1wdWJsaWM6L3Zhci93d3cvaHRtbC9wdWJsaWMvdGhlbWVzXG4gICAgZGVwZW5kc19vbjpcbiAgICAgIGJpbGxtb3JhLWRiOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgYmlsbG1vcmEtcmVkaXM6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG5cbiAgYmlsbG1vcmEtZGI6XG4gICAgaW1hZ2U6IG1hcmlhZGI6MTFcbiAgICByZXN0YXJ0OiBhbHdheXNcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gTUFSSUFEQl9EQVRBQkFTRT0ke0RCX0RBVEFCQVNFfVxuICAgICAgLSBNQVJJQURCX1VTRVI9JHtEQl9VU0VSTkFNRX1cbiAgICAgIC0gTUFSSUFEQl9QQVNTV09SRD0ke0RCX1BBU1NXT1JEfVxuICAgICAgLSBNQVJJQURCX1JPT1RfUEFTU1dPUkQ9JHtEQl9ST09UX1BBU1NXT1JEfVxuICAgIHZvbHVtZXM6XG4gICAgICAtIGJpbGxtb3JhLWRiLWRhdGE6L3Zhci9saWIvbXlzcWxcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFtcIkNNRFwiLCBcImhlYWx0aGNoZWNrLnNoXCIsIFwiLS1jb25uZWN0XCIsIFwiLS1pbm5vZGJfaW5pdGlhbGl6ZWRcIl1cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG4gICAgICBzdGFydF9wZXJpb2Q6IDMwc1xuXG4gIGJpbGxtb3JhLXJlZGlzOlxuICAgIGltYWdlOiByZWRpczo3LWFscGluZVxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIGNvbW1hbmQ6IHJlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICR7UkVESVNfUEFTU1dPUkR9XG4gICAgdm9sdW1lczpcbiAgICAgIC0gYmlsbG1vcmEtcmVkaXMtZGF0YTovZGF0YVxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogW1wiQ01EXCIsIFwicmVkaXMtY2xpXCIsIFwiLS1uby1hdXRoLXdhcm5pbmdcIiwgXCItYVwiLCBcIiR7UkVESVNfUEFTU1dPUkR9XCIsIFwicGluZ1wiXVxuICAgICAgaW50ZXJ2YWw6IDEwc1xuICAgICAgdGltZW91dDogM3NcbiAgICAgIHJldHJpZXM6IDVcbiAgICAgIHN0YXJ0X3BlcmlvZDogMTBzXG5cbnZvbHVtZXM6XG4gIGJpbGxtb3JhLXN0b3JhZ2U6XG4gIGJpbGxtb3JhLXBsdWdpbnM6XG4gIGJpbGxtb3JhLXRoZW1lcy1yZXNvdXJjZXM6XG4gIGJpbGxtb3JhLXRoZW1lcy1wdWJsaWM6XG4gIGJpbGxtb3JhLWRiLWRhdGE6XG4gIGJpbGxtb3JhLXJlZGlzLWRhdGE6XG4iLAogICJjb25maWciOiAiW3ZhcmlhYmxlc11cbkFQUF9LRVkgPSBcImJhc2U2NDoke2Jhc2U2NDozMn1cIlxuQVBQX1VSTCA9IFwiaHR0cHM6Ly8ke2RvbWFpbn1cIlxuREJfUEFTU1dPUkQgPSBcIiR7cGFzc3dvcmQ6MTZ9XCJcbkRCX1JPT1RfUEFTU1dPUkQgPSBcIiR7cGFzc3dvcmQ6MTZ9XCJcblJFRElTX1BBU1NXT1JEID0gXCIke3Bhc3N3b3JkOjE2fVwiXG5cbltjb25maWddXG5bW2NvbmZpZy5kb21haW5zXV1cbnNlcnZpY2VOYW1lID0gXCJiaWxsbW9yYS1hcHBcIlxucG9ydCA9IDgwODBcbmhvc3QgPSBcIiR7ZG9tYWlufVwiXG5cbltjb25maWcuZW52XVxuQVBQX05BTUUgPSBcIkJpbGxtb3JhXCJcbkFQUF9FTlYgPSBcInByb2R1Y3Rpb25cIlxuQVBQX0tFWSA9IFwiJHtBUFBfS0VZfVwiXG5BUFBfVVJMID0gXCIke0FQUF9VUkx9XCJcbkRCX0NPTk5FQ1RJT04gPSBcIm1hcmlhZGJcIlxuREJfSE9TVCA9IFwiYmlsbG1vcmEtZGJcIlxuREJfUE9SVCA9IFwiMzMwNlwiXG5EQl9EQVRBQkFTRSA9IFwiYmlsbG1vcmFcIlxuREJfVVNFUk5BTUUgPSBcImJpbGxtb3JhXCJcbkRCX1BBU1NXT1JEID0gXCIke0RCX1BBU1NXT1JEfVwiXG5EQl9ST09UX1BBU1NXT1JEID0gXCIke0RCX1JPT1RfUEFTU1dPUkR9XCJcblJFRElTX0hPU1QgPSBcImJpbGxtb3JhLXJlZGlzXCJcblJFRElTX1BBU1NXT1JEID0gXCIke1JFRElTX1BBU1NXT1JEfVwiXG5SRURJU19QT1JUID0gXCI2Mzc5XCJcblNFU1NJT05fRFJJVkVSID0gXCJyZWRpc1wiXG5DQUNIRV9TVE9SRSA9IFwicmVkaXNcIlxuUVVFVUVfQ09OTkVDVElPTiA9IFwicmVkaXNcIlxuIgp9

Tags

laravel, billing, hosting, automation


Version: latest

On this page