diff --git a/CLAUDE.md b/CLAUDE.md index 527a5ce..51fd4e6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,6 +22,7 @@ Root `compose.yaml` uses Docker Compose's `include` directive to orchestrate mul - **links**: Linkwarden bookmark manager (PostgreSQL + Meilisearch) - **vault**: Vaultwarden password manager (SQLite) - **joplin**: Joplin Server note-taking and sync platform (PostgreSQL) +- **vert**: VERT file format converter (WebAssembly-based, stateless) - **restic**: Backrest backup system with restic backend - **sablier**: Dynamic scaling plugin for Traefik - **vpn**: WireGuard VPN (wg-easy) @@ -247,6 +248,25 @@ Joplin Server note-taking and synchronization platform: 4. Enter server URL: `https://joplin.pivoine.art` 5. Enter email and password created in step 1 +### Vert (vert/compose.yaml) +VERT universal file format converter: +- **vert**: VERT app exposed at `vert.pivoine.art:80` + - WebAssembly-based file conversion (client-side processing) + - Supports 250+ file formats (images, audio, documents, video) + - No file size limits + - Privacy-focused: all conversions happen in the browser + - No persistent data storage required + +**Configuration**: +- **PUB_HOSTNAME**: `vert.pivoine.art` (for proper URL generation) +- **PUB_ENV**: `production` +- **PUB_DISABLE_ALL_EXTERNAL_REQUESTS**: `true` (privacy mode) + +**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. + +**Note**: VERT is stateless and doesn't require backups as no data is persisted. + ### Restic (restic/compose.yaml) Backrest backup system with restic backend: - **backrest**: Backrest web UI exposed at `restic.pivoine.art:9898` diff --git a/README.md b/README.md index f9306ac..448e868 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ The **Falcon** is a state-of-the-art containerized starship, powered by Docker's | **LINKS** | *Interstellar bookmark archive* | [links.pivoine.art](https://links.pivoine.art) | | **VAULT** | *Encrypted password vault* | [vault.pivoine.art](https://vault.pivoine.art) | | **JOPLIN** | *Note-taking server & sync hub* | [joplin.pivoine.art](https://joplin.pivoine.art) | +| **VERT** | *Universal file format converter* | [vert.pivoine.art](https://vert.pivoine.art) | | **RESTIC** | *Automated backup vault system* | [restic.pivoine.art](https://restic.pivoine.art) | | **PROXY** | *Shield control dashboard* | [proxy.pivoine.art](https://proxy.pivoine.art) | | **VPN** | *Cloaking device network* | [vpn.pivoine.art](https://vpn.pivoine.art) | @@ -209,6 +210,7 @@ THE FALCON (falcon_network) │ ├─ Linkwarden Marks [links.pivoine.art] │ ├─ Vaultwarden Vault [vault.pivoine.art] │ ├─ Joplin Sync Server [joplin.pivoine.art] +│ ├─ Vert Converter [vert.pivoine.art] │ ├─ Backrest Backups [restic.pivoine.art] │ └─ WireGuard VPN [vpn.pivoine.art] │ diff --git a/arty.yml b/arty.yml index 6207ee2..4684f8c 100644 --- a/arty.yml +++ b/arty.yml @@ -110,6 +110,11 @@ envs: JOPLIN_TRAEFIK_HOST: joplin.pivoine.art JOPLIN_APP_PORT: 22300 JOPLIN_DB_NAME: joplin + # Vert + VERT_TRAEFIK_ENABLED: true + VERT_COMPOSE_PROJECT_NAME: vert + VERT_IMAGE: ghcr.io/vert-sh/vert:latest + VERT_TRAEFIK_HOST: vert.pivoine.art # Proxy PROXY_COMPOSE_PROJECT_NAME: proxy PROXY_DOCKER_IMAGE: traefik:latest diff --git a/compose.yaml b/compose.yaml index 432094e..5c413bf 100644 --- a/compose.yaml +++ b/compose.yaml @@ -10,6 +10,7 @@ include: - links/compose.yaml - vault/compose.yaml - joplin/compose.yaml + - vert/compose.yaml - restic/compose.yaml - umami/compose.yaml - sablier/compose.yaml diff --git a/vert/compose.yaml b/vert/compose.yaml new file mode 100644 index 0000000..5d879da --- /dev/null +++ b/vert/compose.yaml @@ -0,0 +1,30 @@ +services: + vert: + image: ${VERT_IMAGE:-ghcr.io/vert-sh/vert:latest} + container_name: ${VERT_COMPOSE_PROJECT_NAME}_app + restart: unless-stopped + environment: + PUB_HOSTNAME: ${VERT_TRAEFIK_HOST} + PUB_ENV: production + PUB_DISABLE_ALL_EXTERNAL_REQUESTS: true + networks: + - compose_network + labels: + - 'traefik.enable=${VERT_TRAEFIK_ENABLED}' + - 'traefik.http.middlewares.${VERT_COMPOSE_PROJECT_NAME}-redirect-web-secure.redirectscheme.scheme=https' + - 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web.middlewares=${VERT_COMPOSE_PROJECT_NAME}-redirect-web-secure' + - 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web.rule=Host(`${VERT_TRAEFIK_HOST}`)' + - 'traefik.http.routers.${VERT_COMPOSE_PROJECT_NAME}-web.entrypoints=web' + - '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.entrypoints=web-secure' + - '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.services.${VERT_COMPOSE_PROJECT_NAME}-web-secure.loadbalancer.server.port=80' + - 'traefik.docker.network=${NETWORK_NAME}' + - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' + +networks: + compose_network: + name: ${NETWORK_NAME} + external: true