Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions compose.dokploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# compose.dokploy.yml
# Single-file Docker Compose for deploying Instatic on Dokploy (SQLite mode).
#
# Dokploy's Compose app type wants one compose file, but the VPS guide
# (docs/deployment/vps.md) splits SQLite setup across two files
# (compose.prod.yml + compose.sqlite.yml). This file merges those into one
# so it can be pointed at directly from the Dokploy UI.
Comment on lines +2 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document the new deployment path

Add this deployment method to the deployment documentation, including the Dokploy setup steps and required PUBLIC_ORIGIN/secret configuration. The new file is not referenced anywhere under docs/deployment/, leaving operators with only a compose file whose optional-looking defaults are insufficient for the normal proxied HTTPS deployment; repository rules explicitly require documentation to be updated when deployment configuration changes.

AGENTS.md reference: AGENTS.md:L292-L293

Useful? React with 👍 / 👎.

#
# For Postgres instead of SQLite, follow docs/deployment/vps.md directly
# rather than this file.

name: instatic-prod

services:
app:
image: ${INSTATIC_IMAGE:-ghcr.io/corebunch/instatic:latest}
restart: unless-stopped
ports:
- "${HOST_PORT:-3001}:3001"
Comment on lines +18 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the direct host port publication

Because the service is already attached to dokploy-network for Traefik routing, publishing 3001 on every host interface is unnecessary and bypasses Dokploy's TLS/proxy boundary. With the default HOST_PORT, the deployment also fails whenever another stack already owns host port 3001, which is especially likely on a multi-application Dokploy host. Keep port 3001 container-internal for Traefik instead of publishing it on the VPS.

Useful? React with 👍 / 👎.

environment:
PORT: "3001"
DATABASE_URL: sqlite:/app/data/cms.db
UPLOADS_DIR: /app/uploads
STATIC_DIR: /app/dist
INSTATIC_SECRET_KEY: ${INSTATIC_SECRET_KEY:-}
PUBLIC_ORIGIN: ${PUBLIC_ORIGIN:-}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require the HTTPS public origin

When this compose file is launched through Dokploy's HTTPS/Traefik route without manually defining PUBLIC_ORIGIN, this default expands to an empty value. Instatic deliberately ignores forwarded scheme headers and falls back to the plain-HTTP request URL (server/auth/security.ts:88-94), so a browser origin such as https://cms.example.com does not match the server's expected http://cms.example.com; first-run setup, login, and other state-changing requests are consequently rejected as an invalid origin, and session cookies also lack Secure. Make the public HTTPS origin required rather than silently accepting an empty value.

Useful? React with 👍 / 👎.

TRUSTED_PROXY_CIDRS: ${TRUSTED_PROXY_CIDRS:-}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve client IPs behind the Dokploy proxy

Under the intended Traefik-routed deployment, leaving TRUSTED_PROXY_CIDRS empty makes clientIp() ignore X-Forwarded-For and return Traefik's socket address for every visitor (server/auth/security.ts:327-340). All users then share the same per-IP login and MFA rate-limit buckets, so 30 login attempts or 10 MFA attempts through the proxy can temporarily block every legitimate administrator and audit records contain only the proxy address. Supply or require the Dokploy proxy network's trusted CIDR while ensuring the application is not directly exposed.

Useful? React with 👍 / 👎.

volumes:
- uploads:/app/uploads
- data:/app/data
healthcheck:
test: ["CMD", "bun", "run", "server/healthcheck.ts"]
interval: 30s
timeout: 5s
start_period: 20s
retries: 3
networks:
- dokploy-network

volumes:
data:
uploads:

networks:
dokploy-network:
external: true