mirror of
https://github.com/Dokploy/templates.git
synced 2026-07-22 22:35:24 +02:00
feat: add struxa template (#1037)
* feat: add struxa template
Adds a Dokploy blueprint for Struxa (github.com/struxadotcloud/struxa),
a self-hosted, open-source server management panel. Deploys the
published GHCR images (dashboard, watchkeeper, migrate) plus MySQL
and MinIO sidecars. The web service generates its RS256 JWT keypair
at startup via Node's built-in crypto module, since no Dokploy
template helper covers RSA key generation.
* fix: pin struxa images to latest floating tag
struxa's release workflow pushes a latest floating tag alongside
version tags on every stable release, matching the convention used
by ~44% of existing blueprints (version: "latest" in meta.json).
* fix: generate a 64-char DATABASE_ENCRYPTION_KEY
Dokploy's runtime \${hash:N} helper produces N hex characters, not N
bytes (the templates repo's local preview helpers.ts models it as
byte count, which is inconsistent with the platform). struxa's env
schema requires DATABASE_ENCRYPTION_KEY to be >=64 chars (it's hex
decoded to a 32-byte AES-256 key), so \${hash:32} only produced half
the required length. Confirmed against other blueprints (sim,
chatwoot, outline) which all use \${hash:64} for 64-char secrets.
* fix: address Copilot review comments
- Add explicit \`version: "3.8"\` to docker-compose.yml, matching the
documented template format.
- Pin minio/minio to a specific RELEASE tag (used elsewhere in the
repo: plane, posthog) instead of the floating latest tag.
- Default BETTER_AUTH_URL/APP_URL/CORS_ORIGIN to http://, matching
repo convention for Dokploy-fronted apps (TLS terminates at the
proxy).
* fix: rename web service to struxa
AGENTS.md convention: the primary Docker service name should match
the blueprint folder name. Renamed the web/dashboard service from
"web" to "struxa" in docker-compose.yml and updated
template.toml's config.domains.serviceName to match.
This commit is contained in:
committed by
GitHub
parent
8ca2bf9393
commit
08d87d8a90
90
blueprints/struxa/docker-compose.yml
Normal file
90
blueprints/struxa/docker-compose.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.4
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||
- MYSQL_USER=${MYSQL_USER}
|
||||
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||
volumes:
|
||||
- struxa-mysql:/var/lib/mysql
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
start_period: 60s
|
||||
|
||||
minio:
|
||||
image: minio/minio:RELEASE.2025-04-22T22-12-26Z
|
||||
restart: unless-stopped
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY}
|
||||
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY}
|
||||
volumes:
|
||||
- struxa-minio:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
migrate:
|
||||
image: ghcr.io/struxadotcloud/migrate:${IMAGE_TAG}
|
||||
restart: on-failure:5
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
|
||||
struxa:
|
||||
image: ghcr.io/struxadotcloud/dashboard:${IMAGE_TAG}
|
||||
restart: unless-stopped
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
eval "$$(node -e '
|
||||
const {generateKeyPairSync}=require("crypto");
|
||||
const {publicKey,privateKey}=generateKeyPairSync("rsa",{modulusLength:2048,
|
||||
publicKeyEncoding:{type:"spki",format:"pem"},
|
||||
privateKeyEncoding:{type:"pkcs8",format:"pem"}});
|
||||
console.log("export JWT_PRIVATE_KEY="+JSON.stringify(privateKey.replace(/\n/g,"\\n")));
|
||||
console.log("export JWT_PUBLIC_KEY="+JSON.stringify(publicKey.replace(/\n/g,"\\n")));
|
||||
')"
|
||||
exec node apps/web/server.js
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
|
||||
- BETTER_AUTH_URL=${BETTER_AUTH_URL}
|
||||
- CORS_ORIGIN=${CORS_ORIGIN}
|
||||
- APP_URL=${APP_URL}
|
||||
- DATABASE_ENCRYPTION_KEY=${DATABASE_ENCRYPTION_KEY}
|
||||
- MINIO_ENDPOINT=${MINIO_ENDPOINT}
|
||||
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
|
||||
- MINIO_BUCKET=${MINIO_BUCKET}
|
||||
- NODE_ENV=production
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
minio:
|
||||
condition: service_healthy
|
||||
|
||||
watchkeeper:
|
||||
image: ghcr.io/struxadotcloud/watchkeeper:${IMAGE_TAG}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- DATABASE_ENCRYPTION_KEY=${DATABASE_ENCRYPTION_KEY}
|
||||
depends_on:
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
|
||||
volumes:
|
||||
struxa-mysql:
|
||||
struxa-minio:
|
||||
18
blueprints/struxa/meta.json
Normal file
18
blueprints/struxa/meta.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id": "struxa",
|
||||
"name": "Struxa",
|
||||
"version": "latest",
|
||||
"description": "Struxa is a self-hosted, open-source server management panel — a modern, fully typed replacement for Pterodactyl.",
|
||||
"links": {
|
||||
"github": "https://github.com/struxadotcloud/struxa",
|
||||
"website": "https://struxa.cloud",
|
||||
"docs": "https://docs.struxa.cloud"
|
||||
},
|
||||
"logo": "struxa.svg",
|
||||
"tags": [
|
||||
"hosting",
|
||||
"game-server",
|
||||
"panel",
|
||||
"self-hosted"
|
||||
]
|
||||
}
|
||||
3
blueprints/struxa/struxa.svg
Normal file
3
blueprints/struxa/struxa.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="839" height="789" viewBox="0 0 839 789" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M407.26 0C409.311 3.01855 437.563 194.316 440.941 215.859C432.709 227.644 398.598 260.213 386.51 272.273L241.182 417.006L202.197 455.6C195.731 461.996 184.866 471.557 180.147 478.607C167.061 498.148 189.423 516.264 207.028 500.98C214.727 494.291 222.397 485.648 229.322 478.764L282.741 425.541L451.986 256.722C477.143 231.636 512.24 193.419 540.707 175.544C570.981 156.731 605.776 146.478 641.41 145.873C693.481 144.884 743.774 164.823 781.02 201.227C817.836 237.355 838.656 286.711 838.842 338.287C838.891 375.104 828.529 411.185 808.959 442.367C793.109 467.416 771.781 486.576 750.922 507.426L690.131 568.188L469.74 788.549C458.256 716.615 448.656 643.353 436.557 571.664C487.992 518.803 542.543 465.619 594.799 413.363L637.152 370.987C647.621 360.508 672.426 342.071 656.244 326.121C654.555 324.477 652.524 323.228 650.297 322.464C634.565 316.963 623.149 333.782 613.022 343.945L570.092 387.095L403.432 554.272L356.588 601.352C337.886 620.17 323.781 636.176 301.203 650.688C269.249 671.293 232.153 682.504 194.138 683.07C142.564 683.646 92.9494 663.324 56.5958 626.742C20.1515 590.521 -0.236216 541.195 0.00206543 489.818C0.302847 450.199 12.0988 411.508 33.9572 378.456C46.6564 359.169 66.2355 341.424 82.7706 324.872L145.457 262.05L407.26 0Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
34
blueprints/struxa/template.toml
Normal file
34
blueprints/struxa/template.toml
Normal file
@@ -0,0 +1,34 @@
|
||||
[variables]
|
||||
main_domain = "${domain}"
|
||||
image_tag = "latest"
|
||||
mysql_root_password = "${password:32}"
|
||||
mysql_password = "${password:32}"
|
||||
better_auth_secret = "${base64:32}"
|
||||
db_encryption_key = "${hash:64}"
|
||||
minio_access_key = "${username}"
|
||||
minio_secret_key = "${password:32}"
|
||||
|
||||
[config]
|
||||
env = [
|
||||
"IMAGE_TAG=${image_tag}",
|
||||
"MYSQL_ROOT_PASSWORD=${mysql_root_password}",
|
||||
"MYSQL_DATABASE=struxa",
|
||||
"MYSQL_USER=struxa",
|
||||
"MYSQL_PASSWORD=${mysql_password}",
|
||||
"DATABASE_URL=mysql://struxa:${mysql_password}@mysql:3306/struxa",
|
||||
"BETTER_AUTH_SECRET=${better_auth_secret}",
|
||||
"BETTER_AUTH_URL=http://${main_domain}",
|
||||
"APP_URL=http://${main_domain}",
|
||||
"CORS_ORIGIN=http://${main_domain}",
|
||||
"DATABASE_ENCRYPTION_KEY=${db_encryption_key}",
|
||||
"MINIO_ENDPOINT=http://minio:9000",
|
||||
"MINIO_ACCESS_KEY=${minio_access_key}",
|
||||
"MINIO_SECRET_KEY=${minio_secret_key}",
|
||||
"MINIO_BUCKET=struxa",
|
||||
]
|
||||
mounts = []
|
||||
|
||||
[[config.domains]]
|
||||
serviceName = "struxa"
|
||||
port = 3001
|
||||
host = "${main_domain}"
|
||||
Reference in New Issue
Block a user