Skip to main content
Reshma Bangles & Boutique Logo

Docker Setup Guide

Run the entire Reshma‑Core stack (API, worker, MongoDB, Redis, Typesense) in isolated containers – perfect for consistent development and production deployments.

Docker MongoDB Redis Typesense


📋 Table of Contents

  1. Overview: Two Compose Files
  2. Prerequisites
  3. Development Environment (docker-compose.yml)
  4. Production / Staging (docker-compose.prod.yml)
  5. Environment Variables for Docker
  6. Common Commands
  7. Building & Rebuilding
  8. Database Seeding in Docker
  9. Troubleshooting
  10. Architecture Deep Dive

Overview: Two Compose Files

FilePurposeKey Differences
docker-compose.ymlLocal developmentNo passwords, ports exposed, live reload bind mounts (optional), restart: unless-stopped
docker-compose.prod.ymlProduction / StagingHealthchecks, air‑gapped network, passwords required, restart: always, separate worker service

Both files use the same Dockerfile (multi‑stage build) but with different environment overrides.


Prerequisites

  • Docker Engine 20.10+ or Docker Desktop (Windows/Mac)
  • Docker Compose V2 (included with Docker Desktop)
  • At least 4GB RAM allocated to Docker (for Typesense + MongoDB)

Verify installation:

docker --version
docker-compose --version

Development Environment (docker-compose.yml)

What’s included

ServiceContainer NamePort (host)Purpose
reshma-apireshma-api5000Express API (Node.js)
reshma-workerreshma-workerBullMQ email/export worker
reshma-dbreshma-db27017MongoDB 7.0
reshma-redisreshma-redis6379Redis 7 Alpine
reshma-typesensereshma-typesense8108Typesense 0.25.2

All services run on a custom bridge network reshma-network for internal communication.

Step‑by‑Step

# 1. Clone the repository (if not already)
git clone https://github.com/Afzal14786/reshma-core.git
cd reshma-core

# 2. Copy environment template
cp .env.example .env

# 3. Edit .env – at minimum set:
# - JWT_ACCESS_SECRET, JWT_REFRESH_SECRET (any strong string, min 10 chars)
# - TYPESENSE_API_KEY (must match the one in docker-compose.yml, default: your-super-secret-key)
# Leave other variables as placeholders for now.

# 4. Start all services in detached mode
docker-compose up -d

# 5. Check container status
docker-compose ps

# 6. Seed the database (products, categories, etc.)
docker exec -it reshma-api npm run seed

# 7. Follow API logs
docker-compose logs -f reshma-api

The API will be available at http://localhost:5000.
To stop: docker-compose down.

Development with Live Reload (Optional)

If you want code changes to automatically rebuild and restart the API container, uncomment the volumes section in docker-compose.yml:

volumes:
- ./src:/app/src # mounts local source code

Then rebuild and run:

docker-compose up -d --build

Note: This is slower on Windows/macOS due to file system overhead. For active development, consider running npm run dev natively and only use Docker for dependent services (MongoDB, Redis, Typesense).


Production / Staging (docker-compose.prod.yml)

Differences from Development

FeatureDevelopmentProduction
AuthenticationNo DB/Redis passwordsMONGO_INITDB_ROOT_USERNAME + REDIS_PASSWORD required
HealthchecksNone (basic depends_on)Active healthchecks on all services
Port exposureAll ports exposed to hostOnly API port 5000 exposed
Restart policyunless-stoppedalways
NetworkingBridge network with exposed portsInternal network only (air‑gapped)
WorkerSame image but runs email.worker.jsSame

Environment Preparation

Create a .env.production file (or reuse .env) with all required variables:

# Must be set (no defaults in production compose)
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=strong_password_here
REDIS_PASSWORD=another_strong_password
TYPESENSE_API_KEY=your_super_secret_key # must match the one in compose

# JWT secrets (required)
JWT_ACCESS_SECRET=...
JWT_REFRESH_SECRET=...

Running Production

# Use the production compose file
docker-compose -f docker-compose.prod.yml up -d

# View logs
docker-compose -f docker-compose.prod.yml logs -f

# Stop
docker-compose -f docker-compose.prod.yml down

Security: Never expose MongoDB or Redis ports to the internet. The production compose file only publishes port 5000 (API). All other services are accessible only inside the Docker network.


Environment Variables for Docker

The .env file is shared between both compose files. However, certain variables are overridden inside containers:

VariableLocal (docker-compose.yml)Production (docker-compose.prod.yml)
MONGO_URImongodb://reshma-db:27017/reshmabanglesmongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@reshma-db:27017/reshmabangles?authSource=admin
REDIS_URLredis://reshma-redis:6379redis://default:${REDIS_PASSWORD}@reshma-redis:6379
TYPESENSE_HOSTreshma-typesensereshma-typesense

You do not need to set these in your .env – they are passed directly by the compose file.

Minimum .env for Docker (both modes)

# Core (required)
NODE_ENV=development # or production
CLIENT_URL=http://localhost:3000
ADMIN_URL=http://localhost:3001

