Docker changed how many teams package and deploy applications. Combined with preview environments, you can ensure that what works in development works exactly the same way in your preview—and eventually in production.
Why Docker for Preview Environments?
Docker provides several advantages for preview environments:
- Consistency: Same container runs everywhere
- Isolation: Dependencies are bundled together
- Flexibility: Run self-contained web apps across common stacks
- Speed: Container images are cached and reused
Basic Docker Deployment
If your project has a Dockerfile, prev automatically detects and builds it:
prev create .
# Automatically detects Dockerfile and builds the image
Sample Dockerfile
Here's a basic Dockerfile for a Node.js application:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Deploying Pre-built Images
Already have an image in a registry? Deploy it directly:
prev create --image myregistry.io/myapp:latest --port 3000
Private Registry Authentication
For private registries, use an image reference that your deployment environment can pull. If your registry needs extra credentials, configure access before deploying the image.
Multi-Service Applications
prev is designed for one web container per preview. For databases, use managed databases and attach them with --db; for larger multi-service systems, keep a dedicated staging environment or deploy a self-contained image that exposes one HTTP port.
Attach a Managed Database
prev create . --db app-postgres
Environment Variables
Pass environment-specific variables to your containers:
prev create . --env NODE_ENV=preview \
--env API_KEY=$STAGING_API_KEY \
--env LOG_LEVEL=debug
Using .env Files
For multiple variables, use an env file:
prev create . --env-file .env.preview
Resource Configuration
Each preview gets a fixed resource profile based on the detected project type. For memory-heavy applications, keep the image lean and move durable state into a managed database or external service.
Health Checks
Ensure your container is healthy before the preview URL goes live:
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
Optimizing Docker Builds
Multi-stage Builds
Reduce image size with multi-stage builds:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
Layer Caching
Order your Dockerfile commands to maximize cache hits:
# Dependencies change less frequently
COPY package*.json ./
RUN npm ci
# Source code changes more frequently
COPY . .
RUN npm run build
Debugging Docker Previews
Access Container Logs
prev logs my-preview
Use Build Logs
If a source deployment fails during image build, open the build logs in the dashboard to see the failing Docker step and the most recent build output.
Best Practices
latestConclusion
Docker and preview environments are a practical match for self-contained web apps. With prev's Docker support, you can deploy the same container shape you expect to run elsewhere, without maintaining a shared staging server.
Start with a small Dockerfile, keep the image lean, and attach managed services only where the preview really needs them.