Files
zeekay cf4d0b027e templates.hanzo.ai: 1030-blueprint one-click deploy catalog
Aggregates five OSS one-click/self-hosting catalogs into the Dokploy blueprint
shape the Hanzo PaaS consumes (meta.json array + blueprints/<id>/{template.toml,
docker-compose.yml,meta.json,logo}):

  Dokploy 500 (MIT, verbatim) · Coolify 174 (Apache-2.0) · CapRover 161
  (Apache-2.0) · CasaOS 85 (Apache-2.0) · Runtipi 110 (GPL-3.0)

Deduped by app identity; each source + app keeps its upstream license
(ATTRIBUTION.md). Deterministic aggregators + a hard validator (every
template.toml parses with the platform's toml lib, every compose parses as YAML,
meta.json is the expected array, and an over-HTTP fetch probe exercises all
1030) — 0 hard failures. Served natively by hanzoai/static on DOKS (no CDN/Pages/
Vercel); CI builds on the hanzo-build-linux-amd64 arc pool; operator App CR in
crs/ serves it at templates.hanzo.ai.
2026-07-24 01:46:23 -07:00

91 lines
3.4 KiB
YAML

services:
server:
image: docker.io/awinterstein/habitica-server:latest
restart: unless-stopped
depends_on:
mongo:
condition: service_healthy
environment:
NODE_DB_URI: "mongodb://${MONGO_HABITICA_USER}:${MONGO_HABITICA_PASSWORD}@mongo/habitica?authSource=habitica"
INVITE_ONLY: "${INVITE_ONLY}"
EMAIL_SERVER_URL: "${EMAIL_SERVER_URL}"
EMAIL_SERVER_PORT: "${EMAIL_SERVER_PORT}"
EMAIL_SERVER_AUTH_USER: "${EMAIL_SERVER_AUTH_USER}"
EMAIL_SERVER_AUTH_PASSWORD: "${EMAIL_SERVER_AUTH_PASSWORD}"
ADMIN_EMAIL: "${ADMIN_EMAIL}"
client:
image: docker.io/awinterstein/habitica-client:latest
restart: unless-stopped
depends_on:
- server
ports:
- "80"
mongo:
image: docker.io/mongo:latest
restart: unless-stopped
command: >
bash -c "
echo \"${MONGO_KEYFILE_CONTENT}\" > /etc/mongo-keyfile &&
chown 999:999 /etc/mongo-keyfile &&
chmod 400 /etc/mongo-keyfile &&
exec docker-entrypoint.sh mongod --replSet rs --bind_ip_all --port 27017 --keyFile /etc/mongo-keyfile
"
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ADMIN_USER}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ADMIN_PASSWORD}
MONGO_KEYFILE_CONTENT: ${MONGO_KEYFILE_CONTENT}
MONGO_HABITICA_USER: ${MONGO_HABITICA_USER}
MONGO_HABITICA_PASSWORD: ${MONGO_HABITICA_PASSWORD}
# ---------------------------------------------------------
# SMART HEALTHCHECK: Auto-fixes Hostname Mismatches for replicaSet
# ---------------------------------------------------------
healthcheck:
test: |
mongosh --port 27017 --quiet -u "${MONGO_ADMIN_USER}" -p "${MONGO_ADMIN_PASSWORD}" --authenticationDatabase admin --eval "
try {
// 1. Hostname Fix
const config = rs.conf();
const currentHost = require('os').hostname() + ':27017';
if (config.members[0].host !== currentHost) {
config.members[0].host = currentHost;
rs.reconfig(config, { force: true });
}
// 2. User Creation Logic
const targetDb = db.getSiblingDB('habitica');
const hUser = process.env.MONGO_HABITICA_USER;
const hPass = process.env.MONGO_HABITICA_PASSWORD;
// We can only check/create users if we are Primary
if (rs.isMaster().ismaster) {
if (!targetDb.getUser(hUser)) {
print('Creating missing user ' + hUser + '...');
targetDb.createUser({ user: hUser, pwd: hPass, roles: ['readWrite'] });
}
// SUCCESS: User exists and we are Primary
quit(0);
} else {
// We are not Primary yet (still electing), so we cannot confirm user exists.
// Fail the check so the dependent app waits.
print('Waiting for Primary state...');
quit(1);
}
} catch (err) {
// If not initialized, initiate and FAIL this check so we wait for the next cycle
try {
rs.initiate({ _id: 'rs', members: [{ _id: 0, host: require('os').hostname() + ':27017' }] });
} catch (e) {}
quit(1);
}
"
interval: 5s
timeout: 10s
retries: 20
volumes:
- habitica-mongo-data:/data/db
volumes:
habitica-mongo-data: {}