# JWT (generate actual secrets)
JWT_ACCESS_SECRET=5f8d9a3c7e2b1f6a4d8c0e9b7a3f2d6c
JWT_REFRESH_SECRET=7b2e1f6a4d8c0e9b7a3f2d6c1e8b4a7f

# Typesense (must match the compose file's --api-key)
TYPESENSE_API_KEY=your-super-secret-key

# Optional for production – add if you need email/payment/shipping
SMTP_HOST=smtp.gmail.com
SMTP_USER=...
SMTP_PASS=...

Common Commands

ActionCommand
Start dev servicesdocker-compose up -d
Start prod servicesdocker-compose -f docker-compose.prod.yml up -d
Stop alldocker-compose down (add -f docker-compose.prod.yml for prod)
View logs (API)docker-compose logs -f reshma-api
View logs (worker)docker-compose logs -f reshma-worker
Execute command inside API containerdocker exec -it reshma-api bash
Rebuild after code changesdocker-compose up -d --build
Remove volumes (reset data)docker-compose down -v (⚠️ deletes databases)
Check resource usagedocker stats

Building & Rebuilding

The Dockerfile uses a multi‑stage build:

StagePurpose
baseNode 20 Alpine, sets working directory
depsInstalls all dependencies (including dev)
builderRuns npm run build (TypeScript → JS + path alias resolution)
runnerCopies only production dependencies and compiled dist/, runs as node user

When to rebuild

  • After changing package.json or package-lock.json
  • After changing TypeScript source code (but not environment variables)
  • After changing tsconfig.json or Dockerfile
docker-compose up -d --build --force-recreate

Tip: For rapid frontend/backend iteration, mount your source code as a volume (development only) to avoid rebuilding on every change.


Database Seeding in Docker

Even when running inside containers, you seed the database by executing npm run seed inside the API container.

# Seed the database (development)
docker exec -it reshma-api npm run seed

# If using production compose file, container name is still "reshma-api"
docker exec -it reshma-api npm run seed

The seed script will:

  • Delete existing products (destructive – only for development)
  • Generate 500+ realistic products across all discriminators
  • Automatically sync them to Typesense

To verify seeding succeeded:

docker exec -it reshma-api node -e "require('./dist/db/seed.js')" # alternative

Troubleshooting

1. Error: Cannot find module '@config/env'

Cause: TypeScript not compiled inside the container. Fix: Rebuild the image:

docker-compose up -d --build

2. MongoDB connection refused

Check: Is the MongoDB container healthy?

docker-compose ps
# Look for "reshma-db" with status "Up (healthy)" or "Up"

# Test connection from API container
docker exec -it reshma-api node -e "require('mongoose').connect('mongodb://reshma-db:27017/reshmabangles').then(()=>console.log('OK')).catch(e=>console.error(e))"

3. Typesense returns empty search results

Check: Has the seed script been run? Also verify the API key matches between .env and docker-compose.yml.

# Check Typesense collections
docker exec -it reshma-typesense curl -H "X-TYPESENSE-API-KEY: your-super-secret-key" http://localhost:8108/collections

4. Port conflicts (5000, 27017, 6379, 8108 already in use)

Solution A: Stop the conflicting service on your host. Solution B: Change the host port mapping in docker-compose.yml (e.g., "5001:5000").

5. Container exits immediately with code 1

View the logs:

docker-compose logs reshma-api

Most likely an environment variable validation error – check your .env file matches the required schema.

6. Worker cannot connect to Redis

Ensure Redis is running and the REDIS_URL is correct. In development compose, it should be redis://reshma-redis:6379.

docker-compose restart reshma-worker

7. Out of memory (Typesense)

Typesense keeps the entire index in RAM. For local development, reduce the number of seeded products by modifying src/db/seed.ts (change 500 to 100).


Architecture Deep Dive

Internal Network

All services communicate via the reshma-network bridge network. Service names are resolvable as hostnames:

  • reshma-api → API container
  • reshma-worker → worker container
  • reshma-db → MongoDB
  • reshma-redis → Redis
  • reshma-typesense → Typesense

Healthchecks (Production only)

ServiceHealthcheck Command
reshma-dbmongosh --eval 'db.runCommand("ping").ok'
reshma-redisredis-cli -a $REDIS_PASSWORD ping
reshma-typesensewget -qO- http://localhost:8108/health
reshma-api(implicitly depends on the above)

Volumes (Persistent Data)

VolumeMounted PathPurpose
mongodb_data/data/dbMongoDB database files
redis_data/dataRedis persistence (RDB/AOF)
typesense_data/dataTypesense index (snapshots)

Warning: Removing volumes (docker-compose down -v) will delete all data.

Worker Service

The reshma-worker container runs the same image but overrides the command:

command: ["node", "dist/shared/queues/email.worker.js"]

It processes BullMQ jobs (email sending, data export, search sync retries). The worker does not expose any ports.


Next Steps

  • Read the Environment Variables Guide for production secrets.
  • Learn how to seed custom data for your local environment.
  • For production deployment, add a reverse proxy (Nginx/Traefik) in front of the API container.
  • Set up monitoring with docker stats or Prometheus + Grafana.

The Reshma-Core Team