Initial implementation of Bluetooth toy control app
CI / Static checks (push) Successful in 1m27s
CI / Build and push image (push) Skipped

Next.js app with a browser-side buttplug/buttplug-wasm control layer
(server never touches real-time device commands), SQLite storage via
Drizzle, single-secret auth, recordings/replay with device remapping,
a usage stats dashboard, Docker deployment, and Gitea CI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8WkFF5ppURBAB918593Eb
This commit is contained in:
2026-08-25 07:51:38 +02:00
co-authored by Claude Sonnet 5
commit 1119c8eea0
112 changed files with 15522 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
services:
sexy:
build: .
container_name: sexy
restart: unless-stopped
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
volumes:
# Writable - the SQLite file must persist across restarts, unlike
# everything else in the container filesystem.
- ./data:/app/data
env_file: .env
networks:
- compose_network
labels:
- traefik.enable=true
- traefik.docker.network=${NETWORK_NAME}
- traefik.http.middlewares.sexy-redirect-web-secure.redirectscheme.scheme=https
- traefik.http.routers.sexy-web.rule=Host(`${TRAEFIK_HOST}`)
- traefik.http.routers.sexy-web.entrypoints=web
- traefik.http.routers.sexy-web.middlewares=sexy-redirect-web-secure
- traefik.http.routers.sexy-web-secure.rule=Host(`${TRAEFIK_HOST}`)
- traefik.http.routers.sexy-web-secure.entrypoints=web-secure
- traefik.http.routers.sexy-web-secure.tls.certresolver=resolver
- traefik.http.routers.sexy-web-secure.middlewares=security-headers@file,no-index@file
- traefik.http.services.sexy-web-secure.loadbalancer.server.port=3000
healthcheck:
test: ["CMD", "node", "healthcheck.mjs"]
interval: 30s
timeout: 5s
start_period: 15s
retries: 3
networks:
compose_network:
name: ${NETWORK_NAME}
external: true