Merge remote-tracking branch 'origin/canary' into SamirChatwiti/canary

# Conflicts:
#	meta.json
This commit is contained in:
Mauricio Siu
2026-07-07 17:36:57 -06:00
208 changed files with 6749 additions and 673 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,3 @@
node_modules
package-lock.json
meta.json.backup.*
meta.json.backup.*

4
app/pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,4 @@
packages:
- .
allowBuilds:
esbuild: false

View File

@@ -13,7 +13,9 @@ const Navigation = () => {
"https://api.github.com/repos/dokploy/dokploy"
);
const data = await response.json();
setGithubStars(data.stargazers_count);
setGithubStars(
Number.isFinite(data.stargazers_count) ? data.stargazers_count : 0
);
} catch (error) {
console.error("Error fetching GitHub stars:", error);
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="a" viewBox="0 0 3271 1440"><defs><style>.st0{fill:#dedede}</style></defs><path d="M1009.95 1209.53c-125.1-214.98-250.74-430.9-378.92-651.16-126.82 219.73-251.81 436.28-376.62 652.51H60.69c190.42-329.11 570.87-981.75 570.87-981.75s382.11 651.12 572.49 980.41h-194.1Z" class="st0"/><path d="M875.46 1210.46H383.92c32.72-56.91 64.4-111.99 95.81-166.62H781.8c30.62 54.46 61.09 108.66 93.67 166.62zm1622.92-202.23c19.52 29.84 37.9 57.94 58.46 89.39h-63.61c-18.29-24.88-38.17-51.91-57.71-78.49h-72.24v78.17h-51.11V828.44c30.03 0 58.71-.22 87.38.06 23.48.24 47.32-1.26 70.37 2.21 37.67 5.66 66.94 25.71 74.9 64.9 8.22 40.54 1.62 78.35-35.52 104.62-3.14 2.22-6.21 4.54-10.93 7.99h.01Zm-135.01-40.37c34 0 66.71 1.87 99.08-.66 21.47-1.67 30.97-17.92 31.56-39.77.61-22.88-9.01-40.56-30.99-42.73-32.8-3.23-66.15-.84-99.65-.84zM1674.39 829.9v38.37c-52.36 58.82-104.25 117.13-160.14 179.91h158.93v49.49h-227.62v-51.9c46.98-52.11 95.02-105.41 147.93-164.09h-147.28V829.9zm906.29-489.95c64.48 63.91 125.11 123.99 189.35 187.65V373.68h47.4v271.19c-64.19-62.94-125.05-122.59-190.04-186.3v162.44h-46.72V339.94h.01Zm195.02 692.31c13.79-6.85 33.51-15.76 45.41-21.65 41.44 55.26 105.07 42.53 132.33 18s35.44-59.98 25.2-95.47c-13.36-34.33-42.97-61.14-86.36-59.62-43.38 1.52-81.55 32.41-85.2 84.34h-50.32c-.57-50.11 36.27-109.35 94.12-126.75 72.77-21.89 144.89 13.23 172.07 83.77 25.18 65.37-5.74 138.6-72.21 171-60.69 29.59-140.17 6.97-175.1-53.61h.04Zm-811.82-622.07c-11.07 8.4-24.55 17.68-34.13 24.95-55.99-46.33-119.62-30.88-142.33 27.28-13.63 38.17 6.27 88.2 48.2 103.62 36.45 13.4 76.82-.61 87.32-31.48-8.66-2.61-17.29-5.23-28.25-8.54-.93-12.84-1.85-25.67-2.96-40.9h96.82c7.25 56.02-37.39 118.12-94.41 132.17-63.06 15.54-129.35-19.2-152.31-79.83-22.64-59.76 4.81-131.25 61.88-161.16 55.93-29.3 126.75-15.37 160.17 33.88Zm-531.9-55.25c48.2 92.28 93.04 178.13 139.88 267.84h-53.47c-27.89-50.55-56.47-102.34-86.73-157.13-28.93 54.29-56.1 105.29-83.82 157.31h-54.54c45.87-88.68 90.79-175.5 138.65-268.02h.01Zm1642.09 60.65h-89.98v-46.22h226.22v46.24h-86.43v205.91h-49.82V415.59zM1947.89 878.34v65.77l63.09.91s-.03 30.03-.03 50.34c-25.69.89-53.1.45-78.35-5.53-21.38-5.05-36.73-22.63-37.67-46.05-1.5-36.98-.4-75.88-.4-115.24h216.51v49.81h-163.16Zm-52.88 218.57v-68.62c14.11-.65 27.22-1.25 40.97-1.87 3.47 7 3.06 19.81 9.96 20.09 6.88.29 107.67 0 164.04 0v50.41h-214.97Zm342.4-678.53v60.83l58.36.84s-.03 27.78-.03 46.57c-23.85.41-49.12.41-72.49-5.11-19.77-4.68-33.97-20.93-34.85-42.59-1.39-34.2-.37-70.19-.37-106.6h200.29v46.07H2237.4h.01Zm-48.91 202.2v-63.49c13.05-.6 25.18-1.15 37.9-1.73 3.2 6.48 2.83 18.32 9.2 18.59s99.6 0 151.75 0v46.63h-198.87.01Z" class="st0"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,14 @@
version: "3.8"
services:
agent-zero:
image: agent0ai/agent-zero:v1.9
restart: unless-stopped
expose:
- "80"
environment:
- AUTH_LOGIN=${AUTH_LOGIN}
- AUTH_PASSWORD=${AUTH_PASSWORD}
volumes:
- agent-zero-data:/a0/usr
volumes:
agent-zero-data:

View File

@@ -0,0 +1,16 @@
[variables]
main_domain = "${domain}"
auth_login = "${username}"
auth_password = "${password:32}"
[config]
env = [
"AUTH_LOGIN=${auth_login}",
"AUTH_PASSWORD=${auth_password}",
]
mounts = []
[[config.domains]]
serviceName = "agent-zero"
port = 80
host = "${main_domain}"

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,30 @@
services:
alarik:
image: ghcr.io/achtungsoftware/alarik:latest
restart: unless-stopped
volumes:
- alarik-storage:/app/Storage
environment:
- API_BASE_URL=${API_BASE_URL}
- CONSOLE_BASE_URL=${CONSOLE_BASE_URL}
- ADMIN_USERNAME=${ADMIN_USERNAME}
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- JWT=${JWT}
- ALLOW_ACCOUNT_CREATION=${ALLOW_ACCOUNT_CREATION}
expose:
- 8080
console:
image: ghcr.io/achtungsoftware/alarik-console:latest
restart: unless-stopped
environment:
- NUXT_PUBLIC_API_BASE_URL=${API_BASE_URL}
- NUXT_PUBLIC_CONSOLE_BASE_URL=${CONSOLE_BASE_URL}
- NUXT_PUBLIC_ALLOW_ACCOUNT_CREATION=${ALLOW_ACCOUNT_CREATION}
expose:
- 3000
depends_on:
- alarik
volumes:
alarik-storage:

View File

@@ -0,0 +1,26 @@
[variables]
console_domain = "${domain}"
api_domain = "${domain}"
[config]
mounts = []
# S3-compatible API - point AWS CLI / SDKs / rclone / backup tools at this domain
[[config.domains]]
serviceName = "alarik"
port = 8_080
host = "${api_domain}"
# Web management console - log in with the generated admin credentials below
[[config.domains]]
serviceName = "console"
port = 3_000
host = "${console_domain}"
[config.env]
API_BASE_URL = "http://${api_domain}"
CONSOLE_BASE_URL = "http://${console_domain}"
ADMIN_USERNAME = "alarik"
ADMIN_PASSWORD = "${password:16}"
JWT = "${base64:64}"
ALLOW_ACCOUNT_CREATION = "false"

View File

@@ -8,12 +8,34 @@ x-logging: &x-logging
max-size: "10m"
services:
appwrite:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
<<: *x-logging
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.constraint-label-stack=appwrite
- 'traefik.http.routers.appwrite-sites-wildcard.rule=HostRegexp(`^.+\.${_APP_DOMAIN_SITES}$$`)'
- traefik.http.routers.appwrite-sites-wildcard.entrypoints=web
- traefik.http.routers.appwrite-sites-wildcard.service=appwrite-wildcard
- 'traefik.http.routers.appwrite-sites-wildcard-secure.rule=HostRegexp(`^.+\.${_APP_DOMAIN_SITES}$$`)'
- traefik.http.routers.appwrite-sites-wildcard-secure.entrypoints=websecure
- traefik.http.routers.appwrite-sites-wildcard-secure.tls=true
- traefik.http.routers.appwrite-sites-wildcard-secure.service=appwrite-wildcard
- 'traefik.http.routers.appwrite-functions-wildcard.rule=HostRegexp(`^.+\.${_APP_DOMAIN_FUNCTIONS}$$`)'
- traefik.http.routers.appwrite-functions-wildcard.entrypoints=web
- traefik.http.routers.appwrite-functions-wildcard.service=appwrite-wildcard
- 'traefik.http.routers.appwrite-functions-wildcard-secure.rule=HostRegexp(`^.+\.${_APP_DOMAIN_FUNCTIONS}$$`)'
- traefik.http.routers.appwrite-functions-wildcard-secure.entrypoints=websecure
- traefik.http.routers.appwrite-functions-wildcard-secure.tls=true
- traefik.http.routers.appwrite-functions-wildcard-secure.service=appwrite-wildcard
- traefik.http.services.appwrite-wildcard.loadbalancer.server.port=80
healthcheck:
test:
- CMD
- doctor
interval: 5s
timeout: 5s
retries: 12
volumes:
- appwrite-uploads:/storage/uploads:rw
- appwrite-imports:/storage/imports:rw
@@ -24,21 +46,25 @@ services:
- appwrite-sites:/storage/sites:rw
- appwrite-builds:/storage/builds:rw
depends_on:
- mariadb
- redis
# - clamav
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_EDITION
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_LOCALE
- _APP_COMPRESSION_ENABLED
- _APP_COMPRESSION_MIN_SIZE_BYTES
- _APP_CONSOLE_WHITELIST_ROOT
- _APP_CONSOLE_WHITELIST_EMAILS
- _APP_CONSOLE_SESSION_ALERTS
- _APP_CONSOLE_WHITELIST_IPS
- _APP_CONSOLE_HOSTNAMES
- _APP_CONSOLE_SCHEMA
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_SYSTEM_TEAM_EMAIL
- _APP_EMAIL_SECURITY
- _APP_SYSTEM_RESPONSE_FORMAT
- _APP_OPTIONS_ABUSE
@@ -47,6 +73,8 @@ services:
- _APP_OPTIONS_ROUTER_FORCE_HTTPS
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_CONSOLE_DOMAIN
- _APP_CONSOLE_TRUSTED_PROJECTS
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
- _APP_DOMAIN_TARGET_A
@@ -57,11 +85,18 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER_VECTORSDB
- _APP_DB_HOST_VECTORSDB
- _APP_DB_PORT_VECTORSDB
- _APP_DB_SCHEMA_VECTORSDB
- _APP_DB_USER_VECTORSDB
- _APP_DB_PASS_VECTORSDB
- _APP_SMTP_HOST
- _APP_SMTP_PORT
- _APP_SMTP_SECURE
@@ -108,8 +143,6 @@ services:
- _APP_EXECUTOR_HOST
- _APP_LOGGING_CONFIG
- _APP_MAINTENANCE_INTERVAL
- _APP_MAINTENANCE_DELAY
- _APP_MAINTENANCE_START_TIME
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_MAINTENANCE_RETENTION_CACHE
- _APP_MAINTENANCE_RETENTION_ABUSE
@@ -119,6 +152,7 @@ services:
- _APP_MAINTENANCE_RETENTION_SCHEDULES
- _APP_SMS_PROVIDER
- _APP_SMS_FROM
- _APP_GRAPHQL_INTROSPECTION
- _APP_GRAPHQL_MAX_BATCH_SIZE
- _APP_GRAPHQL_MAX_COMPLEXITY
- _APP_GRAPHQL_MAX_DEPTH
@@ -131,16 +165,26 @@ services:
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
- _APP_ASSISTANT_OPENAI_API_KEY
- _APP_CONSOLE_COUNTRIES_DENYLIST
- _APP_EXPERIMENT_LOGGING_PROVIDER
- _APP_EXPERIMENT_LOGGING_CONFIG
- _APP_DATABASE_SHARED_TABLES
- _APP_DATABASE_SHARED_NAMESPACE
- _APP_FUNCTIONS_CREATION_ABUSE_LIMIT
- _APP_CUSTOM_DOMAIN_DENY_LIST
- _APP_TRUSTED_HEADERS
- _APP_MIGRATION_HOST
appwrite-console:
<<: *x-logging
image: appwrite/console:7.4.7
image: appwrite/console:8.7.5
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.constraint-label-stack=appwrite"
appwrite-realtime:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: realtime
<<: *x-logging
restart: unless-stopped
@@ -148,7 +192,7 @@ services:
- "traefik.enable=true"
- "traefik.constraint-label-stack=appwrite"
depends_on:
- mariadb
- ${_APP_DB_HOST:-mongodb}
- redis
environment:
- _APP_ENV
@@ -160,51 +204,69 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER_VECTORSDB
- _APP_DB_HOST_VECTORSDB
- _APP_DB_PORT_VECTORSDB
- _APP_DB_SCHEMA_VECTORSDB
- _APP_DB_USER_VECTORSDB
- _APP_DB_PASS_VECTORSDB
- _APP_USAGE_STATS
- _APP_LOGGING_CONFIG
- _APP_LOGGING_CONFIG_REALTIME
- _APP_DATABASE_SHARED_TABLES
- _APP_POOL_ADAPTER=swoole
appwrite-worker-audits:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-audits
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_CONFIG
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-webhooks:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-webhooks
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_EMAIL_SECURITY
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -215,15 +277,17 @@ services:
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_LOGGING_CONFIG
- _APP_WEBHOOK_MAX_FAILED_ATTEMPTS
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-deletes:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-deletes
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
volumes:
- appwrite-uploads:/storage/uploads:rw
- appwrite-cache:/storage/cache:rw
@@ -233,12 +297,16 @@ services:
- appwrite-certificates:/storage/certificates:rw
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -269,52 +337,64 @@ services:
- _APP_LOGGING_CONFIG
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_DATABASE_SHARED_TABLES
- _APP_EMAIL_CERTIFICATES
- _APP_MAINTENANCE_RETENTION_AUDIT
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_EMAIL_CERTIFICATES
appwrite-worker-databases:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-databases
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DB_ADAPTER_VECTORSDB
- _APP_DB_HOST_VECTORSDB
- _APP_DB_PORT_VECTORSDB
- _APP_DB_SCHEMA_VECTORSDB
- _APP_DB_USER_VECTORSDB
- _APP_DB_PASS_VECTORSDB
- _APP_LOGGING_CONFIG
- _APP_QUEUE_NAME
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-builds:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-builds
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
volumes:
- appwrite-functions:/storage/functions:rw
- appwrite-sites:/storage/sites:rw
- appwrite-builds:/storage/builds:rw
- appwrite-uploads:/storage/uploads:rw
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
@@ -322,6 +402,7 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -336,10 +417,13 @@ services:
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_OPEN_RUNTIMES_NFT
- _APP_COMPUTE_SIZE_LIMIT
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPTIONS_ROUTER_FORCE_HTTPS
- _APP_DOMAIN
- _APP_CONSOLE_DOMAIN
- _APP_CONSOLE_TRUSTED_PROJECTS
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
@@ -362,22 +446,85 @@ services:
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_DATABASE_SHARED_TABLES
- _APP_DOMAIN_SITES
extra_hosts:
- host.docker.internal:host-gateway
appwrite-worker-screenshots:
image: appwrite/appwrite:1.9.5
entrypoint: worker-screenshots
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- ${_APP_DB_HOST:-mongodb}
volumes:
- appwrite-uploads:/storage/uploads:rw
environment:
- _APP_BROWSER_HOST
- _APP_WORKER_SCREENSHOTS_ROUTER
- _APP_OPTIONS_FORCE_HTTPS
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_LOGGING_CONFIG
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DATABASE_SHARED_TABLES
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
- _APP_STORAGE_S3_REGION
- _APP_STORAGE_S3_BUCKET
- _APP_STORAGE_S3_ENDPOINT
- _APP_STORAGE_DO_SPACES_ACCESS_KEY
- _APP_STORAGE_DO_SPACES_SECRET
- _APP_STORAGE_DO_SPACES_REGION
- _APP_STORAGE_DO_SPACES_BUCKET
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY
- _APP_STORAGE_BACKBLAZE_SECRET
- _APP_STORAGE_BACKBLAZE_REGION
- _APP_STORAGE_BACKBLAZE_BUCKET
- _APP_STORAGE_LINODE_ACCESS_KEY
- _APP_STORAGE_LINODE_SECRET
- _APP_STORAGE_LINODE_REGION
- _APP_STORAGE_LINODE_BUCKET
- _APP_STORAGE_WASABI_ACCESS_KEY
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
extra_hosts:
- host.docker.internal:host-gateway
appwrite-worker-certificates:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-certificates
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
volumes:
- appwrite-config:/storage/config:rw
- appwrite-certificates:/storage/certificates:rw
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
@@ -386,30 +533,64 @@ services:
- _APP_DOMAIN_TARGET_CAA
- _APP_DNS
- _APP_DOMAIN_FUNCTIONS
- _APP_DOMAIN_SITES
- _APP_EMAIL_CERTIFICATES
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_CONFIG
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-functions:
image: appwrite/appwrite:1.8.0
entrypoint: worker-functions
appwrite-worker-executions:
image: appwrite/appwrite:1.9.5
entrypoint: worker-executions
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_CONFIG
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-functions:
image: appwrite/appwrite:1.9.5
entrypoint: worker-functions
<<: *x-logging
restart: unless-stopped
depends_on:
- ${_APP_DB_HOST:-mongodb}
- redis
- openruntimes-executor
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=8
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_OPTIONS_FORCE_HTTPS
@@ -417,6 +598,7 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -433,9 +615,11 @@ services:
- _APP_DOCKER_HUB_USERNAME
- _APP_DOCKER_HUB_PASSWORD
- _APP_LOGGING_CONFIG
- _APP_LOGGING_PROVIDER
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-mails:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-mails
<<: *x-logging
restart: unless-stopped
@@ -443,19 +627,23 @@ services:
- redis
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_SMTP_HOST
- _APP_SMTP_PORT
- _APP_SMTP_SECURE
@@ -464,9 +652,10 @@ services:
- _APP_LOGGING_CONFIG
- _APP_DOMAIN
- _APP_OPTIONS_FORCE_HTTPS
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-messaging:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-messaging
<<: *x-logging
restart: unless-stopped
@@ -476,12 +665,16 @@ services:
- redis
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -490,6 +683,7 @@ services:
- _APP_LOGGING_CONFIG
- _APP_SMS_FROM
- _APP_SMS_PROVIDER
- _APP_SMS_PROJECTS_DENY_LIST
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
@@ -512,19 +706,24 @@ services:
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-migrations:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-migrations
<<: *x-logging
restart: unless-stopped
volumes:
- appwrite-imports:/storage/imports:rw
- appwrite-uploads:/storage/uploads:rw
depends_on:
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
@@ -537,6 +736,7 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -545,17 +745,22 @@ services:
- _APP_LOGGING_CONFIG
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
- _APP_DATABASE_SHARED_TABLES
- _APP_OPTIONS_FORCE_HTTPS
- _APP_MIGRATION_HOST
appwrite-task-maintenance:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: maintenance
<<: *x-logging
restart: unless-stopped
depends_on:
- ${_APP_DB_HOST:-mongodb}
- redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
@@ -568,6 +773,7 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -581,19 +787,58 @@ services:
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
- _APP_MAINTENANCE_RETENTION_SCHEDULES
- _APP_MAINTENANCE_START_TIME
- _APP_DATABASE_SHARED_TABLES
appwrite-task-interval:
image: appwrite/appwrite:1.9.5
entrypoint: interval
<<: *x-logging
restart: unless-stopped
depends_on:
- ${_APP_DB_HOST:-mongodb}
- redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
- _APP_DOMAIN_TARGET_A
- _APP_DOMAIN_TARGET_CAA
- _APP_DNS
- _APP_DOMAIN_FUNCTIONS
- _APP_DOMAIN_SITES
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DATABASE_SHARED_TABLES
- _APP_INTERVAL_DOMAIN_VERIFICATION
- _APP_INTERVAL_CLEANUP_STALE_EXECUTIONS
appwrite-task-stats-resources:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: stats-resources
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -609,42 +854,21 @@ services:
- _APP_STATS_RESOURCES_INTERVAL
appwrite-worker-stats-resources:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: worker-stats-resources
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_USAGE_STATS
- _APP_LOGGING_CONFIG
- _APP_STATS_RESOURCES_INTERVAL
appwrite-worker-stats-usage:
image: appwrite/appwrite:1.8.0
entrypoint: worker-stats-usage
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- mariadb
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
@@ -657,91 +881,145 @@ services:
- _APP_USAGE_STATS
- _APP_LOGGING_CONFIG
- _APP_USAGE_AGGREGATION_INTERVAL
- _APP_DATABASE_SHARED_TABLES
appwrite-worker-stats-usage:
image: appwrite/appwrite:1.9.5
entrypoint: worker-stats-usage
<<: *x-logging
restart: unless-stopped
depends_on:
- redis
- ${_APP_DB_HOST:-mongodb}
environment:
- _APP_ENV
- _APP_WORKERS_NUM=1
- _APP_WORKER_MAX_COROUTINES=1
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_USAGE_STATS
- _APP_LOGGING_CONFIG
- _APP_USAGE_AGGREGATION_INTERVAL
- _APP_DATABASE_SHARED_TABLES
appwrite-task-scheduler-functions:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: schedule-functions
<<: *x-logging
restart: unless-stopped
depends_on:
- mariadb
- ${_APP_DB_HOST:-mongodb}
- redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_OPTIONS_FORCE_HTTPS
- _APP_DOMAIN
- _APP_CONSOLE_DOMAIN
- _APP_DOMAIN_FUNCTIONS
- _APP_DOMAIN_SITES
- _APP_MIGRATION_HOST
- _APP_CONSOLE_SCHEMA
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DATABASE_SHARED_TABLES
appwrite-task-scheduler-executions:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: schedule-executions
<<: *x-logging
restart: unless-stopped
depends_on:
- mariadb
- ${_APP_DB_HOST:-mongodb}
- redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_OPTIONS_FORCE_HTTPS
- _APP_DOMAIN
- _APP_CONSOLE_DOMAIN
- _APP_DOMAIN_FUNCTIONS
- _APP_DOMAIN_SITES
- _APP_MIGRATION_HOST
- _APP_CONSOLE_SCHEMA
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DATABASE_SHARED_TABLES
appwrite-task-scheduler-messages:
image: appwrite/appwrite:1.8.0
image: appwrite/appwrite:1.9.5
entrypoint: schedule-messages
<<: *x-logging
restart: unless-stopped
depends_on:
- mariadb
- ${_APP_DB_HOST:-mongodb}
- redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_ADAPTER
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_DATABASE_SHARED_TABLES
appwrite-assistant:
image: appwrite/assistant:0.8.3
image: appwrite/assistant:0.8.4
<<: *x-logging
restart: unless-stopped
environment:
- _APP_ASSISTANT_OPENAI_API_KEY
appwrite-browser:
image: appwrite/browser:0.2.4
image: appwrite/browser:0.3.2
<<: *x-logging
restart: unless-stopped
openruntimes-executor:
hostname: exc1
hostname: openruntimes-executor
<<: *x-logging
restart: unless-stopped
stop_signal: SIGINT
image: openruntimes/executor:0.7.22
image: openruntimes/executor:0.25.1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- appwrite-builds:/storage/builds:rw
@@ -751,7 +1029,10 @@ services:
# It's not possible to share mount file between 2 containers without host mount (copying is too slow)
- /tmp:/tmp:rw
environment:
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD
- OPR_EXECUTOR_CONNECTION_STORAGE=local://localhost
- OPR_EXECUTOR_CONNECTION_BUILD_CACHE_STORAGE=
- OPR_EXECUTOR_IMAGES=$_APP_EXECUTOR_IMAGES
- OPR_EXECUTOR_INACTIVE_THRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_COMPUTE_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_COMPUTE_RUNTIMES_NETWORK
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
@@ -760,6 +1041,7 @@ services:
- OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES,$_APP_SITES_RUNTIMES
- OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET
- OPR_EXECUTOR_RUNTIME_VERSIONS=v5
- OPEN_RUNTIMES_NFT=$_APP_OPEN_RUNTIMES_NFT
- OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG
- OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE
- OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY
@@ -783,6 +1065,55 @@ services:
- OPR_EXECUTOR_STORAGE_WASABI_SECRET=$_APP_STORAGE_WASABI_SECRET
- OPR_EXECUTOR_STORAGE_WASABI_REGION=$_APP_STORAGE_WASABI_REGION
- OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET
healthcheck:
test:
- CMD-SHELL
- 'curl -fsS -H "Authorization: Bearer $$OPR_EXECUTOR_SECRET" http://localhost/v1/health >/dev/null'
interval: 5s
timeout: 3s
retries: 20
start_period: 5s
mongodb:
image: mongo:8.2.5
<<: *x-logging
restart: unless-stopped
volumes:
- appwrite-mongodb:/data/db
- appwrite-mongodb-keyfile:/data/keyfile
- ../files/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- ../files/mongo-entrypoint.sh:/mongo-entrypoint.sh:ro
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=${_APP_DB_ROOT_PASS}
- MONGO_INITDB_DATABASE=${_APP_DB_SCHEMA}
- MONGO_INITDB_USERNAME=${_APP_DB_USER}
- MONGO_INITDB_PASSWORD=${_APP_DB_PASS}
entrypoint:
- /bin/bash
- /mongo-entrypoint.sh
healthcheck:
test: |
bash -c "
mongosh -u root -p \"$$MONGO_INITDB_ROOT_PASSWORD\" --authenticationDatabase admin --quiet --eval \"
try {
const hello = db.adminCommand({hello: 1});
if (hello.isWritablePrimary) {
quit(0);
}
} catch (e) {}
try {
rs.initiate({_id: 'rs0', members: [{_id: 0, host: 'mongodb:27017'}]});
} catch (e) {}
quit(1);
\" 2>/dev/null
"
interval: 10s
timeout: 10s
retries: 10
start_period: 30s
mariadb:
image: mariadb:10.11 # fix issues when upgrading using: mysql_upgrade -u root -p
@@ -799,7 +1130,7 @@ services:
command: "mysqld --innodb-flush-method=fsync"
redis:
image: redis:7.2.4-alpine
image: redis:7.4.7-alpine
<<: *x-logging
restart: unless-stopped
command: >
@@ -818,6 +1149,8 @@ services:
volumes:
appwrite-mariadb:
appwrite-mongodb:
appwrite-mongodb-keyfile:
appwrite-redis:
appwrite-cache:
appwrite-uploads:

View File

@@ -10,58 +10,69 @@ executor_secret = "${password:32}"
[config]
env = [
"_APP_ENV=production",
"_APP_EDITION=self-hosted",
"_APP_LOCALE=en",
"_APP_POOL_ADAPTER=stack",
"_APP_WORKER_PER_CORE=6",
"_APP_OPTIONS_ABUSE=enabled",
"_APP_OPTIONS_FORCE_HTTPS=disabled",
"_APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled",
"_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled",
"_APP_OPTIONS_ROUTER_PROTECTION=disabled",
"_APP_OPENSSL_KEY_V1=${openssl_key}",
"_APP_DOMAIN=${main_domain}",
"_APP_CONSOLE_DOMAIN=${main_domain}",
"_APP_CONSOLE_TRUSTED_PROJECTS=",
"_APP_CUSTOM_DOMAIN_DENY_LIST=example.com,test.com,app.example.com",
"_APP_DOMAIN_FUNCTIONS=${functions_domain}",
"_APP_DOMAIN_SITES=${sites_domain}",
"_APP_DOMAIN_TARGET=localhost",
"_APP_DOMAIN_TARGET_CNAME=localhost",
"_APP_DOMAIN_TARGET_AAAA=::1",
"_APP_DOMAIN_TARGET_A=127.0.0.1",
"_APP_DOMAIN_TARGET_CAA=",
"_APP_DNS=8.8.8.8",
"_APP_TRUSTED_HEADERS=x-forwarded-for",
"_APP_CONSOLE_WHITELIST_ROOT=enabled",
"_APP_CONSOLE_WHITELIST_EMAILS=",
"_APP_CONSOLE_WHITELIST_IPS=",
"_APP_CONSOLE_HOSTNAMES=",
"_APP_CONSOLE_SCHEMA=appwriteio",
"_APP_CONSOLE_SESSION_ALERTS=disabled",
"_APP_CONSOLE_COUNTRIES_DENYLIST=",
"_APP_SYSTEM_EMAIL_NAME=Appwrite",
"_APP_SYSTEM_EMAIL_ADDRESS=noreply@appwrite.io",
"_APP_SYSTEM_TEAM_EMAIL=team@appwrite.io",
"_APP_SYSTEM_RESPONSE_FORMAT=",
"_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=certs@appwrite.io",
"_APP_EMAIL_SECURITY=",
"_APP_EMAIL_CERTIFICATES=",
"_APP_USAGE_STATS=enabled",
"_APP_LOGGING_PROVIDER=",
"_APP_LOGGING_CONFIG=",
"_APP_USAGE_AGGREGATION_INTERVAL=30",
"_APP_USAGE_TIMESERIES_INTERVAL=30",
"_APP_USAGE_DATABASE_INTERVAL=900",
"_APP_WORKER_PER_CORE=6",
"_APP_CONSOLE_SESSION_ALERTS=disabled",
"_APP_COMPRESSION_ENABLED=enabled",
"_APP_COMPRESSION_MIN_SIZE_BYTES=1024",
"_APP_USAGE_STATS=enabled",
"_APP_USAGE_AGGREGATION_INTERVAL=30",
"_APP_STATS_RESOURCES_INTERVAL=30",
"_APP_LOGGING_PROVIDER=",
"_APP_LOGGING_CONFIG=",
"_APP_LOGGING_CONFIG_REALTIME=",
"_APP_EXPERIMENT_LOGGING_PROVIDER=",
"_APP_EXPERIMENT_LOGGING_CONFIG=",
"_APP_REDIS_HOST=redis",
"_APP_REDIS_PORT=6379",
"_APP_REDIS_USER=",
"_APP_REDIS_PASS=",
"_APP_DB_HOST=mariadb",
"_APP_DB_PORT=3306",
"_APP_DB_ADAPTER=mongodb",
"_APP_DB_HOST=mongodb",
"_APP_DB_PORT=27017",
"_APP_DB_SCHEMA=appwrite",
"_APP_DB_USER=user",
"_APP_DB_PASS=${db_user_pw}",
"_APP_DB_ROOT_PASS=${db_root_pw}",
"_APP_INFLUXDB_HOST=influxdb",
"_APP_INFLUXDB_PORT=8086",
"_APP_STATSD_HOST=telegraf",
"_APP_STATSD_PORT=8125",
"_APP_DATABASE_SHARED_TABLES=",
"_APP_DATABASE_SHARED_NAMESPACE=",
"_APP_DB_ADAPTER_VECTORSDB=",
"_APP_DB_HOST_VECTORSDB=",
"_APP_DB_PORT_VECTORSDB=",
"_APP_DB_SCHEMA_VECTORSDB=",
"_APP_DB_USER_VECTORSDB=",
"_APP_DB_PASS_VECTORSDB=",
"_APP_SMTP_HOST=",
"_APP_SMTP_PORT=",
"_APP_SMTP_SECURE=",
@@ -69,6 +80,7 @@ env = [
"_APP_SMTP_PASSWORD=",
"_APP_SMS_PROVIDER=",
"_APP_SMS_FROM=",
"_APP_SMS_PROJECTS_DENY_LIST=",
"_APP_STORAGE_LIMIT=30000000",
"_APP_STORAGE_PREVIEW_LIMIT=20000000",
"_APP_STORAGE_ANTIVIRUS=disabled",
@@ -96,45 +108,27 @@ env = [
"_APP_STORAGE_WASABI_SECRET=",
"_APP_STORAGE_WASABI_REGION=eu-central-1",
"_APP_STORAGE_WASABI_BUCKET=",
"_APP_FUNCTIONS_SIZE_LIMIT=30000000",
"_APP_COMPUTE_SIZE_LIMIT=30000000",
"_APP_FUNCTIONS_BUILD_SIZE_LIMIT=2000000000",
"_APP_FUNCTIONS_TIMEOUT=900",
"_APP_FUNCTIONS_BUILD_TIMEOUT=900",
"_APP_COMPUTE_BUILD_TIMEOUT=900",
"_APP_FUNCTIONS_CONTAINERS=10",
"_APP_FUNCTIONS_CPUS=0",
"_APP_COMPUTE_CPUS=0",
"_APP_FUNCTIONS_MEMORY=0",
"_APP_COMPUTE_MEMORY=0",
"_APP_FUNCTIONS_MEMORY_SWAP=0",
"_APP_FUNCTIONS_RUNTIMES=node-16.0,php-8.0,python-3.9,ruby-3.0",
"_APP_EXECUTOR_SECRET=${executor_secret}",
"_APP_EXECUTOR_HOST=http://exc1/v1",
"_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes",
"_APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0",
"_APP_FUNCTIONS_INACTIVE_THRESHOLD=60",
"_APP_COMPUTE_INACTIVE_THRESHOLD=60",
"DOCKERHUB_PULL_USERNAME=",
"DOCKERHUB_PULL_PASSWORD=",
"DOCKERHUB_PULL_EMAIL=",
"OPEN_RUNTIMES_NETWORK=appwrite_runtimes",
"_APP_FUNCTIONS_RUNTIMES_NETWORK=dokploy-network",
"_APP_COMPUTE_MAINTENANCE_INTERVAL=3600",
"_APP_COMPUTE_RUNTIMES_NETWORK=dokploy-network",
"_APP_FUNCTIONS_TIMEOUT=900",
"_APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000",
"_APP_FUNCTIONS_RUNTIMES=node-22,python-3.12,php-8.3,ruby-3.3,dart-3.5,go-1.23,rust-1.83,bun-1.1,deno-1.46,java-21.0,dotnet-8.0",
"_APP_SITES_TIMEOUT=900",
"_APP_SITES_RUNTIMES=static-1,node-22",
"_APP_EXECUTOR_SECRET=${executor_secret}",
"_APP_EXECUTOR_HOST=http://openruntimes-executor/v1",
"_APP_EXECUTOR_IMAGES=openruntimes/node:v5-22,openruntimes/python:v5-3.12,openruntimes/php:v5-8.3,openruntimes/static:v5-1",
"_APP_OPEN_RUNTIMES_NFT=enabled",
"_APP_BROWSER_HOST=http://appwrite-browser:3000/v1",
"_APP_WORKER_SCREENSHOTS_ROUTER=http://appwrite",
"_APP_DOCKER_HUB_USERNAME=",
"_APP_DOCKER_HUB_PASSWORD=",
"_APP_FUNCTIONS_MAINTENANCE_INTERVAL=3600",
"_APP_COMPUTE_MAINTENANCE_INTERVAL=3600",
"_APP_SITES_TIMEOUT=900",
"_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29",
"_APP_VCS_GITHUB_APP_NAME=",
"_APP_VCS_GITHUB_PRIVATE_KEY=",
"_APP_VCS_GITHUB_APP_ID=",
"_APP_VCS_GITHUB_CLIENT_ID=",
"_APP_VCS_GITHUB_CLIENT_SECRET=",
"_APP_VCS_GITHUB_WEBHOOK_SECRET=",
"_APP_MAINTENANCE_INTERVAL=86400",
"_APP_MAINTENANCE_DELAY=0",
"_APP_MAINTENANCE_START_TIME=00:00",
"_APP_MAINTENANCE_RETENTION_CACHE=2592000",
"_APP_MAINTENANCE_RETENTION_EXECUTION=1209600",
@@ -143,14 +137,67 @@ env = [
"_APP_MAINTENANCE_RETENTION_ABUSE=86400",
"_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000",
"_APP_MAINTENANCE_RETENTION_SCHEDULES=86400",
"_APP_INTERVAL_DOMAIN_VERIFICATION=120",
"_APP_INTERVAL_CLEANUP_STALE_EXECUTIONS=300",
"_APP_GRAPHQL_INTROSPECTION=enabled",
"_APP_GRAPHQL_MAX_BATCH_SIZE=10",
"_APP_GRAPHQL_MAX_COMPLEXITY=250",
"_APP_GRAPHQL_MAX_DEPTH=3",
"_APP_GRAPHQL_MAX_DEPTH=4",
"_APP_WEBHOOK_MAX_FAILED_ATTEMPTS=10",
"_APP_VCS_GITHUB_APP_NAME=",
"_APP_VCS_GITHUB_PRIVATE_KEY=",
"_APP_VCS_GITHUB_APP_ID=",
"_APP_VCS_GITHUB_CLIENT_ID=",
"_APP_VCS_GITHUB_CLIENT_SECRET=",
"_APP_VCS_GITHUB_WEBHOOK_SECRET=",
"_APP_MIGRATION_HOST=appwrite",
"_APP_MIGRATIONS_FIREBASE_CLIENT_ID=",
"_APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=",
"_APP_ASSISTANT_OPENAI_API_KEY=",
]
mounts = []
[[config.mounts]]
filePath = "mongo-init.js"
content = """// mongo-init.js
// Switch to the admin database
const adminDb = db.getSiblingDB('admin');
// Get username and password from environment variables
const username = process.env.MONGO_INITDB_USERNAME;
const password = process.env.MONGO_INITDB_PASSWORD;
const database = process.env.MONGO_INITDB_DATABASE;
// Create the user
adminDb.createUser({
user: username,
pwd: password,
roles: [
{ role: 'readWrite', db: database }
]
});
"""
[[config.mounts]]
filePath = "mongo-entrypoint.sh"
content = """#!/bin/bash
set -e
# Fix keyfile permissions if mounted from volume
KEYFILE_PATH="/data/keyfile/mongo-keyfile"
if [ ! -f "$KEYFILE_PATH" ]; then
echo "Generating random MongoDB keyfile..."
mkdir -p /data/keyfile
openssl rand -base64 756 > "$KEYFILE_PATH"
fi
chmod 400 "$KEYFILE_PATH"
chown mongodb:mongodb "$KEYFILE_PATH" 2>/dev/null || chown 999:999 "$KEYFILE_PATH"
# Use MongoDB's standard entrypoint with our command
exec docker-entrypoint.sh mongod --replSet rs0 --bind_ip_all --auth --keyFile "$KEYFILE_PATH"
"""
[[config.domains]]
serviceName = "appwrite"

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"><g clip-path="url(#SvgjsClipPath1152)"><rect width="1000" height="1000" fill="#000000"></rect><g transform="matrix(3.401360544217687,0,0,3.401360544217687,250.00000000000003,265.30612244897964)"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="147" height="138" viewBox="0 0 147 138"><image width="147" height="138" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJMAAACKCAYAAACuPHhGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAZgSURBVHgB7Z3rddNAEIVHVBA6MB1AB04H6QCnAuiAQwehgogOoALUAXSAO0g6MBqzCvip1+zundX9zvEJIfkRS1efVrM760oCu91u0355FELGUVdVda//eCWEGMEwETMYJmIGw0TMYJiIGQwTMYNhImYwTMQMhomYwTARMxgmYgbDRMxgmIgZDBMxg2EiZjBMxAyGiZjBMBEzGCZiBsNEzGCYiBkMEzGDYSJmMEzEDIaJmMEwETMYJmIGw0TMYJiIGQwTMYNhImZUUgi73W7VfvktvnhuX2+qqnqWAijJTB/EHzft66MUQhFmClb60b5W4o9i7FSKmd6LzyApxdjJvZlaK+nJ+Cl+w6QUYacSzHQnvoOkFGGnEsykT3Ar8Y97O7k2U9hueiVl4N5Ors1UkJU6nlszvRanuDVTYVbquAnvyyVuzVSglTq2rZ3eiENcmqlQK3WsvNrJpZkKtlJH09rpVpzhzkyFW6lj3b7PtTjDnZkWYKUOd3ZyZaaFWKnDnZ283ebey7L4JI5wE6Zwla5lWbiykyczubpKDXHzvl2EaaFW6nBjJy9mWtpY6RgXdoIvDThtFIjBbVsqaAQYD2Za6ljpGPjjAG0mWukEXTy3FVDQzUQrHQJ9PGDNRCtdBNZOyGailc4Du7QX0ky00lVgGw9QzUQrXQa28QDOTLTSICDthGgmWqkfSDtBmcn5BhSpgbMTmplQN6D4JnjA2QnGTOBW0tajR8FbuQBlJyQzrQUzSHUoEn4VPKDshGQm1EaBfcU5bN2jf+ONYAFjJwgzATcKdFaScLK+CB4wdoIwE7qVum9op+tkNxOwlZrjCVVwO91JZrKbCdhKZ1c2Alfos294kdVMwFbaXloiG2zVCB7ZN7zIfZtDnTr5PPPnuci6F3q2MIFbqb72C8FajeDxNmdbVE4zebXS2N9LTbbjmiVMyFaSgfNwwU6/BI9sTZu5zITaVNmMrNUgTrEoWeyUvDQQrpofgsmoxfrARUzltkrctJnDTKhjpboa2fUBXMRUkh/npGYqyUodtNM/UpsJdaxUVxN70YKdOHaShGYCbxSYdQWX/N7GkNJMqGOlZu7BBp5iUZId9yRhClfuRjCxukWhFjGT1Z1SmQnVSr1TJ0MBnmJRkoxVo4+ZwMcT91ZhUkp8Wh1DCjMVb6WOYKetYBL9PEQNE/hYKVaxEbWIuQk1sWjENhNyq3esxspa/q7JRiRq40G0MIFbqY41fgCfYvkQ004xzYRspdiP8Q+CaaeobVFRwhSstBZM6thPNeBTLNHsFMtMqBtQKKmKi7VgEs1O5nUm8A0okn6GW3ss9DisBY8oTZsxzKTNgCvBJPWUB+oUSxQ7xTATalNllibFJdnJ1Ezgn1SZyxKoZQJzO5maiVY6T3tcngRzJaapnczMRCtdBdlOGzHCzEzIVmpf76qM282ArxM3s7aJmcCt1FSZ9y0Cn2Ix2/DCxEzAVlKir+MZwhLsNNtM4FaqEYKkBDt9F0xWFkt7Z5uJVhoO+ErM2bMDs8xEK40DfJ347MaDube5rJtL9YA6a486xaLMWjY0OUwhxW8Fk9m9cLEo2U5zzIS8+A3VSh3If9/k8zppAA4+kMy+6+wQgKdYlEkt5VPNhDxWQh6T/A9qEVOZZKfRZgJvqnRhJQW8iKmMttMUMyGPlZCv9gPAp1iU0ed5lJkcfH4uVJGyj2CnJ8FllJ3GmgnZSnBFyj7Au1iUURteDDYTrRQH8CdjZfBxHWMmWikC4EVMZfB5H2QmWikuDuz0esiasKFmQrZS4zlIigM7DWo86DWTAytNqtaiEVZgPAomgxoPhpgJ2UrbEoIU+Ca4W/EMaou6GibwbXEUL1MnvTgoYvZueNFnpiQba07EfBtBAB7EsZ0uholWSo93O10zE/K2OFvBfvqZw4PgctVO18K0EVzclwMuEezUCC4X7XQ2TOCNAkpxt7gjkN/fRTudrTOBty/p1Mm9FA7wVjzK2brTiZloJRjQ7bQ5/s8TM9FKOLTn4qfgdgCdrGo9MJMDK6F3nViD/H5PNrw4MBO4lZJuboqAg3XiB3Z6MROthIeDIqba6a775sVM4FZy03VijQM7vdwx9mbiExwuDtaJv7SU781EK2HjYE3Z3k6vQqpWgsvixkrHgH+gtLK3UwVeaVVcr++2wsE68eYPiYOoQetKl74AAAAASUVORK5CYII="></image></svg></g></g><defs><clipPath id="SvgjsClipPath1152"><rect width="1000" height="1000" x="0" y="0" rx="350" ry="350"></rect></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,102 @@
version: "3.8"
# Arche — AI workspace platform that spawns per-user OpenCode containers
# via a Docker socket proxy.
#
# PRE-REQUISITES (run once on the VPS before deploying):
# mkdir -p /opt/arche/kb-content /opt/arche/kb-config /opt/arche/users
#
# Optional (only needed to seed the Knowledge Base):
# git init --bare --initial-branch=main /opt/arche/kb-content
# git init --bare --initial-branch=main /opt/arche/kb-config
#
# POST-DEPLOY (set in Dokploy → Environment, then redeploy):
# 1. Deploy this template once. Dokploy auto-creates a network for the
# compose stack.
# 2. SSH into the host and find the network name:
# docker network ls --format '{{.Name}}' | grep arche
# It looks like `<stack-name>_default` or similar.
# 3. Add the env var OPENCODE_NETWORK=<that-network-name> and redeploy.
# Without it, spawned user workspaces will fail to start.
#
# IMAGE ARCHITECTURE:
# Default tags target linux/amd64. For ARM64 hosts (Apple Silicon,
# Ampere, Graviton), override both images to the `-arm64` variants in
# Dokploy → Environment:
# ARCHE_WEB_IMAGE=ghcr.io/peaberry-studio/arche/web:latest-arm64
# ARCHE_WORKSPACE_IMAGE=ghcr.io/peaberry-studio/arche/workspace:latest-arm64
services:
web:
image: ${ARCHE_WEB_IMAGE:-ghcr.io/peaberry-studio/arche/web:latest}
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
docker-socket-proxy:
condition: service_started
environment:
ARCHE_DOMAIN: ${ARCHE_DOMAIN}
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/arche?schema=public
ARCHE_SESSION_PEPPER: ${ARCHE_SESSION_PEPPER}
ARCHE_ENCRYPTION_KEY: ${ARCHE_ENCRYPTION_KEY}
ARCHE_INTERNAL_TOKEN: ${ARCHE_INTERNAL_TOKEN}
ARCHE_GATEWAY_TOKEN_SECRET: ${ARCHE_GATEWAY_TOKEN_SECRET}
ARCHE_CONNECTOR_OAUTH_STATE_SECRET: ${ARCHE_CONNECTOR_OAUTH_STATE_SECRET}
ARCHE_GATEWAY_TOKEN_TTL_SECONDS: "86400"
ARCHE_GATEWAY_BASE_URL: http://web:3000
ARCHE_PUBLIC_BASE_URL: https://${ARCHE_DOMAIN}
ARCHE_SESSION_TTL_DAYS: "7"
ARCHE_COOKIE_SECURE: "true"
ARCHE_SEED_ADMIN_EMAIL: ${ARCHE_SEED_ADMIN_EMAIL}
ARCHE_SEED_ADMIN_PASSWORD: ${ARCHE_SEED_ADMIN_PASSWORD}
ARCHE_SEED_ADMIN_SLUG: ${ARCHE_SEED_ADMIN_SLUG:-admin}
CONTAINER_PROXY_HOST: docker-socket-proxy
CONTAINER_PROXY_PORT: "2375"
OPENCODE_IMAGE: ${ARCHE_WORKSPACE_IMAGE:-ghcr.io/peaberry-studio/arche/workspace:latest}
OPENCODE_NETWORK: ${OPENCODE_NETWORK}
KB_CONTENT_HOST_PATH: /opt/arche/kb-content
KB_CONFIG_HOST_PATH: /opt/arche/kb-config
ARCHE_USERS_PATH: /opt/arche/users
expose:
- "3000"
volumes:
- /opt/arche/kb-content:/kb-content
- /opt/arche/kb-config:/kb-config
- /opt/arche/users:/opt/arche/users
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: arche
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
docker-socket-proxy:
image: ghcr.io/tecnativa/docker-socket-proxy:master
restart: unless-stopped
environment:
CONTAINERS: 1
NETWORKS: 1
IMAGES: 1
INFO: 1
POST: 1
VOLUMES: 1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes:
postgres_data:

View File

@@ -0,0 +1,33 @@
[variables]
main_domain = "${domain}"
postgres_password = "${password:32}"
session_pepper = "${base64:32}"
encryption_key = "${base64:32}"
internal_token = "${base64:32}"
gateway_token_secret = "${base64:32}"
connector_oauth_state_secret = "${base64:32}"
seed_admin_email = "${email}"
seed_admin_password = "${password:16}"
[config]
env = [
"ARCHE_DOMAIN=${main_domain}",
"POSTGRES_PASSWORD=${postgres_password}",
"ARCHE_SESSION_PEPPER=${session_pepper}",
"ARCHE_ENCRYPTION_KEY=${encryption_key}",
"ARCHE_INTERNAL_TOKEN=${internal_token}",
"ARCHE_GATEWAY_TOKEN_SECRET=${gateway_token_secret}",
"ARCHE_CONNECTOR_OAUTH_STATE_SECRET=${connector_oauth_state_secret}",
"ARCHE_SEED_ADMIN_EMAIL=${seed_admin_email}",
"ARCHE_SEED_ADMIN_PASSWORD=${seed_admin_password}",
"ARCHE_SEED_ADMIN_SLUG=admin",
"ARCHE_WEB_IMAGE=ghcr.io/peaberry-studio/arche/web:latest",
"ARCHE_WORKSPACE_IMAGE=ghcr.io/peaberry-studio/arche/workspace:latest",
"OPENCODE_NETWORK=",
]
mounts = []
[[config.domains]]
serviceName = "web"
port = 3000
host = "${main_domain}"

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<rect width="128" height="128" rx="28" fill="#101828"/>
<circle cx="64" cy="64" r="34" fill="#38bdf8" opacity="0.92"/>
<text x="64" y="74" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" font-weight="700" fill="#ffffff">A</text>
</svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@@ -0,0 +1,16 @@
services:
archivebox:
image: archivebox/archivebox:latest
restart: unless-stopped
command: server --quick-init 0.0.0.0:8000
environment:
ALLOWED_HOSTS: ${ALLOWED_HOSTS}
PUBLIC_INDEX: ${PUBLIC_INDEX}
PUBLIC_SNAPSHOTS: ${PUBLIC_SNAPSHOTS}
volumes:
- archivebox_data:/data
ports:
- "8000"
volumes:
archivebox_data:

View File

@@ -0,0 +1,15 @@
[variables]
main_domain = "${domain}"
[config]
mounts = []
[[config.domains]]
serviceName = "archivebox"
port = 8000
host = "${main_domain}"
[config.env]
ALLOWED_HOSTS = "*"
PUBLIC_INDEX = "True"
PUBLIC_SNAPSHOTS = "True"

View File

@@ -1,6 +1,6 @@
services:
autobase-console:
image: autobase/console:2.5.2
image: autobase/console:2.7.2
restart: unless-stopped
ports:
- "80"
@@ -10,8 +10,10 @@ services:
- PG_CONSOLE_AUTHORIZATION_TOKEN=${PG_CONSOLE_AUTHORIZATION_TOKEN}
volumes:
- console_postgres:/var/lib/postgresql
- dbdesk_studio_data:/opt/dbdesk-studio
- /var/run/docker.sock:/var/run/docker.sock
- /tmp/ansible:/tmp/ansible
volumes:
console_postgres:
dbdesk_studio_data:

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

@@ -0,0 +1,29 @@
version: "3.8"
services:
chatto:
image: ghcr.io/chattocorp/chatto:0.3.8
restart: unless-stopped
expose:
- "4000"
environment:
CHATTO_WEBSERVER_URL: https://${CHATTO_HOST}
CHATTO_WEBSERVER_PORT: "4000"
CHATTO_WEBSERVER_COOKIE_SIGNING_SECRET: ${CHATTO_COOKIE_SECRET}
CHATTO_CORE_SECRET_KEY: ${CHATTO_CORE_SECRET}
CHATTO_CORE_ASSETS_SIGNING_SECRET: ${CHATTO_ASSETS_SECRET}
CHATTO_NATS_EMBEDDED_ENABLED: true
CHATTO_NATS_EMBEDDED_DATA_DIR: /data
CHATTO_OWNERS_EMAILS: ${CHATTO_OWNER_EMAIL}
CHATTO_SMTP_ENABLED: ${CHATTO_SMTP_ENABLED:-false}
CHATTO_SMTP_HOST: ${CHATTO_SMTP_HOST:-}
CHATTO_SMTP_PORT: ${CHATTO_SMTP_PORT:-587}
CHATTO_SMTP_TLS: ${CHATTO_SMTP_TLS:-mandatory}
CHATTO_SMTP_USERNAME: ${CHATTO_SMTP_USERNAME:-}
CHATTO_SMTP_PASSWORD: ${CHATTO_SMTP_PASSWORD:-}
CHATTO_SMTP_FROM: ${CHATTO_SMTP_FROM:-}
volumes:
- chatto-data:/data
volumes:
chatto-data:

BIN
blueprints/chatto/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,21 @@
[variables]
main_domain = "${domain}"
cookie_secret = "${hash:64}"
core_secret = "${hash:64}"
assets_secret = "${hash:64}"
owner_email = "${email}"
[config]
env = [
"CHATTO_HOST=${main_domain}",
"CHATTO_COOKIE_SECRET=${cookie_secret}",
"CHATTO_CORE_SECRET=${core_secret}",
"CHATTO_ASSETS_SECRET=${assets_secret}",
"CHATTO_OWNER_EMAIL=${owner_email}",
]
mounts = []
[[config.domains]]
serviceName = "chatto"
port = 4000
host = "${main_domain}"

View File

@@ -1,6 +1,7 @@
variables = {}
[config]
isolated = false
domains = []
mounts = []

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,41 @@
version: "3.8"
services:
crawlab-master:
image: crawlabteam/crawlab:latest
restart: unless-stopped
environment:
- CRAWLAB_NODE_MASTER=Y
- CRAWLAB_MONGO_HOST=mongo
- CRAWLAB_MONGO_PORT=27017
- CRAWLAB_MONGO_DB=crawlab
- CRAWLAB_MONGO_USERNAME=${MONGO_USERNAME}
- CRAWLAB_MONGO_PASSWORD=${MONGO_PASSWORD}
- CRAWLAB_MONGO_AUTHSOURCE=admin
volumes:
- crawlab-master-data:/root/.crawlab
- crawlab-app-data:/data
- crawlab-logs:/var/log/crawlab
expose:
- "8080"
- "9666"
depends_on:
- mongo
deploy:
resources:
limits:
cpus: "${CPU_LIMIT:-0.8}" # 0.8 will limit to 80% of CPU if one core. If 2 cores, you need to put 0.8*2=1.6
mongo:
image: mongo:4.2
restart: unless-stopped
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
volumes:
- mongo-data:/data/db
volumes:
crawlab-master-data:
crawlab-app-data:
crawlab-logs:
mongo-data:

View File

@@ -0,0 +1,12 @@
[variables]
MONGO_USERNAME = "crawlab"
MONGO_PASSWORD = "${password:24}"
CPU_LIMIT = "0.8"
[config]
env = ["MONGO_USERNAME=${MONGO_USERNAME}", "MONGO_PASSWORD=${MONGO_PASSWORD}", "CPU_LIMIT=${CPU_LIMIT}"]
[[config.domains]]
serviceName = "crawlab-master"
port = 8080
host = "${domain}"

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,20 @@
version: "3.8"
services:
crawlab-worker:
image: crawlabteam/crawlab:latest
restart: unless-stopped
environment:
- CRAWLAB_NODE_MASTER=N
- CRAWLAB_GRPC_ADDRESS=${MASTER_GRPC_ADDRESS}
- CRAWLAB_FS_FILER_URL=${MASTER_FILER_URL}
volumes:
- crawlab-worker-data:/root/.crawlab
- crawlab-worker-app:/data
deploy:
resources:
limits:
cpus: "${CPU_LIMIT:-0.8}" # 0.8 will limit to 80% of CPU if one core. If 2 cores, you need to put 0.8*2=1.6
volumes:
crawlab-worker-data:
crawlab-worker-app:

View File

@@ -0,0 +1,7 @@
[variables]
MASTER_GRPC_ADDRESS = "<master_node_ip>:9666"
MASTER_FILER_URL = "http://<master_node_ip>:8080/api/filer"
CPU_LIMIT = "0.8"
[config]
env = ["MASTER_GRPC_ADDRESS=${MASTER_GRPC_ADDRESS}", "MASTER_FILER_URL=${MASTER_FILER_URL}", "CPU_LIMIT=${CPU_LIMIT}"]

10
blueprints/cut/cut.svg Normal file
View File

@@ -0,0 +1,10 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Cut logo">
<rect width="64" height="64" rx="16" fill="#059669"/>
<g transform="translate(14 14) scale(1.5)" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="6" cy="6" r="3"/>
<path d="M8.12 8.12 12 12"/>
<path d="M20 4 8.12 15.88"/>
<circle cx="6" cy="18" r="3"/>
<path d="M14.8 14.8 20 20"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 494 B

View File

@@ -0,0 +1,37 @@
services:
cut:
image: ghcr.io/mendylanda/cut:latest
restart: unless-stopped
depends_on:
redis:
condition: service_healthy
environment:
# Injected by Dokploy from template.toml (generated strong password).
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
# Bundled Redis below, private to the project network.
- REDIS_URL=redis://redis:6379
# Expose the container port only; Dokploy maps the domain to it.
ports:
- 3000
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/"]
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis:7-alpine
restart: unless-stopped
# appendonly = durable across restarts; noeviction because this is Cut's
# primary datastore, not a cache (don't drop links under memory pressure).
command: redis-server --appendonly yes --maxmemory-policy noeviction
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
volumes:
redis-data:

View File

@@ -0,0 +1,14 @@
[variables]
main_domain = "${domain}"
admin_password = "${password:24}"
[config]
env = [
"ADMIN_PASSWORD=${admin_password}",
]
mounts = []
[[config.domains]]
serviceName = "cut"
port = 3000
host = "${main_domain}"

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -1,29 +1,24 @@
version: '3.7'
services:
discourse-db:
image: docker.io/bitnami/postgresql:17
image: pgvector/pgvector:pg16
volumes:
- discourse-postgresql-data:/bitnami/postgresql
- discourse-postgresql-data:/var/lib/postgresql/data
environment:
POSTGRESQL_USERNAME: bn_discourse
POSTGRESQL_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRESQL_DATABASE: bitnami_discourse
POSTGRES_USER: discourse
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: discourse
healthcheck:
test: ["CMD-SHELL", "pg_isready -U bn_discourse -d bitnami_discourse"]
test: ["CMD-SHELL", "pg_isready -U discourse -d discourse"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
discourse-redis:
image: docker.io/bitnami/redis:7.4
image: redis:7-alpine
volumes:
- discourse-redis-data:/bitnami/redis
environment:
REDIS_PASSWORD: ${REDIS_PASSWORD}
- discourse-redis-data:/data
command: redis-server --requirepass ${REDIS_PASSWORD}
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
@@ -32,59 +27,38 @@ services:
restart: unless-stopped
discourse-app:
image: docker.io/bitnamilegacy/discourse:3.5.0
image: discourse/discourse:2026.1.4
volumes:
- discourse-data:/bitnami/discourse
- discourse-data:/shared
depends_on:
discourse-db:
condition: service_healthy
discourse-redis:
condition: service_healthy
environment:
DISCOURSE_HOST: ${DISCOURSE_HOST}
DISCOURSE_DATABASE_HOST: discourse-db
DISCOURSE_DATABASE_PORT_NUMBER: 5432
DISCOURSE_DATABASE_USER: bn_discourse
DISCOURSE_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
DISCOURSE_DATABASE_NAME: bitnami_discourse
DISCOURSE_HOSTNAME: ${DISCOURSE_HOST}
DISCOURSE_DB_HOST: discourse-db
DISCOURSE_DB_PORT: 5432
DISCOURSE_DB_USERNAME: discourse
DISCOURSE_DB_PASSWORD: ${POSTGRES_PASSWORD}
DISCOURSE_DB_NAME: discourse
DISCOURSE_REDIS_HOST: discourse-redis
DISCOURSE_REDIS_PORT_NUMBER: 6379
DISCOURSE_REDIS_PORT: 6379
DISCOURSE_REDIS_PASSWORD: ${REDIS_PASSWORD}
# Optional: Configure SMTP for email delivery
# DISCOURSE_SMTP_HOST: ${SMTP_HOST}
DISCOURSE_DEVELOPER_EMAILS: ${DISCOURSE_ADMIN_EMAIL}
# Required for email delivery - Discourse will not function correctly without SMTP
# DISCOURSE_SMTP_ADDRESS: ${SMTP_HOST}
# DISCOURSE_SMTP_PORT: ${SMTP_PORT}
# DISCOURSE_SMTP_USER: ${SMTP_USER}
# DISCOURSE_SMTP_PASSWORD: ${SMTP_PASSWORD}
restart: unless-stopped
discourse-sidekiq:
image: docker.io/bitnamilegacy/discourse:3.5.0
volumes:
- discourse-sidekiq-data:/bitnami/discourse
depends_on:
- discourse-app
command: /opt/bitnami/scripts/discourse-sidekiq/run.sh
environment:
DISCOURSE_HOST: ${DISCOURSE_HOST}
DISCOURSE_DATABASE_HOST: discourse-db
DISCOURSE_DATABASE_PORT_NUMBER: 5432
DISCOURSE_DATABASE_USER: bn_discourse
DISCOURSE_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
DISCOURSE_DATABASE_NAME: bitnami_discourse
DISCOURSE_REDIS_HOST: discourse-redis
DISCOURSE_REDIS_PORT_NUMBER: 6379
DISCOURSE_REDIS_PASSWORD: ${REDIS_PASSWORD}
# Optional: Configure SMTP for email delivery
# DISCOURSE_SMTP_HOST: ${SMTP_HOST}
# DISCOURSE_SMTP_PORT: ${SMTP_PORT}
# DISCOURSE_SMTP_USER: ${SMTP_USER}
# DISCOURSE_SMTP_USER_NAME: ${SMTP_USER}
# DISCOURSE_SMTP_PASSWORD: ${SMTP_PASSWORD}
# DISCOURSE_SMTP_ENABLE_START_TLS: "true"
# DISCOURSE_NOTIFICATION_EMAIL: [email protected]
# DISCOURSE_DEVELOPER_EMAILS: [email protected]
ports:
- 80
restart: unless-stopped
volumes:
discourse-postgresql-data:
discourse-redis-data:
discourse-data:
discourse-sidekiq-data:

View File

@@ -1,11 +1,13 @@
[variables]
main_domain = "${domain}"
admin_email = "${email}"
postgres_password = "${password}"
redis_password = "${password}"
[config]
env = [
"DISCOURSE_HOST=${main_domain}",
"DISCOURSE_ADMIN_EMAIL=${admin_email}",
"POSTGRES_PASSWORD=${postgres_password}",
"REDIS_PASSWORD=${redis_password}",
]
@@ -13,5 +15,5 @@ mounts = []
[[config.domains]]
serviceName = "discourse-app"
port = 3_000
host = "${main_domain}"
port = 80
host = "${main_domain}"

View File

@@ -0,0 +1,16 @@
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- dockge_data:/app/data
- dockge_stacks:/opt/stacks
environment:
DOCKGE_STACKS_DIR: /opt/stacks
ports:
- "5001"
volumes:
dockge_data:
dockge_stacks:

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<rect width="128" height="128" rx="28" fill="#101828"/>
<circle cx="64" cy="64" r="34" fill="#38bdf8" opacity="0.92"/>
<text x="64" y="74" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" font-weight="700" fill="#ffffff">D</text>
</svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@@ -0,0 +1,11 @@
[variables]
main_domain = "${domain}"
[config]
env = {}
mounts = []
[[config.domains]]
serviceName = "dockge"
port = 5001
host = "${main_domain}"

View File

@@ -0,0 +1,37 @@
version: "3.8"
services:
db:
image: postgres:17
restart: unless-stopped
volumes:
- fiderPostgresData:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
fider:
image: getfider/fider:0.21.1
restart: unless-stopped
depends_on:
- db
- mailhog
environment:
BASE_URL: ${BASE_URL}
DATABASE_URL: ${DATABASE_URL}
JWT_SECRET: ${JWT_SECRET}
EMAIL: ${EMAIL}
EMAIL_NOREPLY: ${EMAIL_NOREPLY}
EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST}
EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT}
EMAIL_SMTP_USERNAME: ${EMAIL_SMTP_USERNAME}
EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD}
EMAIL_SMTP_ENABLE_STARTTLS: ${EMAIL_SMTP_ENABLE_STARTTLS}
mailhog:
image: mailhog/mailhog:v1.0.1
restart: unless-stopped
volumes:
fiderPostgresData:

View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" role="img" aria-labelledby="title desc">
<title id="title">Fider</title>
<desc id="desc">Fider template logo</desc>
<rect width="256" height="256" rx="54" fill="#0f766e"/>
<path d="M65 74c0-12 10-22 22-22h82c12 0 22 10 22 22v58c0 12-10 22-22 22h-39l-40 36c-6 5-15 1-15-7v-29h-8c-12 0-22-10-22-22V74z" fill="#ecfeff"/>
<circle cx="96" cy="103" r="10" fill="#0f766e"/>
<circle cx="128" cy="103" r="10" fill="#0f766e"/>
<circle cx="160" cy="103" r="10" fill="#0f766e"/>
</svg>

After

Width:  |  Height:  |  Size: 549 B

View File

@@ -0,0 +1,27 @@
[variables]
main_domain = "${domain}"
postgres_password = "${password:32}"
jwt_secret = "${password:64}"
[config]
env = [
"POSTGRES_USER=fider",
"POSTGRES_PASSWORD=${postgres_password}",
"POSTGRES_DB=fider",
"BASE_URL=https://${main_domain}",
"DATABASE_URL=postgres://fider:${postgres_password}@db:5432/fider?sslmode=disable",
"JWT_SECRET=${jwt_secret}",
"EMAIL_NOREPLY=noreply@${main_domain}",
"EMAIL=smtp",
"EMAIL_SMTP_HOST=mailhog",
"EMAIL_SMTP_PORT=1025",
"EMAIL_SMTP_USERNAME=",
"EMAIL_SMTP_PASSWORD=",
"EMAIL_SMTP_ENABLE_STARTTLS=true",
]
mounts = []
[[config.domains]]
serviceName = "fider"
port = 3000
host = "${main_domain}"

View File

@@ -0,0 +1,13 @@
services:
filegator:
image: filegator/filegator:v7.14.3
restart: unless-stopped
volumes:
- filegator_repository:/var/www/filegator/repository
- filegator_private:/var/www/filegator/private
ports:
- "8080"
volumes:
filegator_repository:
filegator_private:

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<rect width="128" height="128" rx="28" fill="#101828"/>
<circle cx="64" cy="64" r="34" fill="#38bdf8" opacity="0.92"/>
<text x="64" y="74" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" font-weight="700" fill="#ffffff">F</text>
</svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@@ -0,0 +1,11 @@
[variables]
main_domain = "${domain}"
[config]
env = {}
mounts = []
[[config.domains]]
serviceName = "filegator"
port = 8080
host = "${main_domain}"

View File

@@ -0,0 +1,13 @@
# Firefly III
Firefly III is a self-hosted personal finance manager for budgets, accounts, transactions, categories, and reports.
This Dokploy template includes:
- Firefly III core web application
- MariaDB database with generated credentials
- Persistent upload and database volumes
- Daily cron runner using Firefly III's static cron token
- Dokploy domain routing on the application service
After deployment, open the generated domain and complete the first-user setup flow.

View File

@@ -0,0 +1,65 @@
version: "3.8"
services:
firefly-iii:
image: fireflyiii/core:version-6.6.3
restart: unless-stopped
depends_on:
firefly-iii-db:
condition: service_healthy
environment:
APP_KEY: ${APP_KEY}
APP_URL: ${APP_URL}
TRUSTED_PROXIES: "**"
TZ: ${TZ}
SITE_OWNER: ${SITE_OWNER}
DEFAULT_LANGUAGE: ${DEFAULT_LANGUAGE}
DEFAULT_LOCALE: ${DEFAULT_LOCALE}
DB_CONNECTION: mysql
DB_HOST: firefly-iii-db
DB_PORT: 3306
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
STATIC_CRON_TOKEN: ${STATIC_CRON_TOKEN}
expose:
- "8080"
volumes:
- firefly-iii-upload:/var/www/html/storage/upload
firefly-iii-db:
image: mariadb:11.8
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
volumes:
- firefly-iii-db:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
firefly-iii-cron:
image: alpine:3.22
restart: unless-stopped
depends_on:
- firefly-iii
environment:
TZ: ${TZ}
STATIC_CRON_TOKEN: ${STATIC_CRON_TOKEN}
command:
- sh
- -c
- |
apk add --no-cache tzdata wget && \
(ln -snf /usr/share/zoneinfo/$$TZ /etc/localtime || true) && \
echo "0 3 * * * wget -qO- http://firefly-iii:8080/api/v1/cron/$$STATIC_CRON_TOKEN; echo" | crontab - && \
crond -f -L /dev/stdout
volumes:
firefly-iii-upload: {}
firefly-iii-db: {}

View File

@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="Firefly III">
<defs>
<linearGradient id="g" x1="20" y1="16" x2="108" y2="112" gradientUnits="userSpaceOnUse">
<stop stop-color="#ffcf4a"/>
<stop offset="0.55" stop-color="#ff7a1a"/>
<stop offset="1" stop-color="#7936d8"/>
</linearGradient>
</defs>
<rect width="128" height="128" rx="28" fill="#171923"/>
<circle cx="64" cy="66" r="38" fill="url(#g)" opacity="0.2"/>
<path d="M64 23c8 15 20 27 34 35-14 8-26 20-34 35-8-15-20-27-34-35 14-8 26-20 34-35Z" fill="url(#g)"/>
<circle cx="64" cy="58" r="13" fill="#fff4c7"/>
<path d="M46 93h36c-3 9-9 14-18 14s-15-5-18-14Z" fill="#ffcf4a"/>
</svg>

After

Width:  |  Height:  |  Size: 715 B

View File

@@ -0,0 +1,36 @@
[variables]
main_domain = "${domain}"
app_key = "${base64:32}"
db_name = "firefly"
db_user = "firefly"
db_password = "${password:32}"
cron_token = "${hash:32}"
site_owner = "${email}"
timezone = "UTC"
default_language = "en_US"
default_locale = "equal"
[config]
env = [
"APP_KEY=base64:${app_key}",
"APP_URL=https://${main_domain}",
"TRUSTED_PROXIES=**",
"TZ=${timezone}",
"SITE_OWNER=${site_owner}",
"DEFAULT_LANGUAGE=${default_language}",
"DEFAULT_LOCALE=${default_locale}",
"DB_DATABASE=${db_name}",
"DB_USERNAME=${db_user}",
"DB_PASSWORD=${db_password}",
"STATIC_CRON_TOKEN=${cron_token}",
"MYSQL_DATABASE=${db_name}",
"MYSQL_USER=${db_user}",
"MYSQL_PASSWORD=${db_password}",
"MYSQL_RANDOM_ROOT_PASSWORD=yes"
]
mounts = []
[[config.domains]]
serviceName = "firefly-iii"
port = 8080
host = "${main_domain}"

View File

@@ -0,0 +1,550 @@
x-custom-image: &custom_image
image: ${IMAGE_NAME:-frappe/erpnext}:${VERSION:-v15}
pull_policy: ${PULL_POLICY:-always}
deploy:
restart_policy:
condition: always
services:
backend:
<<: *custom_image
entrypoint: ["bash", "-c"]
command:
- >
cd /home/frappe/frappe-bench;
if [ -d "apps/lending" ] && ! ./env/bin/pip show lending > /dev/null 2>&1; then
echo "Installing lending app in Python environment...";
./env/bin/pip install -e apps/lending || echo "Failed to install lending";
fi;
echo "Waiting for site to be ready...";
export start=`date +%s`;
while [ ! -f "sites/sites.txt" ] || [ ! -d "sites/${SITE_NAME}" ] || [ ! -f "sites/${SITE_NAME}/site_config.json" ]; do
echo "Waiting for site ${SITE_NAME} to be created and ready...";
sleep 2;
if (( `date +%s`-start > 300 )); then
echo "Timeout waiting for site to be ready";
echo "Checking sites directory:";
ls -la sites/ || echo "sites directory not found";
echo "Checking sites.txt:";
cat sites/sites.txt 2>/dev/null || echo "sites.txt not found";
break;
fi
done;
if [ -f "sites/sites.txt" ] && [ -d "sites/${SITE_NAME}" ] && [ -f "sites/${SITE_NAME}/site_config.json" ]; then
echo "Site ${SITE_NAME} is ready!";
echo "sites.txt contents:";
cat sites/sites.txt;
echo "Verifying site is accessible via bench...";
bench --site ${SITE_NAME} list-apps > /dev/null 2>&1 && echo "Site is accessible via bench" || echo "Warning: Site accessibility check via bench failed";
echo "Site directory structure:";
ls -la sites/${SITE_NAME}/ | head -10;
if [ -n "${MAIN_DOMAIN}" ]; then
echo "Updating host_name and SSL settings to https://${MAIN_DOMAIN} (ensuring correct domain for emails)...";
bench --site ${SITE_NAME} set-config host_name "https://${MAIN_DOMAIN}" || echo "Warning: Could not update host_name";
bench --site ${SITE_NAME} set-config host_url "https://${MAIN_DOMAIN}" || echo "Warning: Could not update host_url";
bench --site ${SITE_NAME} set-config use_ssl 1 || echo "Warning: Could not set use_ssl";
echo "Verifying configuration...";
bench --site ${SITE_NAME} get-config host_name 2>/dev/null || echo "Could not read host_name (this is OK if site is not fully initialized)";
echo "Clearing cache to apply new domain settings...";
bench --site ${SITE_NAME} clear-cache || echo "Warning: Could not clear cache";
bench --site ${SITE_NAME} clear-website-cache || echo "Warning: Could not clear website cache";
fi;
else
echo "Warning: Site may not be fully ready, but starting backend anyway";
fi;
echo "Starting bench serve (production-ready)";
export PYTHONUNBUFFERED=1;
bench serve --port 8000 2>&1 | awk '!/127\.0\.0\.1.*400/ {print}' || bench serve --port 8000;
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
environment:
SITE_NAME: ${SITE_NAME}
FRAPPE_SITE_NAME_HEADER: ""
MAIN_DOMAIN: ${MAIN_DOMAIN}
depends_on:
configurator:
condition: service_completed_successfully
required: true
create-site:
condition: service_completed_successfully
required: true
healthcheck:
test:
- CMD
- wait-for-it
- '0.0.0.0:8000'
interval: 2s
timeout: 10s
retries: 30
frontend:
<<: *custom_image
entrypoint: ["bash", "-c"]
command:
- >
echo "Starting Nginx with port_in_redirect fix...";
nginx-entrypoint.sh &
NGINX_PID=$!;
sleep 3;
if [ -f /etc/nginx/conf.d/frappe.conf ]; then
if ! grep -q "port_in_redirect off" /etc/nginx/conf.d/frappe.conf; then
echo "Applying port_in_redirect fix to prevent :8080 in URLs...";
sed -i 's/listen 8080;/listen 8080;\n port_in_redirect off;\n absolute_redirect off;/' /etc/nginx/conf.d/frappe.conf;
echo "Nginx config updated - reloading...";
sleep 1;
nginx -s reload 2>/dev/null || echo "Nginx will use updated config on next reload";
else
echo "Nginx config already has port_in_redirect settings";
fi
else
echo "Warning: frappe.conf not found yet, will check again";
sleep 2;
if [ -f /etc/nginx/conf.d/frappe.conf ]; then
if ! grep -q "port_in_redirect off" /etc/nginx/conf.d/frappe.conf; then
sed -i 's/listen 8080;/listen 8080;\n port_in_redirect off;\n absolute_redirect off;/' /etc/nginx/conf.d/frappe.conf;
nginx -s reload 2>/dev/null || true;
fi
fi
fi;
wait $NGINX_PID
depends_on:
backend:
condition: service_started
required: true
websocket:
condition: service_started
required: true
environment:
BACKEND: backend:8000
FRAPPE_SITE_NAME_HEADER: ""
SOCKETIO: websocket:9000
UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
UPSTREAM_REAL_IP_RECURSIVE: "off"
USE_X_FORWARDED_HOST: "1"
PROXY_FIX: "1"
X_FORWARDED_PROTO: "https"
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
healthcheck:
test:
- CMD-SHELL
- curl -fsS http://127.0.0.1:8080/login || exit 1
interval: 30s
timeout: 5s
retries: 3
queue-default:
<<: *custom_image
entrypoint: ["bash", "-c"]
command:
- >
cd /home/frappe/frappe-bench;
export start=`date +%s`;
while [ ! -d "apps/lending" ]; do
echo "Waiting for apps to be available...";
sleep 2;
if (( `date +%s`-start > 300 )); then
echo "Timeout waiting for apps";
break;
fi;
done;
if [ -d "apps/lending" ] && ! ./env/bin/pip show lending > /dev/null 2>&1; then
echo "Installing lending app in Python environment...";
./env/bin/pip install -e apps/lending || echo "Failed to install lending";
fi;
exec bench worker --queue default
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
healthcheck:
test:
- CMD
- wait-for-it
- 'redis-queue:6379'
interval: 2s
timeout: 10s
retries: 30
depends_on:
configurator:
condition: service_completed_successfully
required: true
queue-long:
<<: *custom_image
entrypoint: ["bash", "-c"]
command:
- >
cd /home/frappe/frappe-bench;
export start=`date +%s`;
while [ ! -d "apps/lending" ]; do
echo "Waiting for apps to be available...";
sleep 2;
if (( `date +%s`-start > 300 )); then
echo "Timeout waiting for apps";
break;
fi;
done;
if [ -d "apps/lending" ] && ! ./env/bin/pip show lending > /dev/null 2>&1; then
echo "Installing lending app in Python environment...";
./env/bin/pip install -e apps/lending || echo "Failed to install lending";
fi;
exec bench worker --queue long
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
healthcheck:
test:
- CMD
- wait-for-it
- 'redis-queue:6379'
interval: 2s
timeout: 10s
retries: 30
depends_on:
configurator:
condition: service_completed_successfully
required: true
queue-short:
<<: *custom_image
entrypoint: ["bash", "-c"]
command:
- >
cd /home/frappe/frappe-bench;
export start=`date +%s`;
while [ ! -d "apps/lending" ]; do
echo "Waiting for apps to be available...";
sleep 2;
if (( `date +%s`-start > 300 )); then
echo "Timeout waiting for apps";
break;
fi;
done;
if [ -d "apps/lending" ] && ! ./env/bin/pip show lending > /dev/null 2>&1; then
echo "Installing lending app in Python environment...";
./env/bin/pip install -e apps/lending || echo "Failed to install lending";
fi;
exec bench worker --queue short
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
healthcheck:
test:
- CMD
- wait-for-it
- 'redis-queue:6379'
interval: 2s
timeout: 10s
retries: 30
depends_on:
configurator:
condition: service_completed_successfully
required: true
scheduler:
<<: *custom_image
entrypoint: ["bash", "-c"]
command:
- >
cd /home/frappe/frappe-bench;
export start=`date +%s`;
while [ ! -d "apps/lending" ]; do
echo "Waiting for apps to be available...";
sleep 2;
if (( `date +%s`-start > 300 )); then
echo "Timeout waiting for apps";
break;
fi;
done;
if [ -d "apps/lending" ] && ! ./env/bin/pip show lending > /dev/null 2>&1; then
echo "Installing lending app in Python environment...";
./env/bin/pip install -e apps/lending || echo "Failed to install lending";
fi;
exec bench schedule
healthcheck:
test:
- CMD
- wait-for-it
- 'redis-queue:6379'
interval: 2s
timeout: 10s
retries: 30
depends_on:
configurator:
condition: service_completed_successfully
required: true
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
websocket:
<<: *custom_image
healthcheck:
test:
- CMD
- wait-for-it
- '0.0.0.0:9000'
interval: 2s
timeout: 10s
retries: 30
command:
- node
- /home/frappe/frappe-bench/apps/frappe/socketio.js
depends_on:
configurator:
condition: service_completed_successfully
required: true
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
configurator:
<<: *custom_image
deploy:
mode: replicated
replicas: ${CONFIGURE:-0}
restart_policy:
condition: none
entrypoint: ["bash", "-c"]
command:
- >
[[ $${REGENERATE_APPS_TXT} == "1" ]] && ls -1 apps > sites/apps.txt;
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && exit 0;
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;
environment:
DB_HOST: "${DB_HOST:-db}"
DB_PORT: "3306"
REDIS_CACHE: redis-cache:6379
REDIS_QUEUE: redis-queue:6379
SOCKETIO_PORT: "9000"
REGENERATE_APPS_TXT: "${REGENERATE_APPS_TXT:-0}"
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
create-site:
<<: *custom_image
deploy:
mode: replicated
replicas: ${CREATE_SITE:-0}
restart_policy:
condition: none
entrypoint: ["bash", "-c"]
command:
- >
wait-for-it -t 120 $$DB_HOST:$$DB_PORT;
wait-for-it -t 120 redis-cache:6379;
wait-for-it -t 120 redis-queue:6379;
export start=`date +%s`;
until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
do
echo "Waiting for sites/common_site_config.json to be created";
sleep 5;
if (( `date +%s`-start > 120 )); then
echo "could not find sites/common_site_config.json with required keys";
exit 1
fi
done;
echo "sites/common_site_config.json found";
cd /home/frappe/frappe-bench;
if [ -d "sites/${SITE_NAME}" ] && [ -f "sites/${SITE_NAME}/site_config.json" ]; then
echo "Site ${SITE_NAME} already exists, skipping creation";
bench use $${SITE_NAME} || echo "Warning: Could not set current site";
echo "$${SITE_NAME}" > sites/sites.txt || echo "Warning: Could not update sites.txt";
bench set-config -g default_site $${SITE_NAME} || echo "Warning: Could not set default site";
if [ -n "$${ADMIN_PASSWORD}" ]; then
echo "Updating admin password for existing site...";
bench --site $${SITE_NAME} set-admin-password $${ADMIN_PASSWORD} || echo "Warning: Could not update admin password (may need to be done manually)";
fi;
if [ -n "$${MAIN_DOMAIN}" ]; then
echo "Setting host_name and SSL settings to https://${MAIN_DOMAIN} (with HTTPS)...";
bench --site $${SITE_NAME} set-config host_name "https://$${MAIN_DOMAIN}" || echo "Warning: Could not set host_name";
bench --site $${SITE_NAME} set-config host_url "https://$${MAIN_DOMAIN}" || echo "Warning: Could not set host_url";
bench --site $${SITE_NAME} set-config use_ssl 1 || echo "Warning: Could not set use_ssl";
echo "Clearing cache to apply new domain settings...";
bench --site $${SITE_NAME} clear-cache || echo "Warning: Could not clear cache";
bench --site $${SITE_NAME} clear-website-cache || echo "Warning: Could not clear website cache";
fi;
echo "Verifying existing site is accessible...";
bench --site $${SITE_NAME} list-apps > /dev/null 2>&1 && echo "Existing site is accessible and working" || echo "Warning: Site accessibility check failed";
exit 0;
fi;
if [ ! -d "apps/lending" ]; then
echo "Cloning lending app...";
git clone https://github.com/frappe/lending.git apps/lending || echo "Failed to clone lending app";
fi;
if [ -d "apps/lending" ]; then
echo "Installing lending app in Python environment...";
./env/bin/pip install -e apps/lending || echo "Failed to install lending app";
fi;
echo "Regenerating apps.txt to include all apps...";
ls -1 apps > sites/apps.txt || (echo "frappe" > sites/apps.txt && echo "lending" >> sites/apps.txt);
echo "apps.txt contents:";
cat sites/apps.txt;
bench set-mariadb-host $${DB_HOST:-db};
bench new-site --mariadb-user-host-login-scope='%' --admin-password=$${ADMIN_PASSWORD} --db-root-username=root --db-root-password=$${DB_ROOT_PASSWORD} $${INSTALL_APP_ARGS} $${SITE_NAME};
if [ ! -d "sites/${SITE_NAME}" ]; then
echo "ERROR: Site ${SITE_NAME} was not created successfully";
exit 1;
fi;
echo "Site ${SITE_NAME} created successfully";
bench use $${SITE_NAME};
echo "Current site set to: $${SITE_NAME}";
if [ -d "apps/lending" ]; then
echo "Installing lending app on site...";
bench --site $${SITE_NAME} install-app lending || echo "Lending app may already be installed or failed to install";
fi;
echo "Building assets for all apps (this ensures lending JS is available)...";
bench build --apps lending || echo "Asset build completed";
echo "Clearing all caches...";
bench --site $${SITE_NAME} clear-cache || echo "Cache cleared";
bench --site $${SITE_NAME} clear-website-cache || echo "Website cache cleared";
echo "Creating sites.txt for site resolution...";
echo "$${SITE_NAME}" > sites/sites.txt || echo "Warning: Could not create sites.txt";
echo "Site registered in sites.txt:";
cat sites/sites.txt || echo "sites.txt not found";
echo "Verifying site directory and config exist...";
if [ -d "sites/${SITE_NAME}" ] && [ -f "sites/${SITE_NAME}/site_config.json" ]; then
echo "Site directory and config verified successfully";
else
echo "Warning: Site directory or config file missing";
ls -la sites/${SITE_NAME}/ 2>/dev/null || echo "Site directory listing failed";
fi;
echo "Setting default site in common_site_config.json...";
bench set-config -g default_site $${SITE_NAME} || echo "Warning: Could not set default site";
if [ -n "$${MAIN_DOMAIN}" ]; then
echo "Setting host_name and SSL settings to https://${MAIN_DOMAIN} (with HTTPS)...";
bench --site $${SITE_NAME} set-config host_name "https://$${MAIN_DOMAIN}" || echo "Warning: Could not set host_name";
bench --site $${SITE_NAME} set-config host_url "https://$${MAIN_DOMAIN}" || echo "Warning: Could not set host_url";
bench --site $${SITE_NAME} set-config use_ssl 1 || echo "Warning: Could not set use_ssl";
echo "Clearing cache to apply new domain settings...";
bench --site $${SITE_NAME} clear-cache || echo "Warning: Could not clear cache";
bench --site $${SITE_NAME} clear-website-cache || echo "Warning: Could not clear website cache";
fi;
echo "Verifying site is accessible...";
bench --site $${SITE_NAME} list-apps > /dev/null 2>&1 && echo "Site is accessible and working" || echo "Warning: Site accessibility check failed";
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
environment:
SITE_NAME: ${SITE_NAME}
MAIN_DOMAIN: ${main_domain}
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
DB_HOST: ${DB_HOST:-db}
DB_PORT: "${DB_PORT:-3306}"
DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
INSTALL_APP_ARGS: ${INSTALL_APP_ARGS}
migration:
<<: *custom_image
deploy:
mode: replicated
replicas: ${MIGRATE:-0}
restart_policy:
condition: none
entrypoint: ["bash", "-c"]
command:
- >
curl -f http://${SITE_NAME}:8080/api/method/ping || echo "Site busy" && exit 0;
bench --site all set-config -p maintenance_mode 1;
bench --site all set-config -p pause_scheduler 1;
bench --site all migrate;
bench --site all set-config -p maintenance_mode 0;
bench --site all set-config -p pause_scheduler 0;
volumes:
- sites:/home/frappe/frappe-bench/sites
- apps:/home/frappe/frappe-bench/apps
db:
image: mariadb:10.6
deploy:
mode: replicated
replicas: ${ENABLE_DB:-0}
restart_policy:
condition: always
healthcheck:
test: mysqladmin ping -h localhost --password=${DB_ROOT_PASSWORD}
interval: 1s
retries: 20
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --skip-character-set-client-handshake
- --skip-innodb-read-only-compressed
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
volumes:
- db-data:/var/lib/mysql
redis-cache:
deploy:
restart_policy:
condition: always
image: redis:6.2-alpine
volumes:
- redis-cache-data:/data
healthcheck:
test:
- CMD
- redis-cli
- ping
interval: 5s
timeout: 5s
retries: 3
redis-queue:
deploy:
restart_policy:
condition: always
image: redis:6.2-alpine
volumes:
- redis-queue-data:/data
healthcheck:
test:
- CMD
- redis-cli
- ping
interval: 5s
timeout: 5s
retries: 3
redis-socketio:
deploy:
restart_policy:
condition: always
image: redis:6.2-alpine
volumes:
- redis-socketio-data:/data
healthcheck:
test:
- CMD
- redis-cli
- ping
interval: 5s
timeout: 5s
retries: 3
volumes:
db-data:
redis-cache-data:
redis-queue-data:
redis-socketio-data:
sites:
driver_opts:
type: "${SITE_VOLUME_TYPE}"
o: "${SITE_VOLUME_OPTS}"
device: "${SITE_VOLUME_DEV}"
apps:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,29 @@
[variables]
main_domain = "${domain}"
site_name = "frappe.lending"
db_root_password = "${password:32}"
admin_password = "${password:32}"
[config]
env = [
"SITE_NAME=${site_name}",
"ADMIN_PASSWORD=${admin_password}",
"DB_ROOT_PASSWORD=${db_root_password}",
"MIGRATE=1",
"ENABLE_DB=1",
"DB_HOST=db",
"CREATE_SITE=1",
"CONFIGURE=1",
"REGENERATE_APPS_TXT=1",
"INSTALL_APP_ARGS=--install-app erpnext --install-app lending",
"IMAGE_NAME=frappe/erpnext",
"VERSION=latest",
"FRAPPE_SITE_NAME_HEADER=",
"MAIN_DOMAIN=${main_domain}",
]
mounts = []
[[config.domains]]
serviceName = "frontend"
port = 8_080
host = "${main_domain}"

View File

@@ -0,0 +1,27 @@
services:
geoserver:
image: kartoza/geoserver:2.24.1
depends_on:
- db
environment:
- GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER}
- GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD}
- INITIAL_MEMORY=${INITIAL_MEMORY}
- MAXIMUM_MEMORY=${MAXIMUM_MEMORY}
volumes:
- geoserver-data:/opt/geoserver/data_dir
restart: unless-stopped
db:
image: postgis/postgis:17-3.4
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgis-data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
geoserver-data:
postgis-data:

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,18 @@
[info]
name = "GeoServer & PostGIS"
description = "An open-source server for sharing geospatial data, paired with a PostGIS database. Template created and maintained by OpenGeoCity Tanzania (info@ogctz.org). For further assistance contact +255759968919 or visit https://opengeocity.org or github: https://github.com/ShabaniMagawila or linkedin: https://www.linkedin.com/in/shabani-magawila/"
version = "2.24.1"
[variables]
GEOSERVER_ADMIN_USER = "admin"
GEOSERVER_ADMIN_PASSWORD = "geoserver_secure"
INITIAL_MEMORY = "2G"
MAXIMUM_MEMORY = "4G"
POSTGRES_USER = "postgres"
POSTGRES_PASSWORD = "postgres_secure"
POSTGRES_DB = "gis"
[config]
[[config.domains]]
serviceName = "geoserver"
port = 8080

View File

@@ -1,55 +1,52 @@
version: "3.8"
x-environment: &default-environment
DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres
VALKEY_URL: redis://valkey:6379
SECRET_KEY: ${SECRET_KEY}
PORT: ${GLITCHTIP_PORT}
EMAIL_URL: consolemail://
GLITCHTIP_DOMAIN: http://${GLITCHTIP_HOST}
DEFAULT_FROM_EMAIL: email@glitchtip.com
CELERY_WORKER_AUTOSCALE: "1,3"
CELERY_WORKER_MAX_TASKS_PER_CHILD: "10000"
GLITCHTIP_DOMAIN: ${GLITCHTIP_DOMAIN}
DEFAULT_FROM_EMAIL: ${DEFAULT_FROM_EMAIL}
x-depends_on: &default-depends_on
- postgres
- redis
- valkey
services:
postgres:
image: postgres:16
image: postgres:18
environment:
POSTGRES_HOST_AUTH_METHOD: "trust"
restart: unless-stopped
volumes:
- pg-data:/var/lib/postgresql/data
redis:
image: redis
valkey:
image: valkey/valkey:9
restart: unless-stopped
web:
image: glitchtip/glitchtip:v4.0
image: glitchtip/glitchtip:6.1.0
depends_on: *default-depends_on
ports:
expose:
- ${GLITCHTIP_PORT}
environment: *default-environment
restart: unless-stopped
volumes:
- uploads:/code/uploads
worker:
image: glitchtip/glitchtip:v4.0
command: ./bin/run-celery-with-beat.sh
image: glitchtip/glitchtip:6.1.0
command: ./bin/run-worker.sh
depends_on: *default-depends_on
environment: *default-environment
restart: unless-stopped
volumes:
- uploads:/code/uploads
migrate:
image: glitchtip/glitchtip:v4.0
image: glitchtip/glitchtip:6.1.0
depends_on: *default-depends_on
command: "./manage.py migrate"
command: ./bin/run-migrate.sh
environment: *default-environment
volumes:
pg-data:
uploads:

View File

@@ -4,7 +4,8 @@ secret_key = "${base64:32}"
[config]
env = [
"GLITCHTIP_HOST=${main_domain}",
"DEFAULT_FROM_EMAIL=${email}",
"GLITCHTIP_DOMAIN=https://${main_domain}",
"GLITCHTIP_PORT=8000",
"SECRET_KEY=${secret_key}",
]
@@ -12,5 +13,5 @@ mounts = []
[[config.domains]]
serviceName = "web"
port = 8_000
port = 8000
host = "${main_domain}"

View File

@@ -0,0 +1,24 @@
version: "3.8"
services:
go2rtc:
image: alexxit/go2rtc:1.9.14
restart: unless-stopped
# To use a local webcam, add the device to the service:
# devices:
# - /dev/video0:/dev/video0 # Adjust path if your device is at /dev/video1, etc.
expose:
- 1984 # Web UI
- 8554 # RTSP
- 8555 # WebRTC
environment:
- TZ=${TZ}
volumes:
- go2rtc-config:/config
volumes:
go2rtc-config: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,13 @@
[variables]
main_domain = "${domain}"
[config]
[[config.domains]]
serviceName = "go2rtc"
port = 1984
host = "${main_domain}"
env = [
"TZ=${TZ}"
]

View File

@@ -0,0 +1,11 @@
services:
gotify:
image: gotify/server:2.9.1
restart: unless-stopped
volumes:
- gotify_data:/app/data
ports:
- "80"
volumes:
gotify_data:

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<rect width="128" height="128" rx="28" fill="#101828"/>
<circle cx="64" cy="64" r="34" fill="#38bdf8" opacity="0.92"/>
<text x="64" y="74" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" font-weight="700" fill="#ffffff">G</text>
</svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@@ -0,0 +1,11 @@
[variables]
main_domain = "${domain}"
[config]
env = {}
mounts = []
[[config.domains]]
serviceName = "gotify"
port = 80
host = "${main_domain}"

View File

@@ -0,0 +1,37 @@
version: "3.8"
services:
hedgedoc:
image: quay.io/hedgedoc/hedgedoc:1.10.8
restart: unless-stopped
depends_on:
database:
condition: service_healthy
environment:
- CMD_DB_URL=${CMD_DB_URL}
- CMD_DOMAIN=${CMD_DOMAIN}
- CMD_PROTOCOL_USESSL=${CMD_PROTOCOL_USESSL}
- CMD_URL_ADDPORT=${CMD_URL_ADDPORT}
volumes:
- hedgedoc_uploads:/hedgedoc/public/uploads
expose:
- "3000"
database:
image: postgres:17.7-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=hedgedoc
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=hedgedoc
volumes:
- hedgedoc_database:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hedgedoc -d hedgedoc"]
interval: 10s
timeout: 5s
retries: 5
volumes:
hedgedoc_uploads:
hedgedoc_database:

View File

@@ -0,0 +1,32 @@
<!--
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
SPDX-License-Identifier: LicenseRef-HedgeDoc-Icon-Usage-Guidelines
-->
<svg clip-rule="evenodd" fill-rule="evenodd" height="512" stroke-linejoin="round" stroke-miterlimit="2" width="512"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<linearGradient id="a" gradientTransform="matrix(200 -420 420 200 660 1340)" gradientUnits="userSpaceOnUse" x1="0"
x2="1" y1="0" y2="0">
<stop offset="0" stop-color="#fcca8c"/>
<stop offset="1" stop-color="#dca055"/>
</linearGradient>
<g fill-rule="nonzero">
<path d="M486.075 281.925 512 255.998l-25.925-25.923 19.503-31.04-31.04-19.505 12.11-34.605-34.604-12.106 4.103-36.431-36.428-4.104-4.107-36.433-36.429 4.104-12.11-34.604-34.599 12.108-19.51-31.041-31.043 19.505L256 0l-25.922 25.925L199.035 6.42l-19.503 31.04-34.604-12.11-12.107 34.603-36.432-4.105-4.104 36.429-36.43 4.104 4.106 36.43-34.608 12.109 12.108 34.602-31.04 19.504 19.506 31.046L0 255.998l25.925 25.927L6.42 312.968l31.04 19.503-12.108 34.603 34.607 12.11-4.104 36.425 36.43 4.107 4.103 36.429 36.432-4.103 12.107 34.6 34.602-12.104 19.505 31.041 31.04-19.506 25.924 25.683 25.925-25.677 31.04 19.503 19.503-31.044 34.607 12.11 12.106-34.603 36.432 4.103 4.103-36.432 36.432-4.103-4.106-36.43 34.606-12.109-12.11-34.606 31.041-19.503z"
fill="#b51f08"/>
<path d="M433.585 296.98c0-50.105-40.618-90.725-90.724-90.725-24.888 0-47.432 10.03-63.822 26.26l-.011-.011-23.116 23.117-18.9-18.901c-16.629-18.971-41.022-30.965-68.228-30.965-50.107 0-90.725 40.62-90.725 90.725 0 26.183 11.103 49.758 28.843 66.315L256 511.815l145.804-145.898c18.218-17.147 31.781-41.342 31.781-68.937"
fill="#fcca8c"/>
<path d="m885.579 884.73-54.862-54.862c-48.267-55.067-119.071-89.879-198.042-89.879-145.442 0-263.342 117.904-263.342 263.341 0 76 32.23 144.43 83.721 192.49l432.779 432.55"
fill="url(#a)" transform="translate(-49.181 -49.18) scale(.34451)" style="fill:url(#a)"/>
</g>
<path d="m256 511.815-.088-256.194" fill="none" style="stroke-width:.344513"/>
<g fill-rule="nonzero">
<path d="M281.9 486.052c-6.642-6.666-15.82-10.787-25.95-10.787-10.135 0-19.31 4.12-25.952 10.787.106 14.242 11.681 25.756 25.95 25.756 14.268 0 25.845-11.517 25.952-25.756M225.64 329.17c0 10.955-8.878 19.833-19.835 19.833-10.95 0-19.83-8.878-19.83-19.833 0-10.956 8.88-19.834 19.83-19.834 10.957 0 19.834 8.878 19.834 19.834"
fill="#010007"/>
<path d="M218.837 326.198a5.49 5.49 0 0 1-5.495 5.491 5.492 5.492 0 0 1-5.498-5.491 5.5 5.5 0 0 1 5.498-5.499 5.499 5.499 0 0 1 5.495 5.499"
fill="#fffffa"/>
<path d="M326.218 329.17c0 10.956-8.878 19.834-19.834 19.834-10.952 0-19.833-8.878-19.833-19.833 0-10.956 8.881-19.834 19.833-19.834 10.956 0 19.834 8.878 19.834 19.834"
fill="#010007"/>
<path d="M319.414 326.198a5.492 5.492 0 0 1-5.495 5.491 5.492 5.492 0 0 1-5.499-5.491 5.5 5.5 0 0 1 5.499-5.499 5.5 5.5 0 0 1 5.495 5.499"
fill="#fffffa"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,16 @@
[variables]
main_domain = "${domain}"
database_password = "${password:32}"
[config]
[[config.domains]]
serviceName = "hedgedoc"
port = 3000
host = "${main_domain}"
[config.env]
POSTGRES_PASSWORD = "${database_password}"
CMD_DB_URL = "postgres://hedgedoc:${database_password}@database:5432/hedgedoc"
CMD_DOMAIN = "${main_domain}"
CMD_PROTOCOL_USESSL = "true"
CMD_URL_ADDPORT = "false"

View File

@@ -0,0 +1,27 @@
version: "3.8"
services:
hermes:
image: nousresearch/hermes-agent:v2026.6.19
restart: unless-stopped
command: gateway run
ports:
- 9119
- 8642
environment:
- HERMES_DASHBOARD=${HERMES_DASHBOARD}
- HERMES_DASHBOARD_BASIC_AUTH_USERNAME=${HERMES_DASHBOARD_BASIC_AUTH_USERNAME}
- HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=${HERMES_DASHBOARD_BASIC_AUTH_PASSWORD}
- HERMES_DASHBOARD_BASIC_AUTH_SECRET=${HERMES_DASHBOARD_BASIC_AUTH_SECRET}
- API_SERVER_ENABLED=${API_SERVER_ENABLED}
- API_SERVER_HOST=${API_SERVER_HOST}
- API_SERVER_KEY=${API_SERVER_KEY}
volumes:
- hermes_data:/opt/data
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
volumes:
hermes_data:

BIN
blueprints/hermes/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -0,0 +1,33 @@
[variables]
dashboard_domain = "${domain}"
gateway_domain = "${domain}"
# base64 (not just alphanumeric); 96 bytes -> 128 chars
dashboard_password = "${base64:96}"
dashboard_secret = "${base64:32}"
api_key = "${password:32}"
[config]
mounts = []
# Web dashboard (HERMES_DASHBOARD=1). Exposed behind Traefik, so Hermes'
# auth-gated mode kicks in — protect it with the bundled basic-auth provider.
[[config.domains]]
serviceName = "hermes"
port = 9119
host = "${dashboard_domain}"
# OpenAI-compatible gateway API. Disabled and loopback-bound by default,
# so it must be enabled, bound to 0.0.0.0, and given a bearer token.
[[config.domains]]
serviceName = "hermes"
port = 8642
host = "${gateway_domain}"
[config.env]
HERMES_DASHBOARD = "1"
HERMES_DASHBOARD_BASIC_AUTH_USERNAME = "admin"
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD = "${dashboard_password}"
HERMES_DASHBOARD_BASIC_AUTH_SECRET = "${dashboard_secret}"
API_SERVER_ENABLED = "true"
API_SERVER_HOST = "0.0.0.0"
API_SERVER_KEY = "${api_key}"

View File

@@ -1,6 +1,6 @@
services:
all-in-one:
image: daveearley/hi.events-all-in-one:v0.8.0-beta.1
image: daveearley/hi.events-all-in-one:v1.9.0-beta
restart: always
environment:
- VITE_FRONTEND_URL=https://${DOMAIN}
@@ -20,6 +20,8 @@ services:
- MAIL_MAILER
- MAIL_HOST
- MAIL_PORT
- MAIL_USERNAME
- MAIL_PASSWORD
- MAIL_FROM_ADDRESS
- MAIL_FROM_NAME
depends_on:

View File

@@ -16,6 +16,8 @@ env = [
"MAIL_MAILER=",
"MAIL_HOST=",
"MAIL_PORT=",
"MAIL_USERNAME=",
"MAIL_PASSWORD=",
"MAIL_FROM_ADDRESS=",
"MAIL_FROM_NAME=",
]

View File

@@ -0,0 +1,9 @@
version: "3.8"
services:
homepage:
image: ghcr.io/gethomepage/homepage:v1.13.1
restart: unless-stopped
expose:
- 3000
volumes:
- ../files/homepage-config:/app/config

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,13 @@
[variables]
main_domain = "${domain}"
[config]
[[config.domains]]
serviceName = "homepage"
port = 3000
host = "${main_domain}"
[config.env]
HOMEPAGE_ALLOWED_HOSTS = "${main_domain}"
PUID = "1000"
PGID = "1000"

View File

@@ -3,6 +3,8 @@ services:
imgproxy:
image: darthsim/imgproxy:v3.30.1
restart: unless-stopped
expose:
- 8080
environment:
IMGPROXY_KEY: ${IMGPROXY_KEY}
IMGPROXY_SALT: ${IMGPROXY_SALT}

View File

@@ -28,7 +28,7 @@ services:
REDIS_DBINDEX: ${REDIS_DBINDEX}
# Server Configuration
TZ: ${TZ}
restart: always
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:2283/server-info/ping"]
interval: 30s
@@ -44,7 +44,7 @@ services:
REDIS_HOSTNAME: ${REDIS_HOSTNAME}
REDIS_PORT: ${REDIS_PORT}
REDIS_DBINDEX: ${REDIS_DBINDEX}
restart: always
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3003/ping"]
interval: 30s
@@ -61,7 +61,7 @@ services:
interval: 10s
timeout: 5s
retries: 5
restart: always
restart: unless-stopped
immich-database:
image: tensorchord/pgvecto-rs:pg14-v0.3.0
@@ -94,10 +94,10 @@ services:
'-c',
'wal_compression=on',
]
restart: always
restart: unless-stopped
volumes:
immich-model-cache:
immich-postgres:
immich-library:
immich-redis-data:
immich-redis-data:

View File

@@ -0,0 +1,22 @@
version: "3.8"
services:
inkvoice:
image: ghcr.io/pigontech/inkvoice:0.1.0
restart: unless-stopped
environment:
- ADMIN_USER=${ADMIN_USER}
- ADMIN_PASS=${ADMIN_PASS}
- JWT_SECRET=${JWT_SECRET}
- DATABASE_PATH=/app/data/invoice.db
- PORT=3000
- HOST=0.0.0.0
# Dokploy's auto-generated domain is HTTP (sslip.io); keep false so login
# works out of the box. Set true once you attach an HTTPS custom domain.
- COOKIE_SECURE=false
volumes:
- inkvoice-data:/app/data
expose:
- 3000
volumes:
inkvoice-data:

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="512" height="512">
<rect x="9" y="33" width="10" height="34" rx="5" fill="#22252b"></rect>
<rect x="27" y="21" width="10" height="58" rx="5" fill="#22252b"></rect>
<rect x="45" y="8" width="10" height="84" rx="5" fill="#f3522e"></rect>
<rect x="63" y="26" width="10" height="48" rx="5" fill="#22252b"></rect>
<rect x="81" y="37" width="10" height="26" rx="5" fill="#22252b"></rect>
</svg>

After

Width:  |  Height:  |  Size: 467 B

View File

@@ -0,0 +1,17 @@
[variables]
main_domain = "${domain}"
admin_user = "admin"
admin_pass = "${password:16}"
jwt_secret = "${password:48}"
[config]
env = [
"ADMIN_USER=${admin_user}",
"ADMIN_PASS=${admin_pass}",
"JWT_SECRET=${jwt_secret}",
]
[[config.domains]]
serviceName = "inkvoice"
port = 3000
host = "${main_domain}"

View File

@@ -0,0 +1,13 @@
services:
jellyseerr:
image: fallenbagel/jellyseerr:2.7.3
restart: unless-stopped
volumes:
- jellyseerr_config:/app/config
environment:
LOG_LEVEL: info
ports:
- "5055"
volumes:
jellyseerr_config:

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<rect width="128" height="128" rx="28" fill="#101828"/>
<circle cx="64" cy="64" r="34" fill="#38bdf8" opacity="0.92"/>
<text x="64" y="74" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" font-weight="700" fill="#ffffff">J</text>
</svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@@ -0,0 +1,11 @@
[variables]
main_domain = "${domain}"
[config]
env = {}
mounts = []
[[config.domains]]
serviceName = "jellyseerr"
port = 5055
host = "${main_domain}"

View File

@@ -0,0 +1,44 @@
version: "3.8"
services:
joomla:
image: joomla:6.1.0-apache
restart: unless-stopped
depends_on:
joomla-db:
condition: service_healthy
expose:
- "80"
environment:
JOOMLA_DB_HOST: joomla-db
JOOMLA_DB_USER: ${JOOMLA_DB_USER}
JOOMLA_DB_PASSWORD: ${JOOMLA_DB_PASSWORD}
JOOMLA_DB_NAME: ${JOOMLA_DB_NAME}
JOOMLA_SITE_NAME: ${JOOMLA_SITE_NAME}
JOOMLA_ADMIN_USER: ${JOOMLA_ADMIN_USER}
JOOMLA_ADMIN_USERNAME: ${JOOMLA_ADMIN_USERNAME}
JOOMLA_ADMIN_PASSWORD: ${JOOMLA_ADMIN_PASSWORD}
JOOMLA_ADMIN_EMAIL: ${JOOMLA_ADMIN_EMAIL}
volumes:
- joomla-data:/var/www/html
joomla-db:
image: mariadb:11.4
restart: unless-stopped
environment:
MARIADB_DATABASE: ${JOOMLA_DB_NAME}
MARIADB_USER: ${JOOMLA_DB_USER}
MARIADB_PASSWORD: ${JOOMLA_DB_PASSWORD}
MARIADB_RANDOM_ROOT_PASSWORD: "1"
volumes:
- joomla-db:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
volumes:
joomla-data:
joomla-db:

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="Joomla">
<rect width="128" height="128" rx="24" fill="#1a3867"/>
<path fill="#fff" d="M61 29a10 10 0 0 1 16-8l10 10-9 9-9-9a3 3 0 0 0-5 2v16H50V33a17 17 0 0 1 11-4Zm38 32a10 10 0 0 1 8 16L97 87l-9-9 9-9a3 3 0 0 0-2-5H79V50h16a17 17 0 0 1 4 11ZM67 99a10 10 0 0 1-16 8L41 97l9-9 9 9a3 3 0 0 0 5-2V79h14v16a17 17 0 0 1-11 4ZM29 67a10 10 0 0 1-8-16l10-10 9 9-9 9a3 3 0 0 0 2 5h16v14H33a17 17 0 0 1-4-11Z"/>
<rect x="51" y="51" width="26" height="26" rx="6" fill="#f9a03f"/>
</svg>

After

Width:  |  Height:  |  Size: 568 B

View File

@@ -0,0 +1,51 @@
[variables]
main_domain = "${domain}"
site_name = "Joomla"
admin_name = "Joomla Administrator"
admin_username = "${username}"
admin_password = "${password:24}"
admin_email = "${email}"
db_user = "joomla"
db_password = "${password:32}"
db_name = "joomla"
[[config.domains]]
serviceName = "joomla"
port = 80
host = "${main_domain}"
path = "/"
[[config.mounts]]
filePath = "README.md"
content = """# Joomla
This template deploys Joomla CMS with MariaDB using the official Joomla Apache image.
## Access
- URL: `http://${main_domain}`
- Administrator username: the configured `admin_username` value
- Administrator password: the generated `admin_password` value
- Administrator email: the configured `admin_email` value
The template uses Joomla's auto-deployment environment variables so the site and administrator account are initialized on first start.
## Storage
The template creates persistent volumes for:
- Joomla application files at `/var/www/html`
- MariaDB data at `/var/lib/mysql`
Back up both volumes together before upgrades or migrations.
"""
[config.env]
JOOMLA_SITE_NAME = "${site_name}"
JOOMLA_ADMIN_USER = "${admin_name}"
JOOMLA_ADMIN_USERNAME = "${admin_username}"
JOOMLA_ADMIN_PASSWORD = "${admin_password}"
JOOMLA_ADMIN_EMAIL = "${admin_email}"
JOOMLA_DB_USER = "${db_user}"
JOOMLA_DB_PASSWORD = "${db_password}"
JOOMLA_DB_NAME = "${db_name}"

View File

@@ -0,0 +1,30 @@
services:
joplin-db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_DB: ${POSTGRES_DATABASE}
volumes:
- joplin_db_data:/var/lib/postgresql/data
joplin-server:
image: joplin/server:3.7.1
restart: unless-stopped
depends_on:
- joplin-db
environment:
APP_BASE_URL: ${APP_BASE_URL}
APP_PORT: ${APP_PORT}
DB_CLIENT: pg
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DATABASE: ${POSTGRES_DATABASE}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PORT: 5432
POSTGRES_HOST: joplin-db
ports:
- "22300"
volumes:
joplin_db_data:

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<rect width="128" height="128" rx="28" fill="#101828"/>
<circle cx="64" cy="64" r="34" fill="#38bdf8" opacity="0.92"/>
<text x="64" y="74" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" font-weight="700" fill="#ffffff">J</text>
</svg>

After

Width:  |  Height:  |  Size: 325 B

View File

@@ -0,0 +1,18 @@
[variables]
main_domain = "${domain}"
postgres_password = "${password:32}"
[config]
mounts = []
[[config.domains]]
serviceName = "joplin-server"
port = 22300
host = "${main_domain}"
[config.env]
APP_BASE_URL = "http://${main_domain}"
APP_PORT = "22300"
POSTGRES_PASSWORD = "${postgres_password}"
POSTGRES_USER = "joplin"
POSTGRES_DATABASE = "joplin"

View File

@@ -1,31 +1,44 @@
version: "3.8"
services:
langflow:
image: langflowai/langflow:v1.1.1
image: langflowai/langflow:latest
user: root
restart: always
pull_policy: always
ports:
- 7860
depends_on:
- postgres-langflow
environment:
- LANGFLOW_DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres-langflow:5432/langflow
# This variable defines where the logs, file storage, monitor data and secret keys are stored.
- LANGFLOW_CONFIG_DIR=/app/config
- LANGFLOW_SUPERUSER=email@domain.com
- LANGFLOW_SUPERUSER_PASSWORD=changepassword
- LANGFLOW_SECRET_KEY=PP_G4Gwm1lOkyG8r8N0LrdlpWXZ7Tyq5CVyfBquuj6g=
- DO_NOT_TRACK=True
- LANGFLOW_AUTO_SAVING=True
- LANGFLOW_AUTO_LOGIN=False
- LANGFLOW_NEW_USER_IS_ACTIVE=False
- LANGFLOW_ENABLE_SUPERUSER_CLI=False
volumes:
- langflow-data:/app/langflow
- app-data:/app/langflow
- app-config:/app/config
postgres-langflow:
image: postgres:16
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d langflow"]
interval: 3s
timeout: 3s
retries: 10
environment:
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: langflow
ports:
- 5432
volumes:
- langflow-postgres:/var/lib/postgresql/data
- postgres-data:/var/lib/postgresql/data
volumes:
langflow-postgres:
langflow-data:
postgres-data:
app-data:
app-config:

View File

@@ -0,0 +1,17 @@
version: "3.8"
services:
libredb-studio:
image: ghcr.io/libredb/libredb-studio:0.9.27
restart: unless-stopped
environment:
- ADMIN_EMAIL=admin@libredb.org
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- USER_EMAIL=user@libredb.org
- USER_PASSWORD=${USER_PASSWORD}
- JWT_SECRET=${JWT_SECRET}
- STORAGE_PROVIDER=sqlite
- STORAGE_SQLITE_PATH=/app/data/libredb-storage.db
volumes:
- libredb-data:/app/data
volumes:
libredb-data:

View File

@@ -0,0 +1,32 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="logo-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#4F46E5" />
<stop offset="100%" stop-color="#9333EA" />
</linearGradient>
<linearGradient id="code-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#10B981" />
<stop offset="100%" stop-color="#3B82F6" />
</linearGradient>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
</defs>
<!-- Background Shape -->
<path d="M100 20L169.282 60V140L100 180L30.718 140V60L100 20Z" fill="url(#logo-gradient)" fill-opacity="0.05" stroke="url(#logo-gradient)" stroke-width="1.5"/>
<!-- Database Layers (De-emphasized) -->
<g opacity="0.3">
<rect x="70" y="80" width="60" height="10" rx="2" fill="url(#logo-gradient)" />
<rect x="70" y="95" width="60" height="10" rx="2" fill="url(#logo-gradient)" />
<rect x="70" y="110" width="60" height="10" rx="2" fill="url(#logo-gradient)" />
</g>
<!-- Coding Brackets (Emphasized) -->
<g filter="url(#glow)">
<path d="M55 70L35 100L55 130" stroke="url(#code-gradient)" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" />
<path d="M145 70L165 100L145 130" stroke="url(#code-gradient)" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,18 @@
[variables]
admin_password = "${password:32}"
user_password = "${password:32}"
jwt_secret = "${password:64}"
[config]
[[config.domains]]
serviceName = "libredb-studio"
port = 3000
[[config.env]]
ADMIN_PASSWORD = "${admin_password}"
[[config.env]]
USER_PASSWORD = "${user_password}"
[[config.env]]
JWT_SECRET = "${jwt_secret}"

View File

@@ -0,0 +1,20 @@
version: "3.8"
services:
librespeed:
image: lscr.io/linuxserver/librespeed:latest
restart: unless-stopped
expose:
- 80
volumes:
- librespeed-config:/config
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ}
- PASSWORD=${PASSWORD}
- CUSTOM_RESULTS=${CUSTOM_RESULTS}
- DB_TYPE=sqlite
volumes:
librespeed-config:

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 512 512"><circle cx="256" cy="256" r="256" style="fill:#d1d3d4"/><path d="M468.6 246.7C463.3 129.7 364.1 39 247.1 44 129.8 49 39 148.2 44.4 265.5c5.3 117 104.5 207.7 221.5 202.7 117-5.3 207.7-104.5 202.7-221.5m-32.2-32.8-28.2 6.3c-2.8-13.2-7.5-26-14.1-38.6l25.7-13.1c7.5 14.4 13.2 29.8 16.6 45.4m-344.8-45c.2-.1.2-.3.3-.4l25.7 13.1c-6.3 12.2-10.9 25-14.1 38.2h-.1c-.1.3-.1.5-.2.8L75 214.3c3.5-15.7 9.1-31 16.6-45.4m-20.7 85c0-2.1 0-4.3.1-6.4.2-5.9.7-11.9 1.5-17.8l28.5 3.8v.1c-.9 6.7-1.4 13.5-1.4 20.3s.5 13.6 1.4 20.3v.1L72.5 278c-1.1-8-1.7-16-1.6-24.1m21.3 85.5c-.1-.1-.1-.2-.2-.3l-.4.2C84.1 325 78.5 309.6 75 294l28.2-6.3c0 .2.1.4.1.6l.8-.2c2.9 13.2 7.5 26 13.8 38.2zM141 148.9c-6.3 6.9-11.9 14.1-16.6 21.6L100 155.2c.1-.1.2-.3.3-.4l-.3-.2c5.6-9.1 12.2-17.6 19.7-25.7 3.5-3.8 7.2-7.9 11.3-11.3l.3.3 5.4 5.9 13.7 15 .3.4c-3.4 3.1-6.6 6.3-9.7 9.7m19.6-18.9-17.4-22.8c13.1-10 27.2-18.1 41.9-24.1h.1l10.9 26.6c-12.5 5-24.1 11.9-35.3 20.3l-.1-.1zm41.1 259.4h-21.6v-21.6h21.6zm7.2-284.6-8.7-27.3c15.3-4.7 31.3-7.5 47.6-8.4v.3h.2l.6 17.2-1.5 11.8c-12.9.6-25.4 3.1-37.9 6.9l-.2-.5zm36.3 284.6h-21.9v-21.6h21.9zm10.9-95.4c-15 0-27.2-17.5-27.2-39.1l2.6-16 24.7-168.6 24.6 168.6 2.5 16c0 21.6-12.2 39.1-27.2 39.1m32.3 95.4h-21.6v-21.6h21.6zm-23.5-291L263 86.3l1-16.6v-.5c16 .6 32.3 3.4 47.6 8.4l-.1.2h.1l-8.8 27.5c-12.2-3.8-25-6.3-37.9-6.9m67 291H310v-21.6h21.9zm-16.3-279.7 11.3-26.6c14.4 6 28.5 14.1 41.6 24.1L351 130c-11-8.4-22.9-15.3-35.4-20.3m45.6 29.5 19.4-21.3c12.2 11.2 22.6 23.4 31 36.9l-24.1 15.3c-7.1-11.2-15.9-21.9-26.3-30.9m58.6 200.2-25.7-13.5c6.6-12.2 11.3-25.1 14.1-38.2l28.2 6.3c-3.5 15.7-9.1 31-16.6 45.4m19.4-61.3-28.5-3.8c1.9-13.5 1.9-27.2 0-40.7l28.5-3.7c2.2 16 2.2 32.2 0 48.2"/><path d="m439.2 278-28.5-3.8c1.9-13.5 1.9-27.2 0-40.7l28.5-3.8c1.8 16.1 1.8 32.4 0 48.3" style="fill:#ed1c24"/><path d="M419.8 168.5c7.5 14.4 13.1 29.7 16.6 45.4l-28.2 6.3c-2.8-13.1-7.5-26-13.8-38.2z" style="fill:#ef4136"/><path d="m419.8 339.4-25.7-13.1c6.3-12.2 10.9-25 14.1-38.2l28.2 6.3c-3.5 15.2-9.1 30.6-16.6 45" style="fill:#be1e2d"/><path d="m411.6 154.8-24.1 15.3c-7.2-11.3-16-21.9-26.3-31.3l19.4-21.3c12.3 11.3 22.6 23.8 31 37.3" style="fill:#f15a29"/><path d="M368.5 107.2 351 130c-10.9-8.4-22.8-15.3-35.4-20.3l10.9-26.6c14.7 6.3 28.8 14.1 42 24.1" style="fill:#f7941d"/><path d="M255.8 245.2c6.6 0 12.2 5.3 12.2 12.2 0 6.6-5.3 12.2-12.2 12.2-6.6 0-12.2-5.3-12.2-12.2.4-6.9 5.7-12.2 12.2-12.2" style="fill:#e6e7e8"/><linearGradient id="librespeed_svg__a" x1="255.9" x2="255.9" y1="-135.873" y2="-81.648" gradientTransform="matrix(1 0 0 -1 0 46.44)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#1b75bc"/><stop offset="1" style="stop-color:#00aeef"/><stop offset="1" style="stop-color:#000"/></linearGradient><path d="M283.1 254.9c0 21.6-12.2 39.1-27.2 39.1s-27.2-17.5-27.2-39.1l2.2-16 24.7-168.6 24.7 168.6zm-15.1 2.2c0-6.6-5.3-12.2-12.2-12.2-6.6 0-12.2 5.3-12.2 12.2 0 6.6 5.3 12.2 12.2 12.2S268 264 268 257.1" style="fill:url(#librespeed_svg__a)"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,14 @@
[variables]
main_domain = "${domain}"
password = "${password:32}"
[config]
[[config.domains]]
serviceName = "librespeed"
port = 80
host = "${main_domain}"
[config.env]
PASSWORD = "${password}"
TZ = "UTC"
CUSTOM_RESULTS = "false"

