Deploy the Web app
Pinchana Web is hosted with the repository’s docker-compose.yml. It uses the official oven/bun:1.3.14-debian image directly—there is no Pinchana Web image to build or publish. On container start, Bun installs the frozen lockfile, synchronizes browser FFmpeg assets, builds Next.js, and starts the production server.
Pinchana Web requires a running server. It cannot be exported as static HTML because route handlers proxy authenticated requests, verify Ed25519 certificates, read server-only configuration, and manage HttpOnly cookies.
Environment split
Section titled “Environment split”| Variable | Phase | Exposure |
|---|---|---|
NEXT_PUBLIC_TURNSTILE_SITE_KEY |
container build/public | Embedded for the browser; required and registered for the production Web hostname |
PINCHANA_API_URL |
container runtime/server | Default API origin; required and never public |
PINCHANA_INSTANCE_PUBLIC_KEY |
container runtime/server | Optional Ed25519 public verification PEM; preserve newlines or use escaped \n |
WEB_BIND_ADDRESS |
Compose host | Host interface, default 127.0.0.1 |
WEB_HOST_PORT |
Compose host | Reverse-proxy target port, default 3000 |
Configure the selected API separately with the matching Turnstile secret, expected Web hostname pinchana.example.com, action turnstile-spin-v1, and signed-session secret.
Start the service
Section titled “Start the service”- Clone Pinchana Web on the Docker host.
- Create a mode-0600
.envbesidedocker-compose.ymlwith the required variables. Compose reads this file for interpolation; it is not mounted into the container. - Run
docker compose configand inspect the effective configuration without sharing it because it contains deployment values. - Start with
docker compose up -dand follow the initial install/build withdocker compose logs -f web. - Wait for
docker compose psto report the service healthy, then proxy HTTPS to127.0.0.1:3000.
PINCHANA_API_URL=https://api.pinchana.ccNEXT_PUBLIC_TURNSTILE_SITE_KEY=REPLACE_WITH_PUBLIC_SITE_KEYPINCHANA_INSTANCE_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nREPLACE_WITH_PUBLIC_KEY\n-----END PUBLIC KEY-----"WEB_BIND_ADDRESS=127.0.0.1WEB_HOST_PORT=3000Application source and configuration are mounted read-only into a writable /app workspace. The container copies public/ into that workspace before install so the FFmpeg synchronization step can write public/ffmpeg. Named volumes hold installed dependencies and .next-build; recreate these disposable volumes if a corrupt dependency/build cache survives an update.
Reverse proxy and updates
Section titled “Reverse proxy and updates”Put Caddy, Nginx, Traefik, or another HTTPS reverse proxy in front of the loopback port. Preserve streaming, disable response buffering for App Router streams, and forward byte-range requests used by the media proxy.
git pull --ff-onlydocker compose up -d --force-recreate webdocker compose logs --tail=100 webThe startup command rebuilds from the checked-out revision. NEXT_PUBLIC_TURNSTILE_SITE_KEY is frozen into that build, so changing it also requires recreation. Roll back by checking out the previous revision and force-recreating the service again.
Verification checklist
Section titled “Verification checklist”- Page load checks an existing session or renders Turnstile.
- Browser network requests never reveal the API origin, signed session, or instance certificate cookie.
- URL processing, image/video/audio preview, byte-range seeking, Media and Audio-only saves, ZIP creation, and FFmpeg loading work.
- Cookies are
HttpOnly,SameSite=Strict, andSecureover production HTTPS. - Custom origin selection accepts an authorized certificate and rejects mismatched/expired envelopes.