feat: migrate all stacks to Coolify (proxy network, clean labels, pull_policy)
- Remove traefik.enable, traefik.docker.network, traefik.http.routers.* from all services - Keep traefik.http.services.<name>.loadbalancer.server.port labels - Keep all middleware definitions (forwardauth, headers, redirects) - Add pull_policy: always to main/frontend services - Add proxy network + label to gitea and karakeep (previously missing) - Add COOLIFY-TEMPLATE.md reference guide Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
171
COOLIFY-TEMPLATE.md
Normal file
171
COOLIFY-TEMPLATE.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Coolify Compose Template — TheHomelessSherlock
|
||||
|
||||
## Proxy & Networking Rules
|
||||
|
||||
### Our Setup
|
||||
- **Proxy**: `coolify-proxy` (Traefik v3) configured with `--providers.docker.network=proxy`
|
||||
- **TLS**: certresolver `letsencrypt` via HTTP challenge
|
||||
- **Domain routing**: configured in Coolify UI, NOT in compose labels
|
||||
|
||||
### Rule 1 — Every service exposed via HTTP/HTTPS must be on the `proxy` network
|
||||
|
||||
```yaml
|
||||
services:
|
||||
myapp:
|
||||
image: myimage:latest
|
||||
pull_policy: always
|
||||
networks:
|
||||
- internal
|
||||
- proxy # ← mandatory for Traefik to reach it
|
||||
labels:
|
||||
traefik.http.services.myapp.loadbalancer.server.port: "3000" # ← mandatory port label
|
||||
|
||||
networks:
|
||||
internal:
|
||||
driver: bridge
|
||||
proxy:
|
||||
external: true # ← always external, pre-created by Coolify
|
||||
```
|
||||
|
||||
### Rule 2 — Internal-only services do NOT need proxy
|
||||
|
||||
```yaml
|
||||
services:
|
||||
mydb:
|
||||
image: postgres:16
|
||||
networks:
|
||||
- internal # ← only internal, no proxy
|
||||
|
||||
networks:
|
||||
internal:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### Rule 3 — Mail-relay access via mail_internal network
|
||||
|
||||
Services that need to send mail via the internal mail-relay must be on `mail_internal`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
myapp:
|
||||
networks:
|
||||
- internal
|
||||
- proxy
|
||||
- mail_internal # ← only services that need mail
|
||||
environment:
|
||||
SMTP_HOST: mail-relay # ← container name as hostname
|
||||
SMTP_PORT: 587
|
||||
|
||||
networks:
|
||||
mail_internal:
|
||||
external: true # ← pre-created: docker network create mail_internal
|
||||
```
|
||||
|
||||
### Rule 4 — Labels: only port + optional middleware
|
||||
|
||||
Coolify manages routing labels automatically. Only set:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
# MANDATORY: tell Traefik which port your app listens on
|
||||
traefik.http.services.myapp.loadbalancer.server.port: "3000"
|
||||
|
||||
# OPTIONAL: define reusable middleware (e.g. security headers, redirects)
|
||||
traefik.http.middlewares.myapp-headers.headers.stsSeconds: "31536000"
|
||||
traefik.http.middlewares.myapp-headers.headers.stsIncludeSubdomains: "true"
|
||||
```
|
||||
|
||||
**NEVER add these** (Coolify adds them automatically based on UI config):
|
||||
- `traefik.enable`
|
||||
- `traefik.docker.network`
|
||||
- `traefik.http.routers.*`
|
||||
|
||||
### Rule 5 — pull_policy: always on main service
|
||||
|
||||
Ensures the latest image is pulled on every deploy:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
myapp:
|
||||
image: myimage:latest
|
||||
pull_policy: always # ← add to main/frontend service only
|
||||
```
|
||||
|
||||
### Rule 6 — Authentik middleware
|
||||
|
||||
To protect a service with Authentik SSO, use the middleware defined in the authentik stack:
|
||||
|
||||
In Coolify UI: add this label to your application under "Labels":
|
||||
```
|
||||
traefik.http.routers.<your-router-name>.middlewares=ths-authentik@docker
|
||||
```
|
||||
|
||||
Or in your compose labels (will be merged with Coolify's auto-labels):
|
||||
```yaml
|
||||
labels:
|
||||
traefik.http.services.myapp.loadbalancer.server.port: "3000"
|
||||
# The router name Coolify generates follows: https-0-<uuid>-<servicename>
|
||||
# Use Coolify UI "Labels" field to add the middleware after first deploy
|
||||
```
|
||||
|
||||
## Full Example — Minimal web app with DB and mail
|
||||
|
||||
```yaml
|
||||
services:
|
||||
myapp:
|
||||
image: myimage:latest
|
||||
pull_policy: always
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- myapp-db
|
||||
environment:
|
||||
DB_HOST: myapp-db
|
||||
DB_PORT: 5432
|
||||
SMTP_HOST: mail-relay
|
||||
SMTP_PORT: 587
|
||||
networks:
|
||||
- internal
|
||||
- proxy
|
||||
- mail_internal
|
||||
labels:
|
||||
traefik.http.services.myapp.loadbalancer.server.port: "3000"
|
||||
|
||||
myapp-db:
|
||||
image: postgres:16
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: myapp
|
||||
POSTGRES_USER: myapp
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- /opt/myapp/db:/var/lib/postgresql/data:Z
|
||||
networks:
|
||||
- internal
|
||||
|
||||
networks:
|
||||
internal:
|
||||
driver: bridge
|
||||
proxy:
|
||||
external: true
|
||||
mail_internal:
|
||||
external: true
|
||||
```
|
||||
|
||||
## Pre-created networks on the host
|
||||
|
||||
These networks must exist before deploying stacks that use them:
|
||||
|
||||
```bash
|
||||
# Already created by Coolify:
|
||||
# docker network create proxy ← created as part of Coolify install
|
||||
|
||||
# Create manually once:
|
||||
docker network create mail_internal
|
||||
```
|
||||
|
||||
## Coolify UI checklist per application
|
||||
|
||||
1. **Ports Exposes**: set to the app's HTTP port (must match `loadbalancer.server.port` label)
|
||||
2. **Domain**: set FQDN (e.g. `myapp.sherlockhomeless.net`)
|
||||
3. **Base Directory**: set to the subdirectory (e.g. `/gitea`, `/n8n`)
|
||||
4. **Environment Variables**: fill from `stack.env` template
|
||||
Reference in New Issue
Block a user