Skip to main content
Vercel For Frontend uses Docker to build frontend projects in isolated containers. The deploy service creates temporary Docker images for each project, runs the build, and extracts the output.

How Docker is Used

The build process (deploy-service/src/utils/buildProject.ts:22) follows these steps:
  1. Create Dockerfile: Generates a Node.js 20 Alpine-based Dockerfile in the project directory
  2. Build Image: docker build -t frontend-build-{id} .
  3. Create Container: docker create --name build-container-{id}
  4. Extract Build Output: docker cp the /app/build or /app/dist folder
  5. Cleanup: Remove container and image
Docker must be installed and the daemon must be running for builds to work.

Installation

1

Download Docker Desktop

Download Docker Desktop from docker.com.
2

Install Docker

  1. Open the downloaded .dmg file
  2. Drag Docker to Applications folder
  3. Launch Docker from Applications
  4. Follow the setup wizard
3

Start Docker

Docker Desktop should start automatically. Look for the Docker icon in the menu bar.
Allow Docker to access your filesystem when prompted.
4

Verify Installation

docker --version
docker run hello-world
You should see version information and a welcome message.

Post-Installation Setup

Add User to Docker Group (Linux)

Avoid using sudo for every Docker command:
sudo usermod -aG docker $USER
newgrp docker
Log out and back in for changes to take effect.
The docker group grants privileges equivalent to root. Only add trusted users.
Test without sudo:
docker run hello-world

Configure Docker Daemon

Optimize Docker for build performance:
Create or edit /etc/docker/daemon.json:
/etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "default-address-pools": [
    {
      "base": "172.17.0.0/16",
      "size": 24
    }
  ]
}
Restart Docker:
sudo systemctl restart docker

Testing Docker for Builds

Test the exact build process used by the platform:
1

Create Test Project

mkdir test-build
cd test-build
Create a simple package.json:
package.json
{
  "name": "test-project",
  "version": "1.0.0",
  "scripts": {
    "build": "echo 'Build successful' && mkdir -p dist && echo '<h1>Test</h1>' > dist/index.html"
  }
}
2

Create Dockerfile

Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
This matches the Dockerfile generated in buildProject.ts:12.
3

Build Image

docker build -t test-frontend-build .
Should complete without errors.
4

Create Container

docker create --name test-container test-frontend-build
5

Extract Build Output

docker cp test-container:/app/dist ./output
Verify output:
ls -la output/
cat output/index.html
6

Cleanup

docker rm test-container
docker rmi test-frontend-build
rm -rf output
cd ..
rm -rf test-build
If all steps succeed, Docker is correctly configured for the platform’s build process.

Docker Daemon Management

Check Docker Status

sudo systemctl status docker

Start/Stop Docker

# Start
sudo systemctl start docker

# Stop
sudo systemctl stop docker

# Restart
sudo systemctl restart docker

Auto-Start on Boot

sudo systemctl enable docker

Monitoring and Cleanup

Monitor Running Builds

# List running containers
docker ps

# Watch container logs
docker logs -f build-container-{id}

# Monitor resource usage
docker stats

Clean Up Build Artifacts

The platform automatically removes containers and images after builds, but orphaned resources can accumulate:
# Remove stopped containers
docker container prune -f

# Remove unused images
docker image prune -a -f

# Remove build cache
docker builder prune -f

# Nuclear option (removes everything)
docker system prune -a --volumes -f
docker system prune removes ALL unused containers, images, networks, and volumes. Use with caution.

Automated Cleanup

Schedule regular cleanup with cron (Linux/macOS):
crontab -e
Add:
# Clean Docker weekly on Sunday at 2 AM
0 2 * * 0 docker system prune -f

Troubleshooting

Error: Cannot connect to the Docker daemonSolutions:
# Check status
sudo systemctl status docker

# Start daemon
sudo systemctl start docker

# Check logs
sudo journalctl -u docker -n 50
Error: permission denied while trying to connect to the Docker daemon socketSolutions:
# Add user to docker group
sudo usermod -aG docker $USER

# Apply group changes
newgrp docker

# Or log out and back in

# Test
docker ps
Error: Execution error: Command failedSolutions:
  • Check Docker daemon is running: docker info
  • Verify Node.js image is available: docker pull node:20-alpine
  • Check disk space: df -h
  • View build logs: docker logs build-container-{id}
  • Test build manually:
    cd dist/output/{id}
    docker build -t test-build .
    
Error: no space left on deviceSolutions:
  • Check Docker disk usage: docker system df
  • Clean up:
    docker system prune -a --volumes
    
  • Increase Docker Desktop disk limit (Settings → Resources → Disk image size)
  • Move Docker data directory (Linux):
    /etc/docker/daemon.json
    {
      "data-root": "/new/path/to/docker"
    }
    
Symptom: Builds hang indefinitelySolutions:
  • Check container status: docker ps -a | grep build-container
  • Kill stuck containers:
    docker kill build-container-{id}
    docker rm build-container-{id}
    
  • Increase timeout in buildProject.ts (modify exec options)
  • Check network connectivity for npm install
Error: Error response from daemon: container is runningSolutions:
# Stop container first
docker stop build-container-{id}

# Force remove
docker rm -f build-container-{id}

# If still stuck, restart Docker daemon
sudo systemctl restart docker

Performance Optimization

Use BuildKit

Enable Docker BuildKit for faster builds:
export DOCKER_BUILDKIT=1
Or configure permanently:
/etc/docker/daemon.json
{
  "features": {
    "buildkit": true
  }
}

Allocate More Resources

Docker Desktop → Settings → Resources:
  • CPUs: Allocate 50-75% of available cores
  • Memory: At least 4GB, 8GB recommended
  • Swap: 2GB
  • Disk: 60GB+ for multiple builds

Cache npm Dependencies

Modify the Dockerfile to cache node_modules:
FROM node:20-alpine AS builder
WORKDIR /app

# Copy package files first (cached layer)
COPY package*.json ./
RUN npm ci --only=production

# Copy source (changes frequently)
COPY . .
RUN npm run build

Security Best Practices

Run Rootless Docker

Run Docker daemon as non-root user:
# Install rootless Docker
curl -fsSL https://get.docker.com/rootless | sh

# Enable at startup
systemctl --user enable docker

Scan Images for Vulnerabilities

# Scan Node.js image
docker scan node:20-alpine

# Enable automatic scanning
docker scan --accept-license

Limit Container Resources

Prevent resource exhaustion:
docker run --memory="512m" --cpus="1.0" \
  image-name

Use Read-Only Filesystem

docker run --read-only \
  --tmpfs /tmp \
  image-name

Next Steps

Environment Variables

Configure all required environment variables

Quick Start

Start deploying your first project

Build docs developers (and LLMs) love