Next.js 16 App Router application for unified Google Drive and OneDrive management.
npm run env:check
npm run lint
npm run test
npm run buildStart from .env.example and configure at least:
DATABASE_URLNEXTAUTH_SECRETNEXTAUTH_URLROOT_DOMAINNEXT_PUBLIC_ROOT_DOMAINENCRYPTION_KEYADMIN_EMAILSorADMIN_EMAIL
Optional integrations must be configured as complete sets:
- Google OAuth:
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET - Microsoft OAuth:
MICROSOFT_CLIENT_ID,MICROSOFT_CLIENT_SECRET - SMTP:
SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASS
The project now builds with Next.js standalone output for container deployment.
cp .env.example .env
# edit .env and replace the placeholder secrets
docker compose up --build -d
docker compose logs -f appFor local Docker, open http://localtest.me:3000; subdomains like http://demo.localtest.me:3000 also resolve back to your machine.
Fresh machine checklist:
cp .env.example .env
openssl rand -base64 32 # use for NEXTAUTH_SECRET
openssl rand -base64 32 # use for ENCRYPTION_KEY
docker compose up --build -d
docker compose ps
curl http://localtest.me:3000/api/healthFor a real domain, set NEXTAUTH_URL, ROOT_DOMAIN, and NEXT_PUBLIC_ROOT_DOMAIN to that domain before building. Leave the bundled Postgres settings as-is for a single-machine Docker deploy, or replace DATABASE_URL and remove/ignore the db service if you manage Postgres separately.
For a one-command VPS install on Ubuntu/Debian, run:
chmod +x install.sh
./install.shThe installer expects a Cloudflare API token for wildcard TLS and automatic DNS:
Zone:ReadDNS:Edit- scoped to the root domain zone
What the installer does:
- asks for the root domain, admin emails, database mode, and optional integrations that are actually enabled in the app
- asks for a Cloudflare token and VPS public IPv4
- creates or updates Cloudflare
@and*A records unless--skip-dnsis used - generates production env files under
deploy/runtime/ - provisions Docker if needed
- boots Traefik with Let's Encrypt wildcard TLS through Cloudflare DNS challenge
- bootstraps Prisma schema and starts the app stack
Notes:
- Port
80and443must be reachable from the internet for Traefik and the application. - If
prisma/migrations/is empty, the installer usesprisma db pushfor first-time schema bootstrap. - If a deploy step fails, fix the reported issue and rerun
./install.sh --resume; existing answers indeploy/runtime/are reused.
Runtime behavior:
- Container startup validates critical environment variables before booting Next.js.
- Container startup applies Prisma schema changes automatically. If
prisma/migrations/exists it runsprisma migrate deploy; otherwise it runsprisma db push. GET /api/healthreturns200only when both env config and database connectivity are healthy.- The image runs as a non-root user and exposes port
3000.
If CapRover fails at RUN npm ci with ENOSPC: no space left on device, Docker ran out of disk during dependency extraction before the app build started. Check and clean Docker's build cache on the VPS:
df -h
docker system df
docker builder prune -af
docker image prune -af
docker container prune -f
journalctl --vacuum-time=3d
apt-get cleanDo not run docker system prune --volumes unless the database and CapRover app volumes are backed up; that can remove persistent data.
- Put nginx or another reverse proxy in front of the app for TLS, request size limits, buffering control, and rate limiting.
- Keep
ROOT_DOMAINandNEXT_PUBLIC_ROOT_DOMAINidentical so subdomain routing behaves consistently on server and client. - Keep
ENFORCE_HTTPS=falsefor local HTTP Docker. Set it totrueonly when building an image that will be served over HTTPS. - Set
PRISMA_SKIP_BOOTSTRAP=1only when migrations/schema bootstrap are handled by a separate release job. - If you deploy multiple app instances, also set
DEPLOYMENT_VERSIONduring rollout so Next.js can detect version skew.