Overview
The build system uses Docker containers to provide isolated, reproducible builds for every deployment. Each project is built in its own ephemeral container, ensuring build consistency and preventing dependency conflicts.Architecture
All builds run in isolated Docker containers with Node.js 20 Alpine Linux, providing a lightweight and consistent build environment.
Build Process
Download Source Files
The deploy service downloads the project source from S3Implementation: The function:
deploy-service/src/utils/donwloadS3Folde.ts:13-64- Lists all objects with the deployment ID prefix
- Creates necessary directory structure locally
- Downloads files in parallel using streams
- Recreates the original project structure
Generate Dockerfile
A Dockerfile is dynamically created for each buildImplementation:
deploy-service/src/utils/buildProject.ts:10-19Dockerfile Breakdown
Dockerfile Breakdown
- Base Image:
node:20-alpine- Lightweight Node.js 20 runtime (~170MB) - Stage Name:
builder- Multi-stage build preparation - Working Directory:
/app- Standard application directory - Dependency Installation: Copies package files first for layer caching
- Source Copy: Copies entire project after dependencies
- Build Command: Runs
npm run buildfrom package.json
Execute Docker Build
The system runs a series of Docker commands to build and extract outputImplementation:
deploy-service/src/utils/buildProject.ts:21-55Extract Build Output
The built files are copied from the container to the host filesystemThe system tries two common output directories:
/app/build(Create React App, Next.js)/app/dist(Vite, Vue, general bundlers)
The
|| operator ensures fallback: if /app/build doesn’t exist, it tries /app/dist instead.Upload Built Assets
Final build output is uploaded to S3 for hostingImplementation: S3 Structure:
deploy-service/src/utils/buildProject.ts:73-81Docker Command Breakdown
Let’s examine each Docker command in detail:- docker build
- docker create
- docker cp
- Cleanup Commands
-t frontend-build-${lowerCaseId}: Tags image with deployment ID.: Uses current directory as build context- Example tag:
frontend-build-ab3xk9mp2q
/app/build or /app/distBuild Output Handling
The system intelligently handles different build tools and their output directories:/app/build
Used by:
- Create React App
- Next.js (
next build && next export) - Gatsby
- Some custom setups
/app/dist
Used by:
- Vite
- Vue CLI
- Parcel
- Most bundlers
Build Monitoring
The build process includes real-time output streaming: Implementation:deploy-service/src/utils/buildProject.ts:48-54
- Docker build steps and layer caching
- npm install progress and warnings
- Build command output and errors
- File sizes and optimization stats
Error Handling
Build Failure Scenarios
Build Failure Scenarios
1. Docker Build FailuresCommon causes:Occurs during final asset upload to S3.
- Missing
package.json - Invalid dependencies
- Build script errors
- Out of memory
- If neither
/app/buildnor/app/distexists, docker cp fails - Usually indicates build script didn’t run or failed silently
- Docker not running
- Insufficient permissions
- Disk space exhausted
Performance Optimizations
Layer Caching
Dependencies are copied before source code:This allows Docker to cache the dependency layer when only source code changes.
Build Environment Variables
AWS Configuration:AWS_ACCESS_KEY_ID: AWS access credentialsAWS_SECRET_ACCESS_KEY: AWS secret credentialsAWS_REGION: S3 bucket region
Key Implementation Files
| File | Lines | Purpose |
|---|---|---|
deploy-service/src/utils/buildProject.ts | 1-81 | Core build logic, Docker orchestration |
deploy-service/src/utils/donwloadS3Folde.ts | 13-64 | S3 source download |
deploy-service/src/server.ts | 11-27 | Build queue consumer |
Next Steps
Deployment Process
Understand the full deployment pipeline
Queue Management
Learn how builds are queued and processed