Appearance
Local Docker Image Testing
Use this workflow to build the production Docker image on your machine and run it against your local .env.local — the same image CI publishes, without pushing to a registry.
Works with Docker or Podman (commands below use docker; with Podman, docker is often an alias, or substitute podman directly).
When to use this
- Before merging
Dockerfileor production-runtime changes - To reproduce production behavior locally (
pnpm devvs the standalone Next.js server) - To smoke-test OAuth, uploads, or other features in the container
For day-to-day development, prefer pnpm dev — see Daily Dev Workflow.
Prerequisites
.env.localconfigured (copy from.env.example). Required at minimum:MONGO_ROOT_PASSWORDJWT_SECRETTOKEN_ENCRYPTION_KEYNEXT_PUBLIC_APP_URL— usehttp://localhost:9624when testing on the same machine
- Google sign-in (optional): add
http://localhost:9624/api/auth/oauth/callbackas an authorized redirect URI in Google Cloud Console
1. Build the image
On amd64 (typical PC / laptop):
bash
./scripts/docker-build-platform.sh linux/amd64 videosphere:amd64-testOn arm64 (Apple Silicon, Raspberry Pi, Odroid):
bash
./scripts/docker-build-platform.sh linux/arm64 videosphere:arm64-testThe script defaults to linux/arm64 and tag videosphere:local-test when no arguments are given. Podman tags the result as localhost/videosphere:amd64-test.
Cross-arch builds (e.g. arm64 on amd64) need QEMU — see comments in scripts/docker-build-platform.sh.
2. Start MongoDB
Use Compose so Mongo gets a persistent volume and health checks:
bash
docker compose --env-file .env.local up -d mongoCompose reads MONGO_ROOT_PASSWORD from .env.local for Mongo initialization. The container name is videosphere-mongo on network videosphere_default.
3. Run the app container
Important: Two details that are easy to get wrong:
MONGODB_URIin.env.localuseslocalhost— correct forpnpm dev, wrong inside a container. Override it to use the Compose service hostnamevideosphere-mongo.- Shell expansion for
-e MONGODB_URI=...—${MONGO_ROOT_PASSWORD}is expanded by your shell when you rundocker run, not by Docker from--env-file. Source.env.localfirst so the password is in your shell.
bash
set -a
source .env.local
set +a
docker run -d \
--name videosphere-test \
--network videosphere_default \
-p 9624:9624 \
--env-file .env.local \
-e "MONGODB_URI=mongodb://${MONGO_ROOT_USER:-admin}:${MONGO_ROOT_PASSWORD}@videosphere-mongo:27017/videosphere?authSource=admin" \
localhost/videosphere:amd64-testReplace amd64-test with your tag if you built a different one.
4. Verify
- Open
http://localhost:9624(or yourNEXT_PUBLIC_APP_URL) - Sign in or complete first-run setup at
/setup - Check logs:
docker logs -f videosphere-test
If auth fails with MongoServerError: Authentication failed in the logs, the MONGODB_URI override did not get the password — re-run step 3 after source .env.local.
5. Clean up
bash
docker rm -f videosphere-test
docker compose --env-file .env.local downTo remove the built image: docker rmi localhost/videosphere:amd64-test
Intermediate <none> images from builds can be pruned with docker image prune.
Quick reference (copy-paste)
bash
# Build (amd64)
./scripts/docker-build-platform.sh linux/amd64 videosphere:amd64-test
# Mongo
docker compose --env-file .env.local up -d mongo
# App
set -a && source .env.local && set +a
docker run -d \
--name videosphere-test \
--network videosphere_default \
-p 9624:9624 \
--env-file .env.local \
-e "MONGODB_URI=mongodb://${MONGO_ROOT_USER:-admin}:${MONGO_ROOT_PASSWORD}@videosphere-mongo:27017/videosphere?authSource=admin" \
localhost/videosphere:amd64-test
# Teardown
docker rm -f videosphere-test
docker compose --env-file .env.local downRelated
- Deployment Guide — production with pre-built registry images
- Local Setup — first-run setup and Mongo options
- CONTRIBUTING.md — multi-arch build verification before merge