feat: add HTTP auth and Sablier scale-to-zero to VERT stack
Added authentication and scale-to-zero capabilities to VERT file converter service: **Authentication**: - Added HTTP Basic Auth middleware using VERT_AUTH_USERS - Auth middleware applied to web-secure router - Credentials configured via .env file (htpasswd format) **Sablier Scale-to-Zero**: - Added sablier.enable and sablier.group labels - Created proxy/dynamic/vert-sablier.yaml with Sablier middleware config - 1-hour session duration before automatic scale-down - Ghost theme with custom display name - Middleware chain: sablier-vert@file → auth → compress **Configuration Updates**: - Added VERT_SABLIER_ENABLED to arty.yml (default: true) - Updated CLAUDE.md with auth and Sablier documentation - Middleware order ensures Sablier wakes container before auth check Infrastructure: - Follows same pattern as Scrapy service for auth - Dynamic Traefik configuration for Sablier plugin - Container name: vert_app (referenced in Sablier config) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -256,11 +256,16 @@ VERT universal file format converter:
|
|||||||
- No file size limits
|
- No file size limits
|
||||||
- Privacy-focused: all conversions happen in the browser
|
- Privacy-focused: all conversions happen in the browser
|
||||||
- No persistent data storage required
|
- No persistent data storage required
|
||||||
|
- Protected by HTTP Basic Auth (credentials in `.env`)
|
||||||
|
- Scale-to-zero enabled via Sablier (configurable via `VERT_SABLIER_ENABLED`)
|
||||||
|
- 1-hour session duration before automatic scale-down
|
||||||
|
|
||||||
**Configuration**:
|
**Configuration**:
|
||||||
- **PUB_HOSTNAME**: `vert.pivoine.art` (for proper URL generation)
|
- **PUB_HOSTNAME**: `vert.pivoine.art` (public hostname)
|
||||||
- **PUB_ENV**: `production`
|
- **PUB_ENV**: `production` (environment mode)
|
||||||
- **PUB_DISABLE_ALL_EXTERNAL_REQUESTS**: `true` (privacy mode)
|
- **PUB_DISABLE_ALL_EXTERNAL_REQUESTS**: `true` (privacy mode)
|
||||||
|
- **VERT_SABLIER_ENABLED**: `true` (enable scale-to-zero)
|
||||||
|
- **VERT_AUTH_USERS**: HTTP Basic Auth credentials (htpasswd format in `.env`)
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
Simply access https://vert.pivoine.art and drag/drop files to convert between formats. All processing happens in your browser using WebAssembly - no data is uploaded to the server.
|
Simply access https://vert.pivoine.art and drag/drop files to convert between formats. All processing happens in your browser using WebAssembly - no data is uploaded to the server.
|
||||||
|
|||||||
1
arty.yml
1
arty.yml
@@ -115,6 +115,7 @@ envs:
|
|||||||
VERT_COMPOSE_PROJECT_NAME: vert
|
VERT_COMPOSE_PROJECT_NAME: vert
|
||||||
VERT_IMAGE: ghcr.io/vert-sh/vert:latest
|
VERT_IMAGE: ghcr.io/vert-sh/vert:latest
|
||||||
VERT_TRAEFIK_HOST: vert.pivoine.art
|
VERT_TRAEFIK_HOST: vert.pivoine.art
|
||||||
|
VERT_SABLIER_ENABLED: true
|
||||||
# Proxy
|
# Proxy
|
||||||
PROXY_COMPOSE_PROJECT_NAME: proxy
|
PROXY_COMPOSE_PROJECT_NAME: proxy
|
||||||
PROXY_DOCKER_IMAGE: traefik:latest
|
PROXY_DOCKER_IMAGE: traefik:latest
|
||||||
|
|||||||
11
proxy/dynamic/vert-sablier.yaml
Normal file
11
proxy/dynamic/vert-sablier.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
sablier-vert:
|
||||||
|
plugin:
|
||||||
|
sablier:
|
||||||
|
names: vert_app
|
||||||
|
sablierUrl: http://sablier_app:10000
|
||||||
|
sessionDuration: 1h
|
||||||
|
dynamic:
|
||||||
|
displayName: VERT File Converter
|
||||||
|
theme: ghost
|
||||||
@@ -18,10 +18,13 @@ services:
|
|||||||
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.rule=Host(`${VERT_TRAEFIK_HOST}`)'
|
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.rule=Host(`${VERT_TRAEFIK_HOST}`)'
|
||||||
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.tls.certresolver=resolver'
|
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.tls.certresolver=resolver'
|
||||||
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.entrypoints=web-secure'
|
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.entrypoints=web-secure'
|
||||||
|
- 'traefik.http.middlewares.${VERT_COMPOSE_PROJECT_NAME}-auth.basicauth.users=${VERT_AUTH_USERS}'
|
||||||
- 'traefik.http.middlewares.${VERT_COMPOSE_PROJECT_NAME}-web-secure-compress.compress=true'
|
- 'traefik.http.middlewares.${VERT_COMPOSE_PROJECT_NAME}-web-secure-compress.compress=true'
|
||||||
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.middlewares=${VERT_COMPOSE_PROJECT_NAME}-web-secure-compress'
|
- 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web-secure.middlewares=sablier-vert@file,${VERT_COMPOSE_PROJECT_NAME}-auth,${VERT_COMPOSE_PROJECT_NAME}-web-secure-compress'
|
||||||
- 'traefik.http.services.${VERT_COMPOSE_PROJECT_NAME}-web-secure.loadbalancer.server.port=80'
|
- 'traefik.http.services.${VERT_COMPOSE_PROJECT_NAME}-web-secure.loadbalancer.server.port=80'
|
||||||
- 'traefik.docker.network=${NETWORK_NAME}'
|
- 'traefik.docker.network=${NETWORK_NAME}'
|
||||||
|
- 'sablier.enable=${VERT_SABLIER_ENABLED}'
|
||||||
|
- 'sablier.group=${VERT_COMPOSE_PROJECT_NAME}'
|
||||||
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
|
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
Reference in New Issue
Block a user