Overview
The single-instance Docker deployment runs CryptoPulse with PostgreSQL and Redis in isolated containers. This setup is ideal for development, testing, and small-scale production environments.
Prerequisites
Before you begin, ensure you have:
Docker Engine 20.10+
Docker Compose v2.0+
At least 2GB of available RAM
Port 3000 available on your host machine
Quick Start
Clone the repository
git clone https://github.com/your-org/cryptopulse.git
cd cryptopulse
Configure environment variables
Copy the example environment file and update it with your settings: Edit .env and set the required variables: PORT = 3000
ADMIN_USER = admin
ADMIN_PASS = your-secure-password
JWT_SECRET = your-secret-key-min-32-chars
JWT_EXPIRES_IN = 1h
DATABASE_URL = postgres://postgres:postgres@postgres:5432/crypto_pulse
REDIS_URL = redis://redis:6379
COINGECKO_API_KEY = your-coingecko-api-key
COINGECKO_BASE_URL = https://api.coingecko.com
Make sure to change ADMIN_PASS and JWT_SECRET to secure values before deploying to production.
Start the services
Build and start all containers: docker compose up --build
For detached mode (running in background): docker compose up --build -d
Verify deployment
Check that all services are healthy: Access the Swagger documentation at: http://localhost:3000/docs
Docker Compose Configuration
The docker-compose.yml file defines three services:
services :
postgres :
image : postgres:16-alpine
environment :
POSTGRES_DB : crypto_pulse
POSTGRES_USER : postgres
POSTGRES_PASSWORD : postgres
ports :
- '5432:5432'
volumes :
- postgres-data:/var/lib/postgresql/data
healthcheck :
test : [ 'CMD-SHELL' , 'pg_isready -U postgres -d crypto_pulse' ]
interval : 5s
timeout : 5s
retries : 10
redis :
image : redis:7-alpine
ports :
- '6379:6379'
healthcheck :
test : [ 'CMD' , 'redis-cli' , 'ping' ]
interval : 5s
timeout : 5s
retries : 10
api :
build :
context : .
env_file :
- .env
ports :
- '3000:3000'
depends_on :
postgres :
condition : service_healthy
redis :
condition : service_healthy
volumes :
postgres-data :
Service Breakdown
PostgreSQL Database
Uses PostgreSQL 16 Alpine for minimal size
Persists data in a Docker volume
Health checks ensure the database is ready before API starts
Redis Cache
Redis 7 Alpine for batching coordination and throttling
Required for multi-instance deployments
Health checks verify connectivity
API Service
Built from the Dockerfile in the repository root
Waits for both PostgreSQL and Redis to be healthy
Exposes port 3000 for HTTP traffic
Dockerfile Build Process
The application uses a multi-stage build for optimal image size:
FROM node:22-alpine AS deps
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN pnpm install
FROM node:22-alpine AS builder
WORKDIR /app
RUN corepack enable
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm run build
FROM node:22-alpine AS runner
WORKDIR /app
RUN corepack enable
ENV NODE_ENV=production
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod
COPY --from=builder /app/.env ./.env
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD [ "node" , "dist/main.js" ]
Build Stages:
deps : Installs all dependencies
builder : Compiles TypeScript to JavaScript
runner : Production image with only runtime dependencies
Managing the Deployment
View Logs
All Services
API Only
PostgreSQL Only
Stop Services
To also remove volumes (deletes all data):
Restart a Service
docker compose restart api
Rebuild After Code Changes
docker compose up --build api
Accessing Services
Service URL Purpose API http://localhost:3000Main API endpoints Swagger UI http://localhost:3000/docsInteractive API documentation PostgreSQL localhost:5432Database connection (for debugging) Redis localhost:6379Redis connection (for debugging)
Data Persistence
PostgreSQL data is stored in a Docker volume named postgres-data. This ensures your data persists across container restarts.
To backup your database:
docker compose exec postgres pg_dump -U postgres crypto_pulse > backup.sql
To restore from backup:
cat backup.sql | docker compose exec -T postgres psql -U postgres crypto_pulse
Troubleshooting
API Won’t Start
Check that PostgreSQL and Redis are healthy:
Both should show “healthy” status. If not, check their logs:
docker compose logs postgres
docker compose logs redis
Port Already in Use
If port 3000 is already in use, modify the port mapping in docker-compose.yml:
api :
ports :
- '8080:3000' # Use port 8080 on host instead
Connection Errors
When running inside Docker Compose, always use service names (e.g., postgres, redis) in connection URLs, not localhost.
Correct .env configuration:
DATABASE_URL = postgres://postgres:postgres@postgres:5432/crypto_pulse
REDIS_URL = redis://redis:6379
Next Steps