Compare commits
21 Commits
81c7b45069
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b1525f2c9 | ||
|
|
7eb63a921c | ||
|
|
8373f1ddfb | ||
|
|
fd332455c1 | ||
|
|
ca4fd7be30 | ||
|
|
7896614cfd | ||
|
|
38440fe0f0 | ||
|
|
5617b29fcf | ||
|
|
9f7bcb3ecc | ||
|
|
93ea33c045 | ||
|
|
9e82928049 | ||
|
|
95f93094da | ||
|
|
baa0c6b769 | ||
|
|
e6fda25c3d | ||
|
|
1dbf673051 | ||
|
|
f7a4c1134a | ||
|
|
f36e537336 | ||
|
|
faffd54ff1 | ||
|
|
797fa7aa4a | ||
|
|
833b80accf | ||
|
|
a17b589803 |
255
COOLIFY-TEMPLATE.md
Normal file
255
COOLIFY-TEMPLATE.md
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gotchas del sistema — leer antes de tocar el proxy
|
||||||
|
|
||||||
|
### Gotcha 1 — Directorio dynamic del proxy NO es el de Coolify
|
||||||
|
|
||||||
|
El proxy `coolify-proxy` monta su directorio de configuración dinámica desde:
|
||||||
|
```
|
||||||
|
/opt/traefik/dynamic → /dynamic (dentro del contenedor)
|
||||||
|
```
|
||||||
|
|
||||||
|
**NO** desde `/data/coolify/proxy/dynamic/` (ese directorio existe pero Traefik NO lo lee).
|
||||||
|
|
||||||
|
Si necesitas añadir rutas manuales (por ejemplo, para el dashboard de Coolify), edita:
|
||||||
|
```bash
|
||||||
|
/opt/traefik/dynamic/coolify.yaml # ← aquí es donde importa
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gotcha 2 — Entrypoints del proxy: `http` y `https` (NO `web`/`websecure`)
|
||||||
|
|
||||||
|
Coolify genera automáticamente labels de Traefik con:
|
||||||
|
- `entryPoints=http` (puerto 80)
|
||||||
|
- `entryPoints=https` (puerto 443)
|
||||||
|
|
||||||
|
El proxy (`/data/coolify/proxy/docker-compose.yml`) está configurado con esos mismos nombres.
|
||||||
|
El contenedor `coolify` propio tiene labels antiguas con `websecure` — no importa porque
|
||||||
|
su routing está definido en `/opt/traefik/dynamic/coolify.yaml`.
|
||||||
|
|
||||||
|
**Si el dashboard de Coolify da 404**, verificar:
|
||||||
|
1. Que `/opt/traefik/dynamic/coolify.yaml` existe y tiene routers `http`/`https`
|
||||||
|
2. Que `coolify-proxy` puede resolver `coolify:8080` (ambos en red `proxy`)
|
||||||
|
|
||||||
|
### Gotcha 3 — Variables en bind mounts → Coolify las convierte en volúmenes nombrados
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# ❌ MAL: Coolify NO resuelve la variable → crea volumen Docker nombrado vacío
|
||||||
|
volumes:
|
||||||
|
- ${MY_DATA_PATH}:/var/lib/postgresql/data:Z
|
||||||
|
|
||||||
|
# ✅ BIEN: rutas hardcodeadas
|
||||||
|
volumes:
|
||||||
|
- /opt/myapp/postgres:/var/lib/postgresql/data:Z
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gotcha 4 — SSH MaxSessions
|
||||||
|
|
||||||
|
`/etc/ssh/sshd_config` tiene `MaxSessions 20` (cambiado de 2).
|
||||||
|
Coolify abre múltiples sesiones SSH en paralelo durante el deploy.
|
||||||
|
Si vuelve a bajar a 2 (upgrade del OS, etc.), todos los deploys fallarán con exit code 255.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep MaxSessions /etc/ssh/sshd_config # debe ser >= 10
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gotcha 5 — Todos los datos del host están en /opt/<stack>/
|
||||||
|
|
||||||
|
Convención de este servidor: todos los bind mounts van bajo `/opt/<nombre-stack>/`.
|
||||||
|
Antes de hardcodear rutas en un compose, verificar siempre:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls /opt/<stack>/ # ej: /opt/adguard/, /opt/authentik/, /opt/gitea/, etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
Si existe el directorio con datos → usar bind mount a esa ruta.
|
||||||
|
Si no existe → crear el directorio antes de desplegar, o usar named volume.
|
||||||
|
|
||||||
|
### Gotcha 6 — Variables en labels de Traefik NO se expanden en Coolify
|
||||||
|
|
||||||
|
Coolify expande `${VAR}` en la sección `environment:` pero NO en `labels:`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# ❌ MAL: quedará como literal ${OO_DOMAIN} en el label del contenedor
|
||||||
|
labels:
|
||||||
|
- traefik.http.middlewares.foo.headers.customRequestHeaders.X-Forwarded-Host=${OO_DOMAIN}
|
||||||
|
|
||||||
|
# ✅ BIEN: hardcodear el valor real
|
||||||
|
labels:
|
||||||
|
- traefik.http.middlewares.foo.headers.customRequestHeaders.X-Forwarded-Host=onlyoffice.sherlockhomeless.net
|
||||||
|
```
|
||||||
|
|
||||||
|
Esto afecta especialmente a headers `X-Forwarded-Host` de OnlyOffice — si queda
|
||||||
|
como literal, el JS de OnlyOffice intenta cargar assets de `https://${oo_domain}/...`
|
||||||
|
y el editor de documentos falla completamente.
|
||||||
@@ -2,13 +2,14 @@ services:
|
|||||||
adguardhome:
|
adguardhome:
|
||||||
image: ${ADGUARD_IMAGE}
|
image: ${ADGUARD_IMAGE}
|
||||||
container_name: adguardhome
|
container_name: adguardhome
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${ADGUARD_WORK_PATH}:/opt/adguardhome/work:Z
|
- /opt/adguard/work:/opt/adguardhome/work:Z
|
||||||
- ${ADGUARD_CONF_PATH}:/opt/adguardhome/conf:Z
|
- /opt/adguard/conf:/opt/adguardhome/conf:Z
|
||||||
- ${ADGUARD_CERT_CRT_PATH}:/certs/adguard.crt:ro,Z
|
- adguard-cert-crt-path:/certs/adguard.crt:ro,Z
|
||||||
- ${ADGUARD_CERT_KEY_PATH}:/certs/adguard.key:ro,Z
|
- adguard-cert-key-path:/certs/adguard.key:ro,Z
|
||||||
|
|
||||||
# Solo DNS/DoT expuestos en el host
|
# Solo DNS/DoT expuestos en el host
|
||||||
ports:
|
ports:
|
||||||
@@ -22,22 +23,12 @@ services:
|
|||||||
ipv4_address: ${ADGUARD_IPV4}
|
ipv4_address: ${ADGUARD_IPV4}
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
traefik.http.services.adguard.loadbalancer.server.port: "80"
|
||||||
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
|
|
||||||
|
|
||||||
# Router HTTPS para el panel web
|
volumes:
|
||||||
traefik.http.routers.adguard.rule: "Host(`${ADGUARD_DOMAIN}`)"
|
adguard-cert-crt-path:
|
||||||
traefik.http.routers.adguard.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
adguard-cert-key-path:
|
||||||
traefik.http.routers.adguard.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
|
|
||||||
# Panel interno de AdGuard (HTTP en el contenedor)
|
|
||||||
# OJO: si es la primera vez y el panel escucha en 3000, cambia a 3000
|
|
||||||
traefik.http.services.adguard.loadbalancer.server.port: "${ADGUARD_HTTP_PORT}"
|
|
||||||
|
|
||||||
# Proteger el panel con Authentik (middleware definido en authentik-server)
|
|
||||||
traefik.http.routers.adguard.middlewares: "${TRAEFIK_AUTH_MIDDLEWARE}"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
proxy:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ ADGUARD_CERT_CRT_PATH=
|
|||||||
ADGUARD_CERT_KEY_PATH=
|
ADGUARD_CERT_KEY_PATH=
|
||||||
ADGUARD_DOT_PORT=
|
ADGUARD_DOT_PORT=
|
||||||
ADGUARD_IPV4=
|
ADGUARD_IPV4=
|
||||||
ADGUARD_HTTP_PORT=
|
ADGUARD_HTTP_PORT=80
|
||||||
|
|
||||||
##### Traefik / red #####
|
##### Traefik / red #####
|
||||||
TRAEFIK_DOCKER_NETWORK=
|
TRAEFIK_DOCKER_NETWORK=
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ services:
|
|||||||
POSTGRES_USER: ${AUTHENTIK_DB_USER}
|
POSTGRES_USER: ${AUTHENTIK_DB_USER}
|
||||||
POSTGRES_DB: ${AUTHENTIK_DB_NAME}
|
POSTGRES_DB: ${AUTHENTIK_DB_NAME}
|
||||||
volumes:
|
volumes:
|
||||||
- ${AUTHENTIK_POSTGRES_PATH}:/var/lib/postgresql/data:Z
|
- /opt/authentik/postgres:/var/lib/postgresql/data:Z
|
||||||
networks:
|
networks:
|
||||||
- ths_authentik_internal
|
- ths_authentik_internal
|
||||||
|
|
||||||
@@ -18,13 +18,14 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
|
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
|
||||||
volumes:
|
volumes:
|
||||||
- ${AUTHENTIK_REDIS_PATH}:/data:Z
|
- /opt/authentik/redis:/data:Z
|
||||||
networks:
|
networks:
|
||||||
- ths_authentik_internal
|
- ths_authentik_internal
|
||||||
|
|
||||||
ths-authentik-server:
|
ths-authentik-server:
|
||||||
image: ${AUTHENTIK_IMAGE}
|
image: ${AUTHENTIK_IMAGE}
|
||||||
container_name: ths-authentik-server
|
container_name: ths-authentik-server
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: ["server"]
|
command: ["server"]
|
||||||
environment:
|
environment:
|
||||||
@@ -47,40 +48,21 @@ services:
|
|||||||
- ths-authentik-redis
|
- ths-authentik-redis
|
||||||
|
|
||||||
expose:
|
expose:
|
||||||
- "${AUTHENTIK_HTTP_PORT}"
|
- "9000"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- ths_authentik_internal
|
- ths_authentik_internal
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
|
||||||
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
|
|
||||||
|
|
||||||
# Service Authentik (panel + endpoints)
|
# Service Authentik (panel + endpoints)
|
||||||
traefik.http.services.ths-authentik.loadbalancer.server.port: "${AUTHENTIK_HTTP_PORT}"
|
traefik.http.services.ths-authentik.loadbalancer.server.port: "9000"
|
||||||
|
|
||||||
# Panel Authentik (auth.thehomelesssherlock.com)
|
# Middleware forwardAuth (para proteger otros servicios) -> usar ths-authentik@docker en tus stacks THS
|
||||||
traefik.http.routers.ths-authentik.rule: "Host(`${AUTHENTIK_DOMAIN}`)"
|
|
||||||
traefik.http.routers.ths-authentik.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.ths-authentik.tls: "true"
|
|
||||||
traefik.http.routers.ths-authentik.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.ths-authentik.service: "ths-authentik"
|
|
||||||
|
|
||||||
# Middleware forwardAuth (para proteger otros servicios) -> usar ths-ths-authentik@docker en tus stacks THS
|
|
||||||
traefik.http.middlewares.ths-authentik.forwardauth.address: "http://ths-authentik-server:${AUTHENTIK_HTTP_PORT}/outpost.goauthentik.io/auth/traefik"
|
traefik.http.middlewares.ths-authentik.forwardauth.address: "http://ths-authentik-server:${AUTHENTIK_HTTP_PORT}/outpost.goauthentik.io/auth/traefik"
|
||||||
traefik.http.middlewares.ths-authentik.forwardauth.trustForwardHeader: "true"
|
traefik.http.middlewares.ths-authentik.forwardauth.trustForwardHeader: "true"
|
||||||
traefik.http.middlewares.ths-authentik.forwardauth.authResponseHeaders: "X-Authentik-Username,X-Authentik-Groups,X-Authentik-Email,X-Authentik-Uid,X-Authentik-Jwt"
|
traefik.http.middlewares.ths-authentik.forwardauth.authResponseHeaders: "X-Authentik-Username,X-Authentik-Groups,X-Authentik-Email,X-Authentik-Uid,X-Authentik-Jwt"
|
||||||
|
|
||||||
# OUTPOST genérico para TODO el dominio THS (subdominios + apex + www)
|
|
||||||
# ✅ Sin comas dentro de Host()
|
|
||||||
traefik.http.routers.ths-authentik-outpost.rule: "(HostRegexp(`{subdomain:[a-z0-9-]+}.thehomelesssherlock.com`) || Host(`thehomelesssherlock.com`) || Host(`www.thehomelesssherlock.com`)) && PathPrefix(`/outpost.goauthentik.io/`)"
|
|
||||||
traefik.http.routers.ths-authentik-outpost.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.ths-authentik-outpost.tls: "true"
|
|
||||||
traefik.http.routers.ths-authentik-outpost.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.ths-authentik-outpost.service: "ths-authentik"
|
|
||||||
traefik.http.routers.ths-authentik-outpost.priority: "1000"
|
|
||||||
|
|
||||||
ths-authentik-worker:
|
ths-authentik-worker:
|
||||||
image: ${AUTHENTIK_IMAGE}
|
image: ${AUTHENTIK_IMAGE}
|
||||||
container_name: ths-authentik-worker
|
container_name: ths-authentik-worker
|
||||||
@@ -109,4 +91,3 @@ networks:
|
|||||||
external: true
|
external: true
|
||||||
ths_authentik_internal:
|
ths_authentik_internal:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ AUTHENTIK_SECRET_KEY=
|
|||||||
AUTHENTIK_BOOTSTRAP_EMAIL=
|
AUTHENTIK_BOOTSTRAP_EMAIL=
|
||||||
AUTHENTIK_BOOTSTRAP_PASSWORD=
|
AUTHENTIK_BOOTSTRAP_PASSWORD=
|
||||||
AUTHENTIK_BOOTSTRAP_TOKEN=
|
AUTHENTIK_BOOTSTRAP_TOKEN=
|
||||||
AUTHENTIK_HTTP_PORT=
|
AUTHENTIK_HTTP_PORT=9000
|
||||||
|
|
||||||
##### Traefik / dominios #####
|
##### Traefik / dominios #####
|
||||||
TRAEFIK_DOCKER_NETWORK=
|
TRAEFIK_DOCKER_NETWORK=
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ services:
|
|||||||
POSTGRES_PASSWORD: ${GITEA_DB_PASSWORD}
|
POSTGRES_PASSWORD: ${GITEA_DB_PASSWORD}
|
||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
volumes:
|
volumes:
|
||||||
- ${GITEA_POSTGRES_PATH}:/var/lib/postgresql/data:Z
|
- /opt/gitea/postgres:/var/lib/postgresql/data:Z
|
||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
|
|
||||||
gitea:
|
gitea:
|
||||||
image: ${GITEA_IMAGE}
|
image: ${GITEA_IMAGE}
|
||||||
|
pull_policy: always
|
||||||
container_name: gitea
|
container_name: gitea
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -61,45 +62,14 @@ services:
|
|||||||
GITEA__ui__THEMES: ${GITEA_UI_THEMES}
|
GITEA__ui__THEMES: ${GITEA_UI_THEMES}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${GITEA_DATA_PATH}:/data:Z
|
- /opt/gitea/data:/data:Z
|
||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
# Exponer SSH (contenedor y host mismo puerto)
|
|
||||||
ports:
|
ports:
|
||||||
- "${GITEA_SSH_PORT}:${GITEA_SSH_PORT}"
|
- "${GITEA_SSH_PORT}:${GITEA_SSH_PORT}"
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
traefik.http.services.gitea.loadbalancer.server.port: "3000"
|
||||||
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
|
|
||||||
|
|
||||||
traefik.http.services.gitea.loadbalancer.server.port: "${GITEA_HTTP_PORT}"
|
|
||||||
|
|
||||||
# Router principal (sin Authentik)
|
|
||||||
traefik.http.routers.gitea-main.rule: "Host(`${GITEA_DOMAIN}`)"
|
|
||||||
traefik.http.routers.gitea-main.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.gitea-main.tls: "true"
|
|
||||||
traefik.http.routers.gitea-main.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.gitea-main.priority: "10"
|
|
||||||
|
|
||||||
# Router login + explore + perfil TheHomelessSherlock (con Authentik)
|
|
||||||
traefik.http.routers.gitea-login.rule: >-
|
|
||||||
Host(`${GITEA_DOMAIN}`) &&
|
|
||||||
(Path(`/user/login`) ||
|
|
||||||
PathPrefix(`/user/sign_up`) ||
|
|
||||||
PathPrefix(`/user/forgot_password`) ||
|
|
||||||
PathPrefix(`/user/two_factor`) ||
|
|
||||||
PathPrefix(`/login/oauth`) ||
|
|
||||||
PathPrefix(`/explore`) ||
|
|
||||||
PathPrefix(`/api`) ||
|
|
||||||
PathPrefix(`/api/swagger`) ||
|
|
||||||
PathRegexp(`^/TheHomelessSherlock/?$`))
|
|
||||||
traefik.http.routers.gitea-login.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.gitea-login.tls: "true"
|
|
||||||
traefik.http.routers.gitea-login.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.gitea-login.middlewares: "${TRAEFIK_AUTH_MIDDLEWARE}"
|
|
||||||
traefik.http.routers.gitea-login.priority: "20"
|
|
||||||
|
|
||||||
gitea-runner:
|
gitea-runner:
|
||||||
image: ${GITEA_RUNNER_IMAGE}
|
image: ${GITEA_RUNNER_IMAGE}
|
||||||
@@ -113,7 +83,7 @@ services:
|
|||||||
GITEA_RUNNER_NAME: ${GITEA_RUNNER_NAME}
|
GITEA_RUNNER_NAME: ${GITEA_RUNNER_NAME}
|
||||||
GITEA_RUNNER_LABELS: ${GITEA_RUNNER_LABELS}
|
GITEA_RUNNER_LABELS: ${GITEA_RUNNER_LABELS}
|
||||||
volumes:
|
volumes:
|
||||||
- ${GITEA_RUNNER_DATA_PATH}:/data:Z
|
- /opt/gitea/runner:/data:Z
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:Z
|
- /var/run/docker.sock:/var/run/docker.sock:Z
|
||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
@@ -123,4 +93,3 @@ networks:
|
|||||||
driver: bridge
|
driver: bridge
|
||||||
proxy:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +1,49 @@
|
|||||||
##### Postgres Gitea #####
|
##### Postgres Gitea #####
|
||||||
GITEA_POSTGRES_IMAGE=
|
GITEA_POSTGRES_IMAGE=postgres:16
|
||||||
GITEA_DB_NAME=
|
GITEA_DB_NAME=gitea
|
||||||
GITEA_DB_USER=
|
GITEA_DB_USER=gitea
|
||||||
GITEA_DB_PASSWORD=
|
GITEA_DB_PASSWORD=pon_una_pass_fuerte_aqui
|
||||||
TZ=
|
TZ=Europe/Madrid
|
||||||
GITEA_POSTGRES_PATH=
|
GITEA_POSTGRES_PATH=/opt/gitea/postgres
|
||||||
|
|
||||||
##### Gitea #####
|
##### Gitea #####
|
||||||
GITEA_IMAGE=
|
GITEA_IMAGE=gitea/gitea:latest
|
||||||
GITEA_USER_UID=
|
GITEA_USER_UID=1000
|
||||||
GITEA_USER_GID=
|
GITEA_USER_GID=1000
|
||||||
|
|
||||||
GITEA_DB_TYPE=
|
GITEA_DB_TYPE=postgres
|
||||||
GITEA_DB_HOST=
|
GITEA_DB_HOST=postgres
|
||||||
GITEA_DB_PORT=
|
GITEA_DB_PORT=5432
|
||||||
|
|
||||||
GITEA_DOMAIN=
|
GITEA_DOMAIN=gitea.thehomelesssherlock.com
|
||||||
GITEA_ROOT_URL=
|
GITEA_ROOT_URL=https://gitea.thehomelesssherlock.com/
|
||||||
GITEA_SERVER_PROTOCOL=
|
GITEA_SERVER_PROTOCOL=http
|
||||||
GITEA_HTTP_PORT=
|
GITEA_HTTP_PORT=3000
|
||||||
|
|
||||||
GITEA_SSH_DOMAIN=
|
GITEA_SSH_DOMAIN=gitea.thehomelesssherlock.com
|
||||||
GITEA_SSH_PORT=
|
GITEA_SSH_PORT=1516
|
||||||
GITEA_START_SSH_SERVER=
|
GITEA_START_SSH_SERVER=true
|
||||||
|
|
||||||
GITEA_ACTIONS_ENABLED=
|
GITEA_ACTIONS_ENABLED=true
|
||||||
GITEA_DISABLE_REGISTRATION=
|
GITEA_DISABLE_REGISTRATION=true
|
||||||
GITEA_REQUIRE_SIGNIN_VIEW=
|
GITEA_REQUIRE_SIGNIN_VIEW=false
|
||||||
GITEA_ENABLE_OPENID_SIGNUP=
|
GITEA_ENABLE_OPENID_SIGNUP=false
|
||||||
GITEA_ENABLE_OPENID_SIGNIN=
|
GITEA_ENABLE_OPENID_SIGNIN=false
|
||||||
GITEA_DISABLE_LOGIN_FORM=
|
GITEA_DISABLE_LOGIN_FORM=false
|
||||||
GITEA_HIDE_EMAIL_ADDRESS=
|
GITEA_HIDE_EMAIL_ADDRESS=true
|
||||||
GITEA_DEFAULT_ALLOW_CREATE_ORGANIZATION=
|
GITEA_DEFAULT_ALLOW_CREATE_ORGANIZATION=false
|
||||||
GITEA_DEFAULT_ORG_VISIBILITY=
|
GITEA_DEFAULT_ORG_VISIBILITY=private
|
||||||
GITEA_DEFAULT_VISIBILITY=
|
GITEA_DEFAULT_VISIBILITY=private
|
||||||
|
|
||||||
GITEA_DEFAULT_THEME=
|
GITEA_DEFAULT_THEME=gitea-dark
|
||||||
GITEA_UI_THEMES=
|
GITEA_UI_THEMES=gitea-dark
|
||||||
|
|
||||||
GITEA_DATA_PATH=
|
GITEA_DATA_PATH=/opt/gitea/data
|
||||||
|
|
||||||
##### Traefik #####
|
|
||||||
TRAEFIK_DOCKER_NETWORK=
|
|
||||||
TRAEFIK_ENTRYPOINT_SECURE=
|
|
||||||
TRAEFIK_CERTRESOLVER=
|
|
||||||
TRAEFIK_AUTH_MIDDLEWARE=
|
|
||||||
|
|
||||||
##### Runner #####
|
##### Runner #####
|
||||||
GITEA_RUNNER_IMAGE=
|
GITEA_RUNNER_IMAGE=docker.io/gitea/act_runner:latest
|
||||||
GITEA_INSTANCE_URL=
|
GITEA_INSTANCE_URL=http://gitea:3000
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN=
|
GITEA_RUNNER_REGISTRATION_TOKEN=LRex9dPrXdrEeh1tIPiaRXndu4L1o7Co9j9PSjis
|
||||||
GITEA_RUNNER_NAME=
|
GITEA_RUNNER_NAME=almasrv-runner-1
|
||||||
GITEA_RUNNER_LABELS=
|
GITEA_RUNNER_LABELS=
|
||||||
GITEA_RUNNER_DATA_PATH=
|
GITEA_RUNNER_DATA_PATH=/opt/gitea/runner
|
||||||
|
|
||||||
|
|||||||
77
karakeep/docker-compose.yml
Normal file
77
karakeep/docker-compose.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
services:
|
||||||
|
karakeep:
|
||||||
|
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION}
|
||||||
|
pull_policy: always
|
||||||
|
container_name: karakeep
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
DATA_DIR: /data
|
||||||
|
MEILI_ADDR: http://karakeep-meilisearch:7700
|
||||||
|
BROWSER_WEB_URL: http://karakeep-chrome:9222
|
||||||
|
NEXTAUTH_URL: https://${KARAKEEP_DOMAIN}
|
||||||
|
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
|
||||||
|
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
|
||||||
|
DISABLE_SIGNUPS: ${DISABLE_SIGNUPS}
|
||||||
|
OCR_LANGS: ${OCR_LANGS}
|
||||||
|
|
||||||
|
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||||
|
INFERENCE_TEXT_MODEL: ${INFERENCE_TEXT_MODEL}
|
||||||
|
INFERENCE_IMAGE_MODEL: ${INFERENCE_IMAGE_MODEL}
|
||||||
|
EMBEDDING_TEXT_MODEL: ${EMBEDDING_TEXT_MODEL}
|
||||||
|
|
||||||
|
INFERENCE_LANG: ${INFERENCE_LANG}
|
||||||
|
INFERENCE_ENABLE_AUTO_TAGGING: ${INFERENCE_ENABLE_AUTO_TAGGING}
|
||||||
|
INFERENCE_ENABLE_AUTO_SUMMARIZATION: ${INFERENCE_ENABLE_AUTO_SUMMARIZATION}
|
||||||
|
|
||||||
|
INFERENCE_CONTEXT_LENGTH: ${INFERENCE_CONTEXT_LENGTH}
|
||||||
|
INFERENCE_MAX_OUTPUT_TOKENS: ${INFERENCE_MAX_OUTPUT_TOKENS}
|
||||||
|
INFERENCE_USE_MAX_COMPLETION_TOKENS: ${INFERENCE_USE_MAX_COMPLETION_TOKENS}
|
||||||
|
|
||||||
|
INFERENCE_NUM_WORKERS: ${INFERENCE_NUM_WORKERS}
|
||||||
|
INFERENCE_JOB_TIMEOUT_SEC: ${INFERENCE_JOB_TIMEOUT_SEC}
|
||||||
|
|
||||||
|
LOG_LEVEL: ${LOG_LEVEL}
|
||||||
|
DB_WAL_MODE: ${DB_WAL_MODE}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /opt/karakeep/data:/data:Z
|
||||||
|
depends_on:
|
||||||
|
- karakeep-meilisearch
|
||||||
|
- karakeep-chrome
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
traefik.http.services.karakeep.loadbalancer.server.port: "3000"
|
||||||
|
|
||||||
|
karakeep-chrome:
|
||||||
|
image: gcr.io/zenika-hub/alpine-chrome:124
|
||||||
|
container_name: karakeep-chrome
|
||||||
|
restart: unless-stopped
|
||||||
|
command:
|
||||||
|
- --no-sandbox
|
||||||
|
- --disable-gpu
|
||||||
|
- --disable-dev-shm-usage
|
||||||
|
- --remote-debugging-address=0.0.0.0
|
||||||
|
- --remote-debugging-port=9222
|
||||||
|
- --hide-scrollbars
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
|
||||||
|
karakeep-meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.37.0
|
||||||
|
container_name: karakeep-meilisearch
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
|
||||||
|
MEILI_NO_ANALYTICS: "true"
|
||||||
|
volumes:
|
||||||
|
- /opt/karakeep/meili_data:/meili_data:Z
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
karakeep_internal:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
@@ -2,6 +2,7 @@ services:
|
|||||||
mail-relay:
|
mail-relay:
|
||||||
image: ${MAIL_RELAY_IMAGE}
|
image: ${MAIL_RELAY_IMAGE}
|
||||||
container_name: mail-relay
|
container_name: mail-relay
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
@@ -30,9 +31,9 @@ services:
|
|||||||
DKIM_SELECTOR: ${MAIL_RELAY_DKIM_SELECTOR}
|
DKIM_SELECTOR: ${MAIL_RELAY_DKIM_SELECTOR}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${MAIL_RELAY_QUEUE_PATH}:/var/spool/postfix:Z
|
- /opt/mail-relay/queue:/var/spool/postfix:Z
|
||||||
- ${MAIL_RELAY_DKIM_KEYS_PATH}:/etc/opendkim/keys:Z
|
- /opt/mail-relay/opendkim:/etc/opendkim/keys:Z
|
||||||
- ${MAIL_RELAY_PASSWORD_FILE_PATH}:/run/secrets/relayhost_password:ro,Z
|
- /opt/mail-relay/secrets/relayhost_password:/run/secrets/relayhost_password:ro,Z
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
mail_internal:
|
mail_internal:
|
||||||
|
|||||||
@@ -21,58 +21,47 @@ services:
|
|||||||
prowlarr:
|
prowlarr:
|
||||||
image: lscr.io/linuxserver/prowlarr:latest
|
image: lscr.io/linuxserver/prowlarr:latest
|
||||||
container_name: prowlarr
|
container_name: prowlarr
|
||||||
|
pull_policy: always
|
||||||
environment:
|
environment:
|
||||||
- PUID=0
|
- PUID=0
|
||||||
- PGID=0
|
- PGID=0
|
||||||
- TZ=${TZ:-Europe/Madrid}
|
- TZ=${TZ:-Europe/Madrid}
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMMON_PATH}/configs/prowlarr:/config:Z
|
- /opt/media/configs/prowlarr:/config:Z
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- media
|
- media
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- traefik.http.routers.prowlarr.rule=Host(`${PROWLARR_HOST}`)
|
|
||||||
- traefik.http.routers.prowlarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.prowlarr.tls=true
|
|
||||||
- traefik.http.routers.prowlarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.prowlarr.middlewares=ths-authentik@docker
|
|
||||||
- traefik.http.services.prowlarr.loadbalancer.server.port=9696
|
- traefik.http.services.prowlarr.loadbalancer.server.port=9696
|
||||||
|
|
||||||
jackett:
|
jackett:
|
||||||
image: lscr.io/linuxserver/jackett:latest
|
image: lscr.io/linuxserver/jackett:latest
|
||||||
container_name: jackett
|
container_name: jackett
|
||||||
|
pull_policy: always
|
||||||
environment:
|
environment:
|
||||||
- PUID=0
|
- PUID=0
|
||||||
- PGID=0
|
- PGID=0
|
||||||
- TZ=${TZ:-Europe/Madrid}
|
- TZ=${TZ:-Europe/Madrid}
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMMON_PATH}/configs/jackett:/config:Z
|
- /opt/media/configs/jackett:/config:Z
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- media
|
- media
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- traefik.http.routers.jackett.rule=Host(`${JACKETT_HOST}`)
|
|
||||||
- traefik.http.routers.jackett.entrypoints=websecure
|
|
||||||
- traefik.http.routers.jackett.tls=true
|
|
||||||
- traefik.http.routers.jackett.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.jackett.middlewares=ths-authentik@docker
|
|
||||||
- traefik.http.services.jackett.loadbalancer.server.port=9117
|
- traefik.http.services.jackett.loadbalancer.server.port=9117
|
||||||
|
|
||||||
sonarr:
|
sonarr:
|
||||||
image: lscr.io/linuxserver/sonarr:latest
|
image: lscr.io/linuxserver/sonarr:latest
|
||||||
container_name: sonarr
|
container_name: sonarr
|
||||||
|
pull_policy: always
|
||||||
environment:
|
environment:
|
||||||
- PUID=0
|
- PUID=0
|
||||||
- PGID=0
|
- PGID=0
|
||||||
- TZ=${TZ:-Europe/Madrid}
|
- TZ=${TZ:-Europe/Madrid}
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMMON_PATH}/configs/sonarr:/config:Z
|
- /opt/media/configs/sonarr:/config:Z
|
||||||
- /mnt/media/tv:/tv
|
- /mnt/media/tv:/tv
|
||||||
- /mnt/media/downloads:/downloads
|
- /mnt/media/downloads:/downloads
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -80,24 +69,18 @@ services:
|
|||||||
- media
|
- media
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- traefik.http.routers.sonarr.rule=Host(`${SONARR_HOST}`)
|
|
||||||
- traefik.http.routers.sonarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.sonarr.tls=true
|
|
||||||
- traefik.http.routers.sonarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.sonarr.middlewares=ths-authentik@docker
|
|
||||||
- traefik.http.services.sonarr.loadbalancer.server.port=8989
|
- traefik.http.services.sonarr.loadbalancer.server.port=8989
|
||||||
|
|
||||||
radarr:
|
radarr:
|
||||||
image: lscr.io/linuxserver/radarr:latest
|
image: lscr.io/linuxserver/radarr:latest
|
||||||
container_name: radarr
|
container_name: radarr
|
||||||
|
pull_policy: always
|
||||||
environment:
|
environment:
|
||||||
- PUID=0
|
- PUID=0
|
||||||
- PGID=0
|
- PGID=0
|
||||||
- TZ=${TZ:-Europe/Madrid}
|
- TZ=${TZ:-Europe/Madrid}
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMMON_PATH}/configs/radarr:/config:Z
|
- /opt/media/configs/radarr:/config:Z
|
||||||
- /mnt/media/movies:/movies
|
- /mnt/media/movies:/movies
|
||||||
- /mnt/media/downloads:/downloads
|
- /mnt/media/downloads:/downloads
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -105,48 +88,36 @@ services:
|
|||||||
- media
|
- media
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- traefik.http.routers.radarr.rule=Host(`${RADARR_HOST}`)
|
|
||||||
- traefik.http.routers.radarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.radarr.tls=true
|
|
||||||
- traefik.http.routers.radarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.radarr.middlewares=ths-authentik@docker
|
|
||||||
- traefik.http.services.radarr.loadbalancer.server.port=7878
|
- traefik.http.services.radarr.loadbalancer.server.port=7878
|
||||||
|
|
||||||
jellyseerr:
|
jellyseerr:
|
||||||
image: fallenbagel/jellyseerr:latest
|
image: fallenbagel/jellyseerr:latest
|
||||||
container_name: jellyseerr
|
container_name: jellyseerr
|
||||||
|
pull_policy: always
|
||||||
environment:
|
environment:
|
||||||
- LOG_LEVEL=debug
|
- LOG_LEVEL=debug
|
||||||
- TZ=${TZ:-Europe/Madrid}
|
- TZ=${TZ:-Europe/Madrid}
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMMON_PATH}/configs/jellyseerr:/app/config:Z
|
- /opt/media/configs/jellyseerr:/app/config:Z
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- media
|
- media
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- traefik.http.routers.jellyseerr.rule=Host(`${JELLYSEERR_HOST}`)
|
|
||||||
- traefik.http.routers.jellyseerr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.jellyseerr.tls=true
|
|
||||||
- traefik.http.routers.jellyseerr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.jellyseerr.middlewares=ths-authentik@docker
|
|
||||||
- traefik.http.services.jellyseerr.loadbalancer.server.port=5055
|
- traefik.http.services.jellyseerr.loadbalancer.server.port=5055
|
||||||
|
|
||||||
# Opcional: Jellyfin en VPS (sin GPU)
|
# Opcional: Jellyfin en VPS (sin GPU)
|
||||||
jellyfin:
|
jellyfin:
|
||||||
image: lscr.io/linuxserver/jellyfin:latest
|
image: lscr.io/linuxserver/jellyfin:latest
|
||||||
container_name: jellyfin-vps
|
container_name: jellyfin-vps
|
||||||
|
pull_policy: always
|
||||||
environment:
|
environment:
|
||||||
- PUID=0
|
- PUID=0
|
||||||
- PGID=0
|
- PGID=0
|
||||||
- TZ=${TZ:-Europe/Madrid}
|
- TZ=${TZ:-Europe/Madrid}
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMMON_PATH}/configs/jellyfin-vps:/config:Z
|
- /opt/media/configs/jellyfin-vps:/config:Z
|
||||||
- ${COMMON_PATH}/jellyfin/cache-vps:/cache:Z
|
- /opt/media/jellyfin/cache-vps:/cache:Z
|
||||||
- /mnt/media/tv:/data/tvshows
|
- /mnt/media/tv:/data/tvshows
|
||||||
- /mnt/media/movies:/data/movies
|
- /mnt/media/movies:/data/movies
|
||||||
- /mnt/media/downloads:/data/media_downloads
|
- /mnt/media/downloads:/data/media_downloads
|
||||||
@@ -155,12 +126,4 @@ services:
|
|||||||
- media
|
- media
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
- traefik.http.routers.jellyfin.rule=Host(`${JELLYFIN_HOST}`)
|
|
||||||
- traefik.http.routers.jellyfin.entrypoints=websecure
|
|
||||||
- traefik.http.routers.jellyfin.tls=true
|
|
||||||
- traefik.http.routers.jellyfin.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.jellyfin.middlewares=ths-authentik@docker
|
|
||||||
- traefik.http.services.jellyfin.loadbalancer.server.port=8096
|
- traefik.http.services.jellyfin.loadbalancer.server.port=8096
|
||||||
|
|
||||||
|
|||||||
48
memos/docker-compose.yml
Normal file
48
memos/docker-compose.yml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
services:
|
||||||
|
memos-db:
|
||||||
|
image: postgres:17-alpine
|
||||||
|
container_name: memos-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
POSTGRES_DB: ${MEMOS_DB_NAME}
|
||||||
|
POSTGRES_USER: ${MEMOS_DB_USER}
|
||||||
|
POSTGRES_PASSWORD: ${MEMOS_DB_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- /opt/memos/postgres:/var/lib/postgresql/data:Z
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${MEMOS_DB_USER} -d ${MEMOS_DB_NAME}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 20s
|
||||||
|
networks:
|
||||||
|
- memos_internal
|
||||||
|
|
||||||
|
memos:
|
||||||
|
image: neosmemo/memos:stable
|
||||||
|
pull_policy: always
|
||||||
|
container_name: memos
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
memos-db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
MEMOS_PORT: 5230
|
||||||
|
MEMOS_DATA: /var/opt/memos
|
||||||
|
MEMOS_DRIVER: postgres
|
||||||
|
MEMOS_DSN: postgresql://${MEMOS_DB_USER}:${MEMOS_DB_PASSWORD}@memos-db:5432/${MEMOS_DB_NAME}?sslmode=disable
|
||||||
|
MEMOS_INSTANCE_URL: https://${MEMOS_DOMAIN}
|
||||||
|
volumes:
|
||||||
|
- /opt/memos/data:/var/opt/memos:Z
|
||||||
|
networks:
|
||||||
|
- memos_internal
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
traefik.http.services.memos.loadbalancer.server.port: "5230"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
memos_internal:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
5
memos/stack.env
Normal file
5
memos/stack.env
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
TZ=Europe/Madrid
|
||||||
|
MEMOS_DOMAIN=memos.sherlockhomeless.net
|
||||||
|
MEMOS_DB_NAME=memos
|
||||||
|
MEMOS_DB_USER=memos
|
||||||
|
MEMOS_DB_PASSWORD=CAMBIAME_db_super_largo_y_unico
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
n8n:
|
n8n:
|
||||||
image: n8nio/n8n:latest
|
image: n8nio/n8n:latest
|
||||||
|
pull_policy: always
|
||||||
container_name: n8n
|
container_name: n8n
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -11,10 +12,10 @@ services:
|
|||||||
DB_POSTGRESDB_USER: ${N8N_DB_USER}
|
DB_POSTGRESDB_USER: ${N8N_DB_USER}
|
||||||
DB_POSTGRESDB_PASSWORD: ${N8N_DB_PASSWORD}
|
DB_POSTGRESDB_PASSWORD: ${N8N_DB_PASSWORD}
|
||||||
|
|
||||||
N8N_HOST: ${N8N_HOST}
|
N8N_HOST: ${SERVICE_FQDN_N8N}
|
||||||
N8N_PORT: ${N8N_PORT}
|
N8N_PORT: ${N8N_PORT}
|
||||||
N8N_PROTOCOL: ${N8N_PROTOCOL}
|
N8N_PROTOCOL: ${N8N_PROTOCOL}
|
||||||
WEBHOOK_URL: ${N8N_WEBHOOK_URL}
|
WEBHOOK_URL: https://${SERVICE_FQDN_N8N}/
|
||||||
|
|
||||||
GENERIC_TIMEZONE: ${N8N_TIMEZONE}
|
GENERIC_TIMEZONE: ${N8N_TIMEZONE}
|
||||||
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
|
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
|
||||||
@@ -22,7 +23,6 @@ services:
|
|||||||
NODE_ENV: ${N8N_NODE_ENV}
|
NODE_ENV: ${N8N_NODE_ENV}
|
||||||
N8N_DIAGNOSTICS_ENABLED: ${N8N_DIAGNOSTICS_ENABLED}
|
N8N_DIAGNOSTICS_ENABLED: ${N8N_DIAGNOSTICS_ENABLED}
|
||||||
|
|
||||||
# Correo saliente
|
|
||||||
N8N_EMAIL_MODE: ${N8N_EMAIL_MODE}
|
N8N_EMAIL_MODE: ${N8N_EMAIL_MODE}
|
||||||
N8N_SMTP_HOST: ${N8N_SMTP_HOST}
|
N8N_SMTP_HOST: ${N8N_SMTP_HOST}
|
||||||
N8N_SMTP_PORT: ${N8N_SMTP_PORT}
|
N8N_SMTP_PORT: ${N8N_SMTP_PORT}
|
||||||
@@ -32,37 +32,18 @@ services:
|
|||||||
N8N_SMTP_SSL: ${N8N_SMTP_SSL}
|
N8N_SMTP_SSL: ${N8N_SMTP_SSL}
|
||||||
N8N_SMTP_STARTTLS: ${N8N_SMTP_STARTTLS}
|
N8N_SMTP_STARTTLS: ${N8N_SMTP_STARTTLS}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /opt/n8n/data:/home/node/.n8n:Z
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
|
||||||
- n8n
|
- n8n
|
||||||
- mail_internal
|
- proxy
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
traefik.http.services.n8n.loadbalancer.server.port: "5678"
|
||||||
traefik.docker.network: "proxy"
|
|
||||||
|
|
||||||
# UI (protegida por Authentik)
|
|
||||||
traefik.http.routers.n8n-ui.rule: "Host(`${N8N_DOMAIN}`)"
|
|
||||||
traefik.http.routers.n8n-ui.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.n8n-ui.tls: "true"
|
|
||||||
traefik.http.routers.n8n-ui.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.n8n-ui.service: "n8n"
|
|
||||||
traefik.http.routers.n8n-ui.priority: "10"
|
|
||||||
# traefik.http.routers.n8n-ui.middlewares: "${TRAEFIK_AUTH_MIDDLEWARE}"
|
|
||||||
|
|
||||||
# Webhooks (NO protegidos, para que terceros puedan llamar)
|
|
||||||
traefik.http.routers.n8n-webhook.rule: "Host(`${N8N_DOMAIN}`) && (PathPrefix(`/webhook`) || PathPrefix(`/webhook-test`))"
|
|
||||||
traefik.http.routers.n8n-webhook.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.n8n-webhook.tls: "true"
|
|
||||||
traefik.http.routers.n8n-webhook.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.n8n-webhook.service: "n8n"
|
|
||||||
traefik.http.routers.n8n-webhook.priority: "20"
|
|
||||||
|
|
||||||
# Puerto interno de n8n
|
|
||||||
traefik.http.services.n8n.loadbalancer.server.port: "${N8N_PORT}"
|
|
||||||
|
|
||||||
n8n-db:
|
n8n-db:
|
||||||
image: postgres:16
|
image: postgres:16
|
||||||
|
pull_policy: always
|
||||||
container_name: n8n-pg
|
container_name: n8n-pg
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -70,16 +51,12 @@ services:
|
|||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
POSTGRES_DB: ${POSTGRES_DB}
|
||||||
volumes:
|
volumes:
|
||||||
- ${N8N_DB_DATA_PATH}:/var/lib/postgresql/data:Z
|
- /opt/n8n/postgres:/var/lib/postgresql/data:Z
|
||||||
networks:
|
networks:
|
||||||
- n8n
|
- n8n
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
proxy:
|
|
||||||
external: true
|
|
||||||
# authentik_internal:
|
|
||||||
# driver: bridge
|
|
||||||
n8n:
|
n8n:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
mail_internal:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
##### n8n - Base de datos #####
|
##### n8n - Base de datos #####
|
||||||
N8N_DB_TYPE=
|
N8N_DB_TYPE=postgresdb
|
||||||
N8N_DB_HOST=
|
N8N_DB_HOST=n8n-db
|
||||||
N8N_DB_PORT=
|
N8N_DB_PORT=5432
|
||||||
N8N_DB_NAME=
|
N8N_DB_NAME=n8n
|
||||||
N8N_DB_USER=
|
N8N_DB_USER=n8n
|
||||||
N8N_DB_PASSWORD=
|
N8N_DB_PASSWORD=
|
||||||
|
|
||||||
##### n8n - Servidor / dominio #####
|
##### n8n - Servidor / dominio #####
|
||||||
N8N_HOST=
|
N8N_HOST=
|
||||||
N8N_PORT=
|
N8N_PORT=5678
|
||||||
N8N_PROTOCOL=
|
N8N_PROTOCOL=https
|
||||||
N8N_WEBHOOK_URL=
|
N8N_WEBHOOK_URL=
|
||||||
|
|
||||||
N8N_TIMEZONE=
|
N8N_TIMEZONE=Europe/Madrid
|
||||||
|
|
||||||
# Genera una nueva con: openssl rand -hex 32
|
# Genera una nueva con: openssl rand -hex 32
|
||||||
N8N_ENCRYPTION_KEY=
|
N8N_ENCRYPTION_KEY=
|
||||||
|
|
||||||
N8N_NODE_ENV=
|
N8N_NODE_ENV=production
|
||||||
N8N_DIAGNOSTICS_ENABLED=
|
N8N_DIAGNOSTICS_ENABLED=false
|
||||||
|
|
||||||
##### n8n - Correo (via mail-relay interno) #####
|
##### n8n - Correo (SMTP) #####
|
||||||
N8N_EMAIL_MODE=smtp
|
N8N_EMAIL_MODE=smtp
|
||||||
N8N_SMTP_HOST=mail-relay
|
N8N_SMTP_HOST=
|
||||||
N8N_SMTP_PORT=587
|
N8N_SMTP_PORT=587
|
||||||
N8N_SMTP_USER=
|
N8N_SMTP_USER=
|
||||||
N8N_SMTP_PASS=
|
N8N_SMTP_PASS=
|
||||||
@@ -31,15 +31,9 @@ N8N_SMTP_SSL=false
|
|||||||
N8N_SMTP_STARTTLS=false
|
N8N_SMTP_STARTTLS=false
|
||||||
|
|
||||||
##### PostgreSQL interno #####
|
##### PostgreSQL interno #####
|
||||||
POSTGRES_USER=
|
POSTGRES_USER=n8n
|
||||||
POSTGRES_PASSWORD=
|
POSTGRES_PASSWORD=
|
||||||
POSTGRES_DB=
|
POSTGRES_DB=n8n
|
||||||
|
|
||||||
# Ruta en el host para los datos de Postgres (relativa o absoluta)
|
# Ruta en el host para los datos de Postgres
|
||||||
N8N_DB_DATA_PATH=
|
N8N_DB_DATA_PATH=/opt/n8n/postgres
|
||||||
|
|
||||||
##### Traefik #####
|
|
||||||
N8N_DOMAIN=
|
|
||||||
TRAEFIK_ENTRYPOINT_SECURE=
|
|
||||||
TRAEFIK_CERTRESOLVER=
|
|
||||||
TRAEFIK_AUTH_MIDDLEWARE=
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ services:
|
|||||||
nextcloud:
|
nextcloud:
|
||||||
image: nextcloud:33-apache
|
image: nextcloud:33-apache
|
||||||
container_name: nextcloud
|
container_name: nextcloud
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- nextcloud-db
|
- nextcloud-db
|
||||||
@@ -79,15 +80,6 @@ services:
|
|||||||
- proxy
|
- proxy
|
||||||
- mail_internal
|
- mail_internal
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
|
|
||||||
- traefik.http.routers.nextcloud.rule=Host(`${NC_DOMAIN}`)
|
|
||||||
- traefik.http.routers.nextcloud.entrypoints=websecure
|
|
||||||
- traefik.http.routers.nextcloud.tls=true
|
|
||||||
- traefik.http.routers.nextcloud.tls.certresolver=${TRAEFIK_CERTRESOLVER}
|
|
||||||
- traefik.http.routers.nextcloud.middlewares=nc-dav,nc-secure-headers
|
|
||||||
|
|
||||||
- traefik.http.middlewares.nc-dav.redirectregex.permanent=true
|
- traefik.http.middlewares.nc-dav.redirectregex.permanent=true
|
||||||
- traefik.http.middlewares.nc-dav.redirectregex.regex=https://(.*)/.well-known/(?:card|cal)dav
|
- traefik.http.middlewares.nc-dav.redirectregex.regex=https://(.*)/.well-known/(?:card|cal)dav
|
||||||
- traefik.http.middlewares.nc-dav.redirectregex.replacement=https://$${1}/remote.php/dav
|
- traefik.http.middlewares.nc-dav.redirectregex.replacement=https://$${1}/remote.php/dav
|
||||||
@@ -156,22 +148,13 @@ services:
|
|||||||
- nextcloud_internal
|
- nextcloud_internal
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
|
|
||||||
- traefik.http.routers.onlyoffice.rule=Host(`${OO_DOMAIN}`)
|
|
||||||
- traefik.http.routers.onlyoffice.entrypoints=websecure
|
|
||||||
- traefik.http.routers.onlyoffice.tls=true
|
|
||||||
- traefik.http.routers.onlyoffice.tls.certresolver=${TRAEFIK_CERTRESOLVER}
|
|
||||||
- traefik.http.routers.onlyoffice.middlewares=oo-secure-headers,oo-forwarded
|
|
||||||
|
|
||||||
- traefik.http.middlewares.oo-secure-headers.headers.stsSeconds=31536000
|
- traefik.http.middlewares.oo-secure-headers.headers.stsSeconds=31536000
|
||||||
- traefik.http.middlewares.oo-secure-headers.headers.stsIncludeSubdomains=true
|
- traefik.http.middlewares.oo-secure-headers.headers.stsIncludeSubdomains=true
|
||||||
- traefik.http.middlewares.oo-secure-headers.headers.stsPreload=true
|
- traefik.http.middlewares.oo-secure-headers.headers.stsPreload=true
|
||||||
- traefik.http.middlewares.oo-secure-headers.headers.contentTypeNosniff=true
|
- traefik.http.middlewares.oo-secure-headers.headers.contentTypeNosniff=true
|
||||||
|
|
||||||
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Proto=https
|
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Proto=https
|
||||||
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Host=${OO_DOMAIN}
|
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Host=onlyoffice.sherlockhomeless.net
|
||||||
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Port=443
|
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Port=443
|
||||||
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Ssl=on
|
- traefik.http.middlewares.oo-forwarded.headers.customRequestHeaders.X-Forwarded-Ssl=on
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
TZ=Europe/Madrid
|
TZ=Europe/Madrid
|
||||||
NC_DOMAIN=nextcloud.example.com
|
NC_DOMAIN=nextcloud.sherlockhomeless.net
|
||||||
OO_DOMAIN=onlyoffice.example.com
|
OO_DOMAIN=onlyoffice.sherlockhomeless.net
|
||||||
TRAEFIK_CERTRESOLVER=letsencrypt
|
TRAEFIK_CERTRESOLVER=letsencrypt
|
||||||
TRUSTED_PROXIES=10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
|
TRUSTED_PROXIES=10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
|
||||||
MYSQL_ROOT_PASSWORD=change_me_mysql_root_password_long_and_secure
|
MYSQL_ROOT_PASSWORD=change_me_mysql_root_password_long_and_secure
|
||||||
@@ -17,5 +17,5 @@ SMTP_SECURE=tls
|
|||||||
SMTP_AUTHTYPE=
|
SMTP_AUTHTYPE=
|
||||||
SMTP_NAME=
|
SMTP_NAME=
|
||||||
SMTP_PASSWORD=
|
SMTP_PASSWORD=
|
||||||
MAIL_FROM_ADDRESS=nextcloud
|
MAIL_FROM_ADDRESS=nextcloud@thehomelesssherlock.com
|
||||||
MAIL_DOMAIN=example.com
|
MAIL_DOMAIN=thehomelesssherlock.com
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ services:
|
|||||||
paperless:
|
paperless:
|
||||||
image: ghcr.io/paperless-ngx/paperless-ngx:latest
|
image: ghcr.io/paperless-ngx/paperless-ngx:latest
|
||||||
container_name: paperless
|
container_name: paperless
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- paperless-db
|
- paperless-db
|
||||||
@@ -85,15 +86,6 @@ services:
|
|||||||
- proxy
|
- proxy
|
||||||
- mail_internal
|
- mail_internal
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
|
|
||||||
- traefik.http.routers.paperless.rule=Host(`${PAPERLESS_DOMAIN}`)
|
|
||||||
- traefik.http.routers.paperless.entrypoints=websecure
|
|
||||||
- traefik.http.routers.paperless.tls=true
|
|
||||||
- traefik.http.routers.paperless.tls.certresolver=${TRAEFIK_CERTRESOLVER}
|
|
||||||
- traefik.http.routers.paperless.middlewares=paperless-secure-headers
|
|
||||||
|
|
||||||
- traefik.http.middlewares.paperless-secure-headers.headers.stsSeconds=31536000
|
- traefik.http.middlewares.paperless-secure-headers.headers.stsSeconds=31536000
|
||||||
- traefik.http.middlewares.paperless-secure-headers.headers.stsIncludeSubdomains=true
|
- traefik.http.middlewares.paperless-secure-headers.headers.stsIncludeSubdomains=true
|
||||||
- traefik.http.middlewares.paperless-secure-headers.headers.stsPreload=true
|
- traefik.http.middlewares.paperless-secure-headers.headers.stsPreload=true
|
||||||
@@ -105,6 +97,7 @@ services:
|
|||||||
paperless-ai:
|
paperless-ai:
|
||||||
image: clusterzx/paperless-ai:latest
|
image: clusterzx/paperless-ai:latest
|
||||||
container_name: paperless-ai
|
container_name: paperless-ai
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- paperless
|
- paperless
|
||||||
@@ -116,15 +109,6 @@ services:
|
|||||||
- paperless_internal
|
- paperless_internal
|
||||||
- proxy
|
- proxy
|
||||||
labels:
|
labels:
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.docker.network=proxy
|
|
||||||
|
|
||||||
- traefik.http.routers.paperless-ai.rule=Host(`${PAPERLESS_AI_DOMAIN}`)
|
|
||||||
- traefik.http.routers.paperless-ai.entrypoints=websecure
|
|
||||||
- traefik.http.routers.paperless-ai.tls=true
|
|
||||||
- traefik.http.routers.paperless-ai.tls.certresolver=${TRAEFIK_CERTRESOLVER}
|
|
||||||
- traefik.http.routers.paperless-ai.middlewares=paperless-ai-secure-headers
|
|
||||||
|
|
||||||
- traefik.http.middlewares.paperless-ai-secure-headers.headers.stsSeconds=31536000
|
- traefik.http.middlewares.paperless-ai-secure-headers.headers.stsSeconds=31536000
|
||||||
- traefik.http.middlewares.paperless-ai-secure-headers.headers.stsIncludeSubdomains=true
|
- traefik.http.middlewares.paperless-ai-secure-headers.headers.stsIncludeSubdomains=true
|
||||||
- traefik.http.middlewares.paperless-ai-secure-headers.headers.stsPreload=true
|
- traefik.http.middlewares.paperless-ai-secure-headers.headers.stsPreload=true
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ services:
|
|||||||
trilium:
|
trilium:
|
||||||
image: ${TRILIUM_IMAGE}
|
image: ${TRILIUM_IMAGE}
|
||||||
container_name: trilium
|
container_name: trilium
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
hostname: ${TRILIUM_HOSTNAME}
|
hostname: ${TRILIUM_HOSTNAME}
|
||||||
|
|
||||||
@@ -9,36 +10,16 @@ services:
|
|||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${TRILIUM_DATA_PATH}:/home/node/trilium-data:Z
|
- /opt/trilium/data:/home/node/trilium-data:Z
|
||||||
|
|
||||||
expose:
|
expose:
|
||||||
- "${TRILIUM_HTTP_PORT}"
|
- "8080"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
traefik.http.services.trilium.loadbalancer.server.port: "8080"
|
||||||
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
|
|
||||||
|
|
||||||
# Router HTTPS - dominio principal
|
|
||||||
traefik.http.routers.trilium.rule: "Host(`${TRILIUM_DOMAIN_1}`)"
|
|
||||||
traefik.http.routers.trilium.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.trilium.tls: "true"
|
|
||||||
traefik.http.routers.trilium.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
|
|
||||||
# Router HTTPS - dominio secundario (sin redirección)
|
|
||||||
traefik.http.routers.trilium-alt.rule: "Host(`${TRILIUM_DOMAIN_2}`)"
|
|
||||||
traefik.http.routers.trilium-alt.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.trilium-alt.tls: "true"
|
|
||||||
traefik.http.routers.trilium-alt.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
traefik.http.routers.trilium-alt.service: "trilium@docker"
|
|
||||||
|
|
||||||
# Servicio interno
|
|
||||||
traefik.http.services.trilium.loadbalancer.server.port: "${TRILIUM_HTTP_PORT}"
|
|
||||||
|
|
||||||
# Middleware solo de headers (sin Authentik)
|
|
||||||
traefik.http.routers.trilium.middlewares: "trilium-sec@docker"
|
|
||||||
|
|
||||||
traefik.http.middlewares.trilium-sec.headers.stsSeconds: "31536000"
|
traefik.http.middlewares.trilium-sec.headers.stsSeconds: "31536000"
|
||||||
traefik.http.middlewares.trilium-sec.headers.stsIncludeSubdomains: "true"
|
traefik.http.middlewares.trilium-sec.headers.stsIncludeSubdomains: "true"
|
||||||
@@ -49,4 +30,3 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
proxy:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ TRILIUM_IMAGE=
|
|||||||
TRILIUM_HOSTNAME=
|
TRILIUM_HOSTNAME=
|
||||||
TZ=
|
TZ=
|
||||||
TRILIUM_DATA_PATH=
|
TRILIUM_DATA_PATH=
|
||||||
TRILIUM_HTTP_PORT=
|
TRILIUM_HTTP_PORT=8080
|
||||||
|
|
||||||
##### Traefik / dominios #####
|
##### Traefik / dominios #####
|
||||||
TRAEFIK_DOCKER_NETWORK=
|
TRAEFIK_DOCKER_NETWORK=
|
||||||
|
|||||||
57
vikunja/docker-compose.yml
Normal file
57
vikunja/docker-compose.yml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
services:
|
||||||
|
vikunja-db:
|
||||||
|
image: postgres:17-alpine
|
||||||
|
container_name: vikunja-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
POSTGRES_DB: ${VIKUNJA_DB_NAME}
|
||||||
|
POSTGRES_USER: ${VIKUNJA_DB_USER}
|
||||||
|
POSTGRES_PASSWORD: ${VIKUNJA_DB_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- /opt/vikunja/postgres:/var/lib/postgresql/data:Z
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${VIKUNJA_DB_USER} -d ${VIKUNJA_DB_NAME}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 20s
|
||||||
|
networks:
|
||||||
|
- vikunja_internal
|
||||||
|
|
||||||
|
vikunja:
|
||||||
|
image: vikunja/vikunja:latest
|
||||||
|
pull_policy: always
|
||||||
|
container_name: vikunja
|
||||||
|
restart: unless-stopped
|
||||||
|
user: "1000:1000"
|
||||||
|
depends_on:
|
||||||
|
vikunja-db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
VIKUNJA_SERVICE_PUBLICURL: https://${VIKUNJA_DOMAIN}/
|
||||||
|
VIKUNJA_SERVICE_JWTSECRET: ${VIKUNJA_JWT_SECRET}
|
||||||
|
VIKUNJA_DATABASE_TYPE: postgres
|
||||||
|
VIKUNJA_DATABASE_HOST: vikunja-db
|
||||||
|
VIKUNJA_DATABASE_PORT: 5432
|
||||||
|
VIKUNJA_DATABASE_DATABASE: ${VIKUNJA_DB_NAME}
|
||||||
|
VIKUNJA_DATABASE_USER: ${VIKUNJA_DB_USER}
|
||||||
|
VIKUNJA_DATABASE_PASSWORD: ${VIKUNJA_DB_PASSWORD}
|
||||||
|
VIKUNJA_SERVICE_ENABLECALDAV: "true"
|
||||||
|
VIKUNJA_MAILER_ENABLED: "false"
|
||||||
|
VIKUNJA_SERVICE_ENABLEEMAILREMINDERS: "false"
|
||||||
|
VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
|
||||||
|
volumes:
|
||||||
|
- /opt/vikunja/files:/app/vikunja/files:Z
|
||||||
|
networks:
|
||||||
|
- vikunja_internal
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
traefik.http.services.vikunja.loadbalancer.server.port: "3456"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
vikunja_internal:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
6
vikunja/stack.env
Normal file
6
vikunja/stack.env
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
TZ=Europe/Madrid
|
||||||
|
VIKUNJA_DOMAIN=vikunja.sherlockhomeless.net
|
||||||
|
VIKUNJA_DB_NAME=vikunja
|
||||||
|
VIKUNJA_DB_USER=vikunja
|
||||||
|
VIKUNJA_DB_PASSWORD=CAMBIAME_db_super_largo_y_unico
|
||||||
|
VIKUNJA_JWT_SECRET=CAMBIAME_jwt_super_largo_y_unico_y_muy_largo
|
||||||
@@ -2,6 +2,7 @@ services:
|
|||||||
wg-easy:
|
wg-easy:
|
||||||
image: ${WG_EASY_IMAGE}
|
image: ${WG_EASY_IMAGE}
|
||||||
container_name: wg-easy
|
container_name: wg-easy
|
||||||
|
pull_policy: always
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
cap_add:
|
cap_add:
|
||||||
@@ -16,40 +17,25 @@ services:
|
|||||||
WG_HOST: ${WG_HOST}
|
WG_HOST: ${WG_HOST}
|
||||||
WG_PORT: ${WG_PORT}
|
WG_PORT: ${WG_PORT}
|
||||||
PORT: ${WG_UI_PORT}
|
PORT: ${WG_UI_PORT}
|
||||||
|
|
||||||
# Arranque desatendido (solo si el volumen está vacío)
|
|
||||||
INIT_ENABLED: ${INIT_ENABLED}
|
INIT_ENABLED: ${INIT_ENABLED}
|
||||||
INIT_USERNAME: ${INIT_USERNAME}
|
INIT_USERNAME: ${INIT_USERNAME}
|
||||||
INIT_PASSWORD: ${INIT_PASSWORD}
|
INIT_PASSWORD: ${INIT_PASSWORD}
|
||||||
|
|
||||||
# Evita reglas ip6tables (tabla nat inexistente en el host)
|
|
||||||
DISABLE_IPV6: ${DISABLE_IPV6}
|
DISABLE_IPV6: ${DISABLE_IPV6}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${WG_DATA_PATH}:/etc/wireguard:Z
|
- /opt/wg-easy:/etc/wireguard:Z
|
||||||
- ${WG_MODULES_PATH}:/lib/modules:ro,Z
|
- /lib/modules:/lib/modules:ro,Z
|
||||||
|
|
||||||
# Puerto UDP de WireGuard expuesto al mundo
|
|
||||||
ports:
|
ports:
|
||||||
- "${WG_UDP_PORT}:${WG_PORT}/udp"
|
- "${WG_UDP_PORT}:${WG_PORT}/udp"
|
||||||
|
- "${TORRENT_PORT}:${TORRENT_PORT}/tcp"
|
||||||
|
- "${TORRENT_PORT}:${TORRENT_PORT}/udp"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
traefik.http.services.wg.loadbalancer.server.port: "51821"
|
||||||
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
|
|
||||||
|
|
||||||
# Router HTTPS para la UI de wg-easy
|
|
||||||
traefik.http.routers.wg.rule: "Host(`${WG_DOMAIN}`)"
|
|
||||||
traefik.http.routers.wg.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
|
|
||||||
traefik.http.routers.wg.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
|
|
||||||
|
|
||||||
# Servicio apuntando al puerto HTTP interno de la UI
|
|
||||||
traefik.http.services.wg.loadbalancer.server.port: "${WG_UI_PORT}"
|
|
||||||
|
|
||||||
# Proteger la UI con Authentik (middleware definido en authentik-server)
|
|
||||||
traefik.http.routers.wg.middlewares: "${TRAEFIK_AUTH_MIDDLEWARE}"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
proxy:
|
proxy:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
WG_EASY_IMAGE=
|
WG_EASY_IMAGE=
|
||||||
WG_HOST=
|
WG_HOST=
|
||||||
WG_PORT=
|
WG_PORT=
|
||||||
WG_UI_PORT=
|
WG_UI_PORT=51821
|
||||||
|
|
||||||
INIT_ENABLED=
|
INIT_ENABLED=
|
||||||
INIT_USERNAME=
|
INIT_USERNAME=
|
||||||
|
|||||||
Reference in New Issue
Block a user