Run & Deploy
Bring the whole stack up with one commandusing Docker Compose, then push it live. You’re at the finish line.
Run It All with Compose
A single docker-compose.yml at the repo root describes the database, the API, and the web app together.
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: inventory
ports: ["5432:5432"]
volumes: ["dbdata:/var/lib/postgresql/data"]
api:
build: ./server
env_file: ./server/.env
ports: ["5000:5000"]
depends_on: [db]
web:
build: ./web
ports: ["3000:3000"]
depends_on: [api]
volumes:
dbdata:$ docker compose up -d --build # build + start everything
$ docker compose logs -f # watch all services
$ docker compose down # stop (data stays in the volume)For Postgres, containers talk to each other by service name, not localhost. Point the API’s DATABASE_URL at db (e.g. postgresql://postgres:secret@db:5432/inventory) when it runs in Compose. For MongoDB Atlas, your connection string remains unchanged as it points to the cloud database.
The reference project (inventory-express) runs locally with npm run devand has no Dockerfile. The compose file and Dockerfiles below are teaching examples — add them when you’re ready to ship.
Example Dockerfiles
Place each file next to its package.json. For Next.js / NestJS, the official docs publish optimised multi-stage examples — search “Dockerfile” on nextjs.org and docs.nestjs.com. For Express + React/Vite:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 5000
CMD ["node", "server.js"]FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
RUN npm install -g serve
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["serve", "-s", "dist", "-l", "3000"]Before You Go Live
A short checklist to flip the app from "works on my machine" to "safe in production".
- ✓Secure your MongoDB Atlas cluster — in production, restrict the IP allowlist to your EC2 instance's public IP instead of
0.0.0.0/0. - ✓Strong secrets — a long random
JWT_SECRET; never reuse the dev value. Runopenssl rand -hex 64to generate one. - ✓Lock CORS — set the API’s CORS
originto your real frontend URL (theCLIENT_URLenv var) instead of the dev localhost value. - ✓Real email — swap Mailtrap for a production SMTP (Gmail App Password, SendGrid, or Resend). Update
EMAIL_HOST,EMAIL_USER,EMAIL_PASSinserver/.env. - ✓Update
CLIENT_URLandSTORE_OWNER_EMAIL— verification links and redirects must point at the live domain.
Step-by-Step Cloud Guide
The professional path: deploy your frontend to Vercel, API server to AWS EC2, and database to AWS (RDS or Docker).
Vercel is the premier platform for static sites and serverless functions, perfect for hosting your web/ directory.
- Push your code to a GitHub repository (ensure
.envis excluded by.gitignore). - Log in to Vercel and click Add New Project.
- Import your GitHub repository.
- In the configuration, set the Root Directory to
web. - Add any required environment variables (e.g.,
NEXT_PUBLIC_API_URLpointing to your EC2 backend:http://your-ec2-public-ip:5000). - Click Deploy. Vercel will build and host your frontend on a
*.vercel.appdomain with SSL enabled.
Alternative Deploy Options
If you prefer quick cloud platforms with built-in databases and simpler interfaces over AWS.
Every host above deploys from a Git repo. git init, commit, create a repo on GitHub, and push — then connect it in each platform’s dashboard.
You Built It
A full inventory system with verified accounts, product CRUD, and automatic low-stock alerts — on the stack of your choice.
- ✓Users register and must verify their email to log in
- ✓Logged-in users add, edit, delete, and view products
- ✓Low stock triggers an automatic email
- ✓The whole stack runs from one
docker compose up - ✓It's deployed and reachable on the internet