View File

@@ -0,0 +1,40 @@
version: "3.8"
services:
db:
image: mariadb:10.11
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=limesurvey
- MYSQL_USER=limesurvey
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
limesurvey:
image: martialblog/limesurvey:latest
restart: always
volumes:
- limesurvey_upload:/var/www/html/upload
environment:
- ADMIN_EMAIL=${ADMIN_EMAIL}
- ADMIN_NAME=Admin
- ADMIN_USER=admin
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- DB_HOST=db
- DB_MYSQL_ENGINE=InnoDB
- DB_NAME=limesurvey
- DB_PASSWORD=${MYSQL_PASSWORD}
- DB_USERNAME=limesurvey
- DEBUG=0
- DEBUG_SQL=0
- PUBLIC_URL=${PUBLIC_URL}
- SHOW_SCRIPT_NAME=false
- URL_FORMAT=path
depends_on:
- db
volumes:
db_data:
limesurvey_upload:

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 159.9 43.5" style="enable-background:new 0 0 159.9 43.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#14AE5C;}
</style>
<path class="st0" d="M41.8,36.4h10.1v-3h-6.3V23.1h-3.8V36.4z M55.1,25c1.1,0.1,2.1-0.7,2.2-1.8c0-0.1,0-0.1,0-0.2
c0-1.1-1-1.9-2-1.9c-0.1,0-0.1,0-0.2,0C54,21,53,21.8,52.9,22.9c0,0,0,0.1,0,0.1c0,1.1,1,2,2.1,1.9C55,25,55,25,55.1,25z M53.2,36.4
h3.6V26.1h-3.6V36.4z M72.6,25.9c-1.4,0-2.7,0.6-3.6,1.6c-0.8-1.1-2-1.7-3.3-1.6c-1.2,0-2.3,0.4-3.1,1.3v-1.1h-3.4v10.3h3.6v-5.1
c0-1.6,0.8-2.3,1.8-2.3c1,0,1.6,0.6,1.6,2.1v5.3h3.6v-5.1c0-1.6,0.8-2.3,1.8-2.3c0.9,0,1.6,0.6,1.6,2.1v5.3h3.6v-5.9
C76.8,27.3,75,25.9,72.6,25.9z M89.7,31.3c0.1-2.8-2.1-5.2-5-5.3c-0.2,0-0.4,0-0.5,0c-3.2,0-5.7,2.2-5.7,5.3c0,3.1,2.4,5.3,6,5.3
c1.6,0.1,3.2-0.5,4.4-1.7l-1.9-2c-0.6,0.6-1.5,0.9-2.4,0.9c-1.1,0.1-2.2-0.6-2.5-1.7h7.5C89.7,31.9,89.7,31.5,89.7,31.3z M84.2,28.5
c1.1,0,2,0.7,2.1,1.8h-4.2C82.3,29.2,83.2,28.5,84.2,28.5z M96.2,36.7c4,0,5.9-2,5.9-4.3c0-4.9-7.5-3.4-7.5-5.4
c0-0.7,0.6-1.2,2.1-1.2c1.3,0,2.6,0.4,3.7,1l1.2-2.8c-1.5-0.8-3.1-1.2-4.8-1.2c-4,0-5.9,1.9-5.9,4.3c0,4.9,7.6,3.4,7.6,5.5
c0,0.6-0.6,1.1-2.2,1.1c-1.6,0-3.1-0.5-4.4-1.3l-1.2,2.8C92.3,36.2,94.3,36.7,96.2,36.7z M110.9,26.1v5c0,1.7-0.9,2.4-1.9,2.4
c-1.1,0-1.7-0.6-1.7-2.2v-5.2h-3.6v5.8c0,3.3,1.8,4.7,4.4,4.7c1.2,0,2.3-0.4,3.1-1.3v1.1h3.4V26.1H110.9z M120.3,27.3v-1.2h-3.4
v10.3h3.6v-4.7c-0.2-1.2,0.7-2.4,1.9-2.5c0.2,0,0.4,0,0.6,0c0.3,0,0.5,0,0.8,0.1v-3.2C122.4,25.8,121.2,26.4,120.3,27.3L120.3,27.3z
M133,26.1l-2.6,6.3l-2.5-6.3h-3.7l4.2,10.3h3.7l4.3-10.3H133z M147.6,31.3c0.1-2.8-2.1-5.2-5-5.3c-0.2,0-0.4,0-0.5,0
c-3.2,0-5.7,2.2-5.7,5.3c0,3.1,2.4,5.3,6,5.3c1.6,0.1,3.2-0.5,4.4-1.7l-1.9-2c-0.6,0.6-1.5,0.9-2.4,0.9c-1.1,0.1-2.2-0.6-2.5-1.7
h7.5C147.5,31.9,147.6,31.5,147.6,31.3z M142.1,28.5c1.1,0,2,0.7,2.1,1.8H140C140.1,29.2,141,28.5,142.1,28.5z M156.5,26.1l-2.5,6.3
l-2.5-6.3h-3.7l4.4,10.4c-0.2,0.6-0.8,0.9-1.4,0.9c-0.6,0-1.2-0.2-1.6-0.6l-1.3,2.5c0.9,0.6,1.9,0.9,3,0.9c2,0,3.6-0.8,4.6-3.4
l4.5-10.7H156.5z"/>
<path class="st0" d="M5.4,4.2c1.3,0,2.6,0.3,3.9,0.7c1.2,0.4,2.4,1,3.6,1.6c1.1,0.6,2.2,1.3,3.3,2.1c0.5,0.4,1,0.8,1.5,1.2
c0.3,0.2,0.5,0.4,0.7,0.6c0.1,0.1,0.2,0.2,0.4,0.3L19,11l0.2,0.2l-3.6,0l0.3-0.4l0.3-0.3c0.2-0.2,0.4-0.4,0.6-0.6
C17.2,9.4,17.6,9,18,8.6c0.4-0.4,0.9-0.8,1.3-1.1c0.2-0.2,0.5-0.4,0.7-0.5l0.3-0.3l0.3-0.3c0.9-0.7,1.9-1.3,2.9-1.9s2-1.1,3.1-1.6
c2.1-1,4.3-1.7,6.5-2.2c1.1-0.2,2.3-0.4,3.4-0.5C37.7,0,38.9,0,40,0.1c-0.5,0.3-1,0.6-1.5,0.9c-0.2,0.1-0.5,0.3-0.7,0.4
c-0.1,0.1-0.2,0.1-0.4,0.2l-0.4,0.2c-0.9,0.6-1.9,1.1-2.8,1.7C32.5,4.7,30.8,5.8,29,7s-3.4,2.4-5.1,3.6c-0.4,0.3-0.8,0.6-1.2,0.9
s-0.8,0.6-1.2,1s-0.8,0.7-1.2,1c-0.2,0.2-0.4,0.3-0.6,0.5l-0.5,0.5L17,16.4l-1.4-1.9c0,0-0.1-0.1-0.1-0.1l-0.1-0.2L15,13.9l-0.6-0.7
c-0.4-0.5-0.8-0.9-1.2-1.3c-0.8-0.9-1.6-1.8-2.4-2.7S9.2,7.4,8.3,6.6C7.4,5.7,6.4,4.9,5.4,4.2z"/>
<g transform="translate(0 11.509)">
<path class="st0" d="M17.5,25.1c-4,0-7.7-2.3-9.5-5.9l-6.3,2.7c3.9,8.3,13.6,12.2,22.2,8.9l-2.7-6.3C20,24.9,18.8,25.1,17.5,25.1z"
/>
<path class="st0" d="M6.9,14.4c0-3.7,2-7.2,5.1-9.1L7.6,0C1,4.5-1.7,13,1.1,20.5l6.4-2.7C7.1,16.7,6.9,15.5,6.9,14.4z"/>
<path class="st0" d="M28.1,0.4l-6,4.4c2,1,3.7,2.6,4.7,4.5l6.3-2.7C32,4.2,30.3,2.1,28.1,0.4z"/>
<path class="st0" d="M35.1,14.4c0-2.2-0.4-4.4-1.2-6.4l-6.3,2.7c1.8,5-0.3,10.6-5,13.1l2.7,6.3C31.3,27.2,35.1,21.1,35.1,14.4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Some files were not shown because too many files have changed in this diff Show More