Add Billmora template (#773)

* feat: add billmora template

* feat: standardize configuration and volume mounts

* feat: hardcode Laravel automations in docker-compose.yml

* fix(billmora): migration race condition

* refactor(billmora): simplify service deploy architecture and standardize blueprint

* feat(billmora): ensure initial data is seeded on startup

* fix(billmora): use storage-based .env persistence to resolve directory mount error

* fix(billmora): revert to separate services for worker and scheduler

* refactor(billmora): remove APP_TIMEZONE from blueprint configuration

* fix(billmora): correct links structure and lowercase tags in meta.json

* fix(billmora): remove invalid volume mounts from template.toml

* fix(billmora): process root meta.json to resolve duplicated templates
This commit is contained in:
Mafly
2026-07-08 06:36:00 +07:00
committed by GitHub
parent 8dfb810e65
commit 4f103ea041
4 changed files with 195 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<style>
.cls-1 {
fill: #7267ef;
stroke-width: 0px;
}
</style>
</defs>
<path class="cls-1" d="m384,35H53v367h75v75h156c96.65,0,175-78.35,175-175V110h-75V35Zm0,266.98c0,55.23-44.77,100-100,100h-156V110.02h256v191.96Z"/>
<rect class="cls-1" x="153" y="160" width="100" height="20"/>
<rect class="cls-1" x="153" y="295" width="75" height="20"/>
<rect class="cls-1" x="153" y="205" width="180" height="20"/>
<rect class="cls-1" x="153" y="250" width="140" height="20"/>
</svg>

After

Width:  |  Height:  |  Size: 663 B

View File

@@ -0,0 +1,130 @@
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
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
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
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-db-data:
billmora-redis-data:

View File

@@ -0,0 +1,31 @@
[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"

View File

@@ -788,6 +788,24 @@
"business"
]
},
{
"id": "billmora",
"name": "Billmora",
"version": "latest",
"description": "Billmora (Billing Management, Operation, and Recurring Automation) is a free, open-source platform for hosting providers to manage clients, invoicing, and server provisioning.",
"logo": "billmora.svg",
"links": {
"website": "https://billmora.com",
"github": "https://github.com/Billmora/billmora",
"docs": "https://billmora.com/docs/introduction"
},
"tags": [
"laravel",
"billing",
"hosting",
"automation"
]
},
{
"id": "blender",
"name": "Blender",