From c506a92800413b30792e04b0d4129f639346dcfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sat, 15 Nov 2025 16:34:28 +0100 Subject: [PATCH] feat: move asciinema to dev stack under asciinema.dev.pivoine.art MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Moved asciinema service from standalone stack to dev/compose.yaml - Updated hostname from asciinema.pivoine.art to asciinema.dev.pivoine.art - Updated environment variables to use DEV_ASCIINEMA_ prefix - Updated restic backup volume reference (asciinema_data -> dev_asciinema_data) - Moved custom.exs to dev/asciinema-custom.exs - Removed standalone asciinema/compose.yaml directory - Container name changes from asciinema_app to dev_asciinema - Volume name changes from asciinema_data to dev_asciinema_data - Preserved admin interface at admin.asciinema.dev.pivoine.art with Basic Auth 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- arty.yml | 13 ++-- asciinema/compose.yaml | 63 ------------------- compose.yaml | 1 - .../custom.exs => dev/asciinema-custom.exs | 0 dev/compose.yaml | 57 +++++++++++++++++ restic/compose.yaml | 2 +- 6 files changed, 62 insertions(+), 74 deletions(-) delete mode 100644 asciinema/compose.yaml rename asciinema/custom.exs => dev/asciinema-custom.exs (100%) diff --git a/arty.yml b/arty.yml index beb067b..c133180 100644 --- a/arty.yml +++ b/arty.yml @@ -124,6 +124,10 @@ envs: DEV_N8N_TRAEFIK_HOST: n8n.dev.pivoine.art DEV_N8N_DB_NAME: n8n DEV_N8N_DB_SCHEMA: public + DEV_ASCIINEMA_IMAGE: ghcr.io/asciinema/asciinema-server:latest + DEV_ASCIINEMA_TRAEFIK_HOST: asciinema.dev.pivoine.art + DEV_ASCIINEMA_DB_NAME: asciinema + DEV_ASCIINEMA_SIGN_UP_DISABLED: true # PairDrop DROP_TRAEFIK_ENABLED: true DROP_COMPOSE_PROJECT_NAME: drop @@ -161,15 +165,6 @@ envs: AI_CRAWL4AI_PORT: 11235 AI_OPENAI_API_BASE_URLS: https://api.anthropic.com/v1 AI_LITELLM_TRAEFIK_HOST: llm.ai.pivoine.art - # Asciinema - ASCIINEMA_TRAEFIK_ENABLED: true - ASCIINEMA_COMPOSE_PROJECT_NAME: asciinema - ASCIINEMA_IMAGE: ghcr.io/asciinema/asciinema-server:latest - ASCIINEMA_TRAEFIK_HOST: asciinema.pivoine.art - ASCIINEMA_DB_NAME: asciinema - ASCIINEMA_SIGN_UP_DISABLED: true - ASCIINEMA_UNCLAIMED_TTL: 30 - ASCIINEMA_MAIL_REPLY_TO: valknar@pivoine.art # Watchtower WATCHTOWER_POLL_INTERVAL: 300 WATCHTOWER_LABEL_ENABLE: true diff --git a/asciinema/compose.yaml b/asciinema/compose.yaml deleted file mode 100644 index a4e74c3..0000000 --- a/asciinema/compose.yaml +++ /dev/null @@ -1,63 +0,0 @@ -services: - asciinema: - image: ${ASCIINEMA_IMAGE:-ghcr.io/asciinema/asciinema-server:latest} - container_name: ${ASCIINEMA_COMPOSE_PROJECT_NAME}_app - restart: unless-stopped - networks: - - compose_network - volumes: - - asciinema_data:/var/opt/asciinema - - ./custom.exs:/opt/app/etc/custom.exs:ro - environment: - SECRET_KEY_BASE: ${ASCIINEMA_SECRET_KEY} - URL_HOST: ${ASCIINEMA_TRAEFIK_HOST} - URL_SCHEME: https - DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@${CORE_DB_HOST}/${ASCIINEMA_DB_NAME}?pool_size=10 - SMTP_HOST: ${EMAIL_SMTP_HOST} - SMTP_USERNAME: ${EMAIL_SMTP_USER} - SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD} - SMTP_FROM_ADDRESS: ${EMAIL_FROM} - SIGN_UP_DISABLED: ${ASCIINEMA_SIGN_UP_DISABLED:-false} - DEFAULT_AVATAR: gravatar - labels: - - 'traefik.enable=${ASCIINEMA_TRAEFIK_ENABLED}' - # Main web interface - HTTP to HTTPS redirect - - 'traefik.http.middlewares.${ASCIINEMA_COMPOSE_PROJECT_NAME}-redirect-web-secure.redirectscheme.scheme=https' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web.middlewares=${ASCIINEMA_COMPOSE_PROJECT_NAME}-redirect-web-secure' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web.rule=Host(`${ASCIINEMA_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web.entrypoints=web' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web.service=${ASCIINEMA_COMPOSE_PROJECT_NAME}' - # Main web interface - HTTPS router - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web-secure.rule=Host(`${ASCIINEMA_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web-secure.tls.certresolver=resolver' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web-secure.entrypoints=web-secure' - - 'traefik.http.middlewares.${ASCIINEMA_COMPOSE_PROJECT_NAME}-compress.compress=true' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web-secure.middlewares=${ASCIINEMA_COMPOSE_PROJECT_NAME}-compress,security-headers@file' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-web-secure.service=${ASCIINEMA_COMPOSE_PROJECT_NAME}' - - 'traefik.http.services.${ASCIINEMA_COMPOSE_PROJECT_NAME}.loadbalancer.server.port=4000' - # Admin interface - HTTP to HTTPS redirect - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web.middlewares=${ASCIINEMA_COMPOSE_PROJECT_NAME}-redirect-web-secure' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web.rule=Host(`admin.${ASCIINEMA_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web.entrypoints=web' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web.service=${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin' - # Admin interface - HTTPS router with Basic Auth - - 'traefik.http.middlewares.${ASCIINEMA_COMPOSE_PROJECT_NAME}-auth.basicauth.users=${AUTH_USERS}' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web-secure.rule=Host(`admin.${ASCIINEMA_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web-secure.tls.certresolver=resolver' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web-secure.entrypoints=web-secure' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web-secure.middlewares=${ASCIINEMA_COMPOSE_PROJECT_NAME}-auth,${ASCIINEMA_COMPOSE_PROJECT_NAME}-compress,security-headers@file' - - 'traefik.http.routers.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin-web-secure.service=${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin' - - 'traefik.http.services.${ASCIINEMA_COMPOSE_PROJECT_NAME}-admin.loadbalancer.server.port=4002' - # Network - - 'traefik.docker.network=${NETWORK_NAME}' - # Watchtower - - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' - -volumes: - asciinema_data: - name: ${ASCIINEMA_COMPOSE_PROJECT_NAME}_data - -networks: - compose_network: - name: ${NETWORK_NAME} - external: true diff --git a/compose.yaml b/compose.yaml index 04eb3bd..e902299 100644 --- a/compose.yaml +++ b/compose.yaml @@ -9,7 +9,6 @@ include: - joplin/compose.yaml - drop/compose.yaml - ai/compose.yaml - - asciinema/compose.yaml - restic/compose.yaml - netdata/compose.yaml - umami/compose.yaml diff --git a/asciinema/custom.exs b/dev/asciinema-custom.exs similarity index 100% rename from asciinema/custom.exs rename to dev/asciinema-custom.exs diff --git a/dev/compose.yaml b/dev/compose.yaml index 73226f8..21f40ab 100644 --- a/dev/compose.yaml +++ b/dev/compose.yaml @@ -226,6 +226,61 @@ services: # Watchtower - "com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}" + # Asciinema - Terminal recording and sharing platform + asciinema: + image: ${DEV_ASCIINEMA_IMAGE:-ghcr.io/asciinema/asciinema-server:latest} + container_name: ${DEV_COMPOSE_PROJECT_NAME}_asciinema + restart: unless-stopped + volumes: + - asciinema_data:/var/opt/asciinema + - ./asciinema-custom.exs:/opt/app/etc/custom.exs:ro + environment: + SECRET_KEY_BASE: ${ASCIINEMA_SECRET_KEY} + URL_HOST: ${DEV_ASCIINEMA_TRAEFIK_HOST} + URL_SCHEME: https + DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@${CORE_DB_HOST}/${DEV_ASCIINEMA_DB_NAME}?pool_size=10 + SMTP_HOST: ${EMAIL_SMTP_HOST} + SMTP_USERNAME: ${EMAIL_SMTP_USER} + SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD} + SMTP_FROM_ADDRESS: ${EMAIL_FROM} + SIGN_UP_DISABLED: ${DEV_ASCIINEMA_SIGN_UP_DISABLED:-false} + DEFAULT_AVATAR: gravatar + networks: + - compose_network + labels: + - "traefik.enable=${DEV_TRAEFIK_ENABLED}" + # Main web interface - HTTP to HTTPS redirect + - "traefik.http.middlewares.${DEV_COMPOSE_PROJECT_NAME}-asciinema-redirect-web-secure.redirectscheme.scheme=https" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web.middlewares=${DEV_COMPOSE_PROJECT_NAME}-asciinema-redirect-web-secure" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web.rule=Host(`${DEV_ASCIINEMA_TRAEFIK_HOST}`)" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web.entrypoints=web" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web.service=${DEV_COMPOSE_PROJECT_NAME}-asciinema" + # Main web interface - HTTPS router + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web-secure.rule=Host(`${DEV_ASCIINEMA_TRAEFIK_HOST}`)" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web-secure.tls.certresolver=resolver" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web-secure.entrypoints=web-secure" + - "traefik.http.middlewares.${DEV_COMPOSE_PROJECT_NAME}-asciinema-compress.compress=true" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web-secure.middlewares=${DEV_COMPOSE_PROJECT_NAME}-asciinema-compress,security-headers@file" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-web-secure.service=${DEV_COMPOSE_PROJECT_NAME}-asciinema" + - "traefik.http.services.${DEV_COMPOSE_PROJECT_NAME}-asciinema.loadbalancer.server.port=4000" + # Admin interface - HTTP to HTTPS redirect + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web.middlewares=${DEV_COMPOSE_PROJECT_NAME}-asciinema-redirect-web-secure" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web.rule=Host(`admin.${DEV_ASCIINEMA_TRAEFIK_HOST}`)" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web.entrypoints=web" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web.service=${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin" + # Admin interface - HTTPS router with Basic Auth + - "traefik.http.middlewares.${DEV_COMPOSE_PROJECT_NAME}-asciinema-auth.basicauth.users=${AUTH_USERS}" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web-secure.rule=Host(`admin.${DEV_ASCIINEMA_TRAEFIK_HOST}`)" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web-secure.tls.certresolver=resolver" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web-secure.entrypoints=web-secure" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web-secure.middlewares=${DEV_COMPOSE_PROJECT_NAME}-asciinema-auth,${DEV_COMPOSE_PROJECT_NAME}-asciinema-compress,security-headers@file" + - "traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin-web-secure.service=${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin" + - "traefik.http.services.${DEV_COMPOSE_PROJECT_NAME}-asciinema-admin.loadbalancer.server.port=4002" + # Network + - "traefik.docker.network=${NETWORK_NAME}" + # Watchtower + - "com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}" + volumes: gitea_data: name: ${DEV_COMPOSE_PROJECT_NAME}_gitea_data @@ -237,6 +292,8 @@ volumes: name: ${DEV_COMPOSE_PROJECT_NAME}_coolify_data n8n_data: name: ${DEV_COMPOSE_PROJECT_NAME}_n8n_data + asciinema_data: + name: ${DEV_COMPOSE_PROJECT_NAME}_asciinema_data networks: compose_network: diff --git a/restic/compose.yaml b/restic/compose.yaml index 15cee63..1abe5cf 100644 --- a/restic/compose.yaml +++ b/restic/compose.yaml @@ -144,7 +144,7 @@ volumes: name: ai_crawl4ai_data external: true backup_asciinema_data: - name: asciinema_data + name: dev_asciinema_data external: true backup_dev_gitea_data: name: dev_gitea_data