Optimizing Build and Deploy Speed
This guide covers best practices and configuration tips to significantly improve your build and deployment speed in Flightcontrol. Faster builds and deployments mean quicker feedback cycles, reduced costs, and more efficient development workflows.
Quick Wins
1. Make sure you are using Flightcontrol’s EC2-based build runners
Flightcontrol offers two build runner options:
- Flightcontrol EC2-based runner (Recommended): A dedicated build server that is started and stopped for each build, and is 2-6x faster than other systems due to local caching.
- AWS CodeBuild (Fallback): An AWS service that is slower and with limited caching support.
To configure the EC2-based runner, select the ec2
type in the ci
section of your service config. See full details in the Build Runners Documentation.
2. Reduce the health check interval
Health checks determine when your service is ready to receive traffic. Optimizing these two key settings can significantly reduce deployment time:
-
healthCheckTimeoutSecs
: Reduce to 2 seconds (default is 5)- This is how long the health check waits for a response before considering it a failure
- Shorter timeouts prevent waiting unnecessarily long for unresponsive services
- If your health check endpoint is lightweight, it should respond well within 2 seconds
-
healthCheckIntervalSecs
: Reduce to 5 seconds (default is 30)- This is how frequently health checks are performed
- 5 successful health checks are required before a service will start receiving traffic
- More frequent checks mean your service can be marked as healthy sooner
- This can reduce deployment and autoscaling time by several minutes
For more details on health check configuration, see the Web Service Health Check documentation.
3. For Next.js, skip TypeScript and ESLint checks in builds
For Next.js applications, you can significantly speed up builds by skipping certain checks during Flightcontrol builds (assuming you run these checks in your normal GitHub CI):
// next.config.js
module.exports = {
eslint: {
ignoreDuringBuilds: Boolean(process.env.FLIGHTCONTROL),
},
typescript: {
ignoreBuildErrors: Boolean(process.env.FLIGHTCONTROL),
},
}
Why this works:
- TypeScript and ESLint checks can add significant time to builds
- These checks are typically already run in your GitHub CI
- The
FLIGHTCONTROL
environment variable is automatically set during Flightcontrol builds
Build Optimizations
Nixpacks Optimization
For services using Nixpacks, Nixpacks can cache the installation phase if your package lock files haven’t changed. This is particularly effective for monorepos or projects with many dependencies.
See the dedicated guide to Speeding up Nixpacks Builds.
Dockerfile Optimization
For services using Dockerfiles, these optimizations can significantly improve build speed:
1. Cache dependency installation:
This will completely skip the installation phase if the package lock files haven’t changed.
# Copy dependency files first
COPY package.json package-lock.json ./
RUN npm ci
# Then copy source code (changes more frequently)
COPY . .
2. Use cache mounts for dependency installation:
These will speed up the installation phase by reusing the cache from previous builds.
Npm install:
RUN --mount=type=cache,id=npm-cache,target=/root/.npm npm ci
Pnpm install:
RUN --mount=type=cache,id=pnpm-cache,target=/root/.local/share/pnpm/store/v3 pnpm i --frozen-lockfile
Yarn install:
RUN --mount=type=cache,id=yarn-cache,target=/usr/local/share/.cache/yarn/v6 yarn install --check-cache
Python install:
RUN --mount=type=cache,id=pip-cache,target=/root/.cache/pip pip install -r requirements.txt
Ruby install:
RUN --mount=type=cache,id=gem-cache,target=/root/.gem bundle install
PHP install:
RUN --mount=type=cache,id=composer-cache,target=/tmp/cache composer install
Apt install:
RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=apt-lib-cache,target=/var/lib/apt,sharing=locked \
apt update && apt-get --no-install-recommends install -y gcc
3. Use cache mounts for build cache:
Next.js build cache:
# Make sure to set `target` to WORKDIR + path to .next/cache in the app your'e building
RUN --mount=type=cache,id=next-build-cache,target=/app/.next/cache next build
4. Use .dockerignore file:
Create a .dockerignore
file to exclude unnecessary files:
node_modules
.git
.github
*.md
.env*
5. Use smaller base images:
Container boot time is directly correlated with the size of the built image. Smaller images boot faster.
FROM node:18-alpine # Instead of node:18
6. Use multi-stage builds:
More complex to set up well, but it can reduce the size of the final image and speed up boot time.
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["npm", "start"]
Monitoring Build and Deploy Performance
After implementing these optimizations, monitor your build and deploy times in the Flightcontrol dashboard. Look for:
- Build duration
- Deploy duration
- Time to first health check pass
If you’re still experiencing slow builds or deployments after implementing these optimizations, contact Flightcontrol support for personalized assistance.