Deployment Guide
Relevant source files
The following files were used as context for generating this wiki page:This guide provides a comprehensive overview of the deployment process for the e-commerce microservices platform. The system is designed to be deployed using Docker and Docker Compose, with a clear separation of services, a centralized message broker (NATS), and externalized PostgreSQL databases. The process involves building versioned Docker images, pushing them to a Docker registry, and deploying them to individual hosts.
The deployment strategy emphasizes automation, scalability, and consistency. It leverages shell scripts for building and deploying, environment variables for configuration, and a CI/CD pipeline for automated builds, testing, and publishing. For more information on local development, see the Setup Guide.
Sources: deploys/README.md:3-5, QUICK_START.md:3-5
Architecture Overview
The deployment architecture consists of multiple hosts, each running one or more microservices as Docker containers. All services communicate via a central NATS server and connect to a central PostgreSQL server that hosts multiple databases, one for each service. Docker images are pulled from a central Docker Registry (Docker Hub).
Sources: deploys/README.md:11-38
The following diagram illustrates the high-level deployment architecture.
Sources: deploys/README.md:11-38
Prerequisites
Before deploying, ensure the following requirements are met for the infrastructure.
| Component | Requirement |
|---|---|
| Each App Host | Docker 20.10+, Docker Compose 2.0+, 2GB RAM minimum, Internet access. |
| PostgreSQL Server | PostgreSQL 14+, 4GB RAM minimum, Network access on port 5432 from app hosts. |
| NATS Server | NATS 2.8+, Network access on port 4222 from app hosts. |
Sources: deploys/README.md:42-58
Deployment Process
The deployment process is divided into three main phases: one-time initial setup, building and pushing images, and deploying services to their respective hosts.
Phase 1: Initial Setup (One-Time)
This phase prepares the database, infrastructure, and code repository for the first deployment.
-
Generate Migrations: Before building any images, initial database migrations must be generated locally. This ensures the migration files are included in the Docker image.
# Generate Prisma clients and migrations for all apps pnpm run db:migrate:all # Commit the new migration files git add apps/*/prisma/migrations/ git commit -m "chore: initial database migrations for all services" git pushSources: deploys/README.md:64-87, QUICK_START.md:10-15
-
Setup PostgreSQL Server: A PostgreSQL instance must be running and accessible to all app hosts. You can use Docker or a managed service. After setup, create the required databases for each microservice.
CREATE DATABASE user_db; CREATE DATABASE product_db; -- ... and so on for order_db, cart_db, etc.Sources: deploys/README.md:92-111
-
Setup NATS Server: A NATS instance must be running for inter-service communication.
docker run -d --name nats -p 4222:4222 -p 8222:8222 nats:alpineSources: deploys/README.md:113-121
-
Setup Docker Hub: Create a Docker Hub account and a Personal Access Token with
Read & Writepermissions. This token will be used as theDOCKER_PASSWORDfor authentication.
Sources: DOCKER_HUB_SETUP.md:17-46
Phase 2: Build and Push Images
This phase packages the applications into Docker images and pushes them to Docker Hub. This can be done manually using scripts or automatically via the CI/CD pipeline.
The overall flow is as follows:
Manual Build & Push
On a local machine or a dedicated build server, execute the provided scripts.
# Set environment variables
export DOCKER_USERNAME=your_docker_username
export VERSION=v1.0.0
# Build all images
./scripts/build-all-images.sh
# Push all images to Docker Hub
./scripts/push-all-images.sh
Sources: QUICK_START.md:21-26, deploys/README.md:134-146
Automated CI/CD Pipeline
The repository is configured with GitHub Actions to automate this process.
- On every push/PR to
mainordevelop: A workflow runs to lint, build, scan, and test the Docker images. - On push to
mainor a git tag (e.g.,v1.0.0): A workflow builds and pushes the images to Docker Hub, tagging them withlatestor the git tag version.
This requires setting DOCKER_USERNAME and DOCKER_PASSWORD (the access token) as secrets in the GitHub repository settings.
Sources: CI_CD_SETUP.md:5-25, 30-40
Phase 3: Deploy Services to Hosts
With the images available in Docker Hub, the final phase is to deploy each service to its designated host using the deploy.sh script.
The deploy.sh Script
This script automates the deployment of a single microservice on a host.
Usage: ./deploy.sh <app-name>
The script performs the following actions:
- Validates that an
<app-name>is provided and that the corresponding<app-name>.ymlDocker Compose file exists. - Checks for and loads the
.envfile. - Pulls the specified image version from Docker Hub.
- Stops any existing container for the service.
- Starts the new container in detached mode (
-d). - Checks the final status and tails the logs.
Sources: deploys/deploy.sh:4-89
The following sequence diagram illustrates the script's execution flow.
Sources: deploys/deploy.sh
Deployment Steps
- SSH into the target host.
- Clone the repository:
git clone <repo> backend-luan-van. - Navigate to the
deploysdirectory:cd backend-luan-van/deploys. - Configure Environment: Copy
.env.exampleto.envand fill in the required values. - Run Deployment: Execute
./deploy.sh <app-name>. For example, on the gateway host, run./deploy.sh gateway.
Sources: deploys/README.md:158-171
Configuration
All deployment configurations are managed through an .env file located in the deploys/ directory. This file must be created from .env.example and should never be committed to version control.
| Variable | Description | Example |
|---|---|---|
DOCKER_USERNAME | Your Docker Hub username. | haongo123 |
VERSION | The version tag of the Docker images to pull. | v1.0.0 or latest |
NATS_URL | The connection URL for the NATS server. | nats://nats-server-ip:4222 |
DATABASE_URL_USER | PostgreSQL connection string for the User service. | postgresql://postgres:password@db-server:5432/user_db |
DATABASE_URL_PRODUCT | PostgreSQL connection string for the Product service. | postgresql://postgres:password@db-server:5432/product_db |
... | (Similar DATABASE_URL_* for other services) | ... |
CORS_ORIGIN | CORS origins for the Gateway. | http://localhost:3000,https://yourdomain.com |
LOG_LEVEL | The log level for the applications. | debug |
NODE_ENV | The Node.js environment. | production |
Sources: deploys/README.md:218-237, QUICK_START.md:43-56
Critical Startup Order
For the system to initialize correctly, services must be started in a specific order. Failure to do so can result in JWT verification errors at the Gateway, as it may not have received the public key from the User service via NATS.
The correct startup sequence is:
- PostgreSQL Server
- NATS Server
user-app(waits 60 seconds for dependencies and publishes JWT public key)gateway(waits 30 seconds to receive the public key)- All other microservices
Common Commands
The following commands are useful for managing and troubleshooting the deployed services on a host.
| Task | Command |
|---|---|
| View Logs | docker compose -f <app-name>.yml logs -f |
| Restart Service | docker compose -f <app-name>.yml restart <app-name> |
| Pull New Version | export VERSION=v1.1.0 && docker compose -f <app-name>.yml pull && docker compose -f <app-name>.yml up -d |
| Check Status | docker compose -f <app-name>.yml ps |
| Run Migrations | docker compose -f <app-name>.yml exec <app-name> npx prisma migrate deploy --schema=... |