Deployment
Docker setup and production deployment for the frontend
Deployment
Docker Setup
Development (docker-compose.yml)
services:
app:
build:
context: .
target: dev
ports:
- "3000:3000"
volumes:
- .:/app
- node_modules:/app/node_modules
environment:
- NODE_ENV=development
- NUXT_PUBLIC_API_BASE_URL=http://localhost
command: npm run dev
volumes:
node_modules:
Key points:
- Source code is mounted for hot-reload
node_modulesuses a named volume (not mounted from host)- Nuxt dev server binds to
0.0.0.0for Docker access
Production (Dockerfile)
The multi-stage Dockerfile produces an optimized production image:
# Dev stage
FROM node:20-alpine AS dev
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
# Production stage
FROM node:20-alpine AS prod
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]
Dokploy Deployment
Setup
- Create a new application in Dokploy
- Set source to Docker (from GitHub Container Registry)
- Configure the image:
ghcr.io/{owner}/{repo}:main - Set up a domain with HTTPS
Environment Variables
Set these in Dokploy application settings:
NUXT_PUBLIC_API_BASE_URL=https://api.yourdomain.com
NUXT_PUBLIC_FIREBASE_API_KEY=your-firebase-api-key
NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NUXT_PUBLIC_FIREBASE_PROJECT_ID=your-firebase-project-id
NUXT_PUBLIC_UMAMI_HOST=https://analytics.yourdomain.com
NUXT_PUBLIC_UMAMI_ID=your-site-id
Deployment Webhook
- In Dokploy, copy the webhook URL from your application settings
- Add it as a GitHub secret:
DOKPLOY_WEBHOOK_URL - Pushes to
mainwill automatically build and deploy
Deployment Architecture
GitHub (push to main)
│
├── Backend CI/CD
│ └── Test → Build → Push to GHCR → Dokploy webhook → Deploy
│
└── Frontend CI/CD
└── Test → Build → Push to GHCR → Dokploy webhook → Deploy
Dokploy Server
├── Backend (FrankenPHP) ← https://api.yourdomain.com
├── Frontend (Node.js) ← https://yourdomain.com
├── PostgreSQL
└── Redis
Both services are deployed as Docker containers managed by Dokploy, with automatic HTTPS via Let's Encrypt.
Installing Dokploy
Dokploy is a self-hosted deployment platform. Install it on your server:
curl -sSL https://dokploy.com/install.sh | sh
Access the Dokploy dashboard at https://your-server-ip:3000.
DNS Configuration
| Record | Domain | Target |
|---|---|---|
| A | yourdomain.com | Your server IP |
| A | api.yourdomain.com | Your server IP |
Dokploy handles HTTPS certificates automatically via Let's Encrypt.
Production Checklist
Verify everything before going live.
Frontend
-
NUXT_PUBLIC_API_BASE_URLpoints to the production backend - Analytics configured (Umami host + ID, if using)
- CSP headers allow the production API domain
Firebase
-
NUXT_PUBLIC_FIREBASE_API_KEYis set on the frontend -
NUXT_PUBLIC_FIREBASE_AUTH_DOMAINis set -
NUXT_PUBLIC_FIREBASE_PROJECT_IDmatches the backend
Cross-Project
-
CORS_ALLOW_ORIGINon backend matches the frontend domain - Stripe success/cancel URLs point to the production frontend
- All redirect URLs in the backend point to valid frontend routes
Infrastructure
- HTTPS is configured on the frontend domain
- DNS records point to the server
- GitHub secrets are set for CI/CD (
DOKPLOY_WEBHOOK_URL) - CI/CD pipeline passes (test → build → deploy)
Smoke Test
After deployment, verify these flows work end-to-end:
- Landing page loads at
https://yourdomain.com - Register a new user
- Check welcome email arrives (via Brevo)
- Login with the new user
- Complete a Stripe test checkout
- Verify subscription appears on profile page
- Test forgot password flow
- Test social login (if configured)
- Access admin panel at
https://api.yourdomain.com/admin