supabase
Handles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...
dokploy-security-hardening
Security best practices for Dokploy templates: secrets management, network isolation, least privilege, image security, and hardening recommendations.
Full skill instructions
Never Hardcode Secrets:
# WRONG - Secret in compose file
environment:
DATABASE_PASSWORD: supersecretpassword123
# CORRECT - Use variable with required syntax
environment:
DATABASE_PASSWORD: ${DATABASE_PASSWORD:?Set database password}
Use Proper Variable Generation in template.toml:
[variables]
# Passwords - random alphanumeric
db_password = "${password:32}"
# Secrets - base64 encoded
secret_key = "${base64:64}"
jwt_secret = "${base64:48}"
# Internal tokens - high entropy
internal_token = "${password:48}"
Mask Sensitive Output:
# In docker-compose, sensitive vars are hidden in Dokploy UI
environment:
API_KEY: ${API_KEY:?Set API key} # Treated as sensitive
Database/Cache Services (Internal Only):
services:
postgres:
image: postgres:16-alpine
networks:
- app-net # Internal ONLY - no dokploy-network
# NO labels - not exposed via Traefik
redis:
image: redis:7-alpine
networks:
- app-net # Internal ONLY
Web Services (External + Internal):
services:
app:
image: myapp:1.0.0
networks:
- app-net # Internal (to reach database)
- dokploy-network # External (for Traefik)
labels:
- "traefik.enable=true"
# ... routing labels
Network Definition:
networks:
app-net:
driver: bridge
# Internal network, not externally accessible
dokploy-network:
external: true
# Managed by Dokploy, shared with Traefik
Pin Image Versions:
# CORRECT - Specific versions
image: postgres:16-alpine
image: mongo:7
image: redis:7-alpine
image: wardpearce/paaster:3.1.7
# WRONG - Floating tags
image: postgres:latest
image: mongo
image: myapp # Implies :latest
Use Official/Trusted Images:
# Prefer official images
image: postgres:16-alpine # Official
image: redis:7-alpine # Official
image: mongo:7 # Official
# For third-party, use verified sources
image: ghcr.io/paperless-ngx/paperless-ngx:2.13 # GitHub verified
image: codeberg.org/forgejo/forgejo:9 # Codeberg verified
Alpine Images (Smaller Attack Surface):
# Prefer Alpine variants when available
image: postgres:16-alpine # vs postgres:16
image: redis:7-alpine # vs redis:7
image: node:20-alpine # vs node:20
Read-Only Filesystem (Where Possible):
services:
app:
image: myapp:1.0.0
read_only: true
tmpfs:
- /tmp
- /var/run
volumes:
- app-data:/app/data # Only writable location
Drop Capabilities:
services:
app:
image: myapp:1.0.0
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE # Only if needed for port < 1024
No Privileged Mode:
# NEVER use privileged mode for application containers
services:
app:
image: myapp:1.0.0
# privileged: true # NEVER DO THIS
Memory and CPU Limits:
services:
app:
image: myapp:1.0.0
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
reservations:
memory: 128M
cpus: "0.25"
Don't Expose Sensitive Info:
healthcheck:
# CORRECT - Simple endpoint
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
# WRONG - Exposes internal state
test: ["CMD", "curl", "-f", "http://localhost:8080/debug/vars"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.routers.app.middlewares=security-headers@docker"
# Security headers middleware
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
- "traefik.http.middlewares.security-headers.headers.referrerPolicy=strict-origin-when-cross-origin"
- "traefik.http.services.app.loadbalancer.server.port=8080"
- "traefik.docker.network=dokploy-network"
${VAR:?message} syntax${password:N} in template.toml${base64:N}:latest tagsWhen reviewing a template, check each category:
## Security Review: [Template Name]
### Secrets Management
- [ ] Secrets: All secrets use variable syntax
- [ ] Passwords: Generated in template.toml
- [ ] External APIs: Left blank for user input
### Network Isolation
- [ ] Databases: Internal network only
- [ ] Web services: dokploy-network attached
- [ ] No debug ports exposed
### Image Security
- [ ] Versions: All images pinned
- [ ] Sources: Official/verified images
- [ ] Alpine: Used where available
### Container Security
- [ ] Privileges: No privileged mode
- [ ] Resources: Limits defined (optional but recommended)
- [ ] Health: Secure health endpoints
### HTTPS/TLS
- [ ] TLS: Using letsencrypt certresolver
- [ ] Entrypoint: websecure (HTTPS)
- [ ] Headers: Security headers middleware (recommended)
### Findings
- [ ] Issue 1: [Description] - [Severity]
- [ ] Issue 2: [Description] - [Severity]
### Recommendations
1. [Recommendation]
2. [Recommendation]
services:
app:
image: myapp:1.2.3 # Pinned version
restart: always
depends_on:
postgres:
condition: service_healthy
environment:
# Domain (required)
APP_DOMAIN: ${DOMAIN:?Set your domain}
APP_URL: https://${DOMAIN}
# Database (secure connection)
DATABASE_URL: postgresql://${DB_USER:-app}:${DB_PASS}@postgres:5432/${DB_NAME:-app}
# Secrets (all use variables)
SECRET_KEY: ${SECRET_KEY:?Set secret key}
JWT_SECRET: ${JWT_SECRET:?Set JWT secret}
# Security settings
DEBUG: "false" # Production default
SECURE_COOKIES: "true"
networks:
- app-net
- dokploy-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.app.entrypoints=websecure" # HTTPS only
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.routers.app.middlewares=security-headers@docker"
# Security headers
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.services.app.loadbalancer.server.port=8080"
- "traefik.docker.network=dokploy-network"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
postgres:
image: postgres:16-alpine # Alpine, pinned version
restart: always
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${DB_NAME:-app}
POSTGRES_USER: ${DB_USER:-app}
POSTGRES_PASSWORD: ${DB_PASS:?Set database password}
networks:
- app-net # Internal ONLY
# NO dokploy-network - not exposed
# NO Traefik labels - not routed
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-app} -d ${DB_NAME:-app}"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
volumes:
postgres-data:
driver: local
networks:
app-net:
driver: bridge
dokploy-network:
external: true
Issue: Database accessible to other containers Solution: Only connect to internal app-net
Issue: Exposes sensitive information Solution: Default DEBUG to "false"
Issue: Unexpected updates, security regressions Solution: Pin all image versions
Issue: Secrets in version control
Solution: Use ${VAR:?message} syntax
This skill is part of the skills-first architecture - loaded during Validation phase (Phase 4) to perform security review of generated templates.
dokploy-compose-structure: Network setupdokploy-environment-config: Secret handlingdokploy-cloudflare-integration: Zero Trust/dokploy-create command: Phase 4 (Validation) - Step 11-3. Phase 3: Generation skills (all files created)
4. This skill: Security review and hardening (Phase 4, Step 1)
5. dokploy-template-validation: Convention compliance validation
6. docker compose config: Final syntax validation
See: .claude/commands/dokploy-create.md for full workflow
Handles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...
Comprehensive guides and best practices for Neon Serverless Postgres, covering setup, connection methods, authentication, and platform APIs.
Guide for setting up and using Firebase Authentication. Use this skill when the user's app requires user sign-in, user management, or secure data access using auth rules.
A skill to evaluate how secure Firestore security rules are. Use this when Firestore security rules are updated to ensure that the generated rules are extremely secure and robust.
Official skill for integrating Firebase AI Logic (Gemini API) into web applications. Covers setup, multimodal inference, structured output, and security.
Complete Better Auth server and client setup with database adapters, session management, plugins, and security configuration.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Complete Cloudflare platform integration with decision trees for compute, storage, AI, networking, security, and infrastructure-as-code.
Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.
Send, read, and manage Gmail messages, drafts, labels, and account settings.
Comprehensive website auditing across 230+ rules in 21 categories including SEO, performance, security, and accessibility.
Shared authentication, CLI syntax, and output formatting patterns for gws Google Workspace commands.
Discover your celebrity doppelgänger with StarByFace!
GeoSpy: Pricing, Features, FAQs, and Alternatives for AI Teams
Detect AI-generated voices to protect against audio fraud.
Ensure Your Content's Originality with AI Plagiarism Checker
Upscale images by 400% without quality loss
Protect your social media from copyright disputes
Accurately Detect AI-Generated Content with TheChecker.AI
Chrome extension that detects and flags AI-generated content