Configuring Web Services with flightcontrol.json
Web Service Attributes
The type for all web services is web
, and should be specified like the following:
type: 'web'
Common Service Configuration
Before configuring the web-specific options below, you should review the Common Service Configuration that applies to all service types. This includes important settings for:
- Name
- Environment variables
- Build configuration
- Pre & post deploy commands
- Watch paths
- And more…
Web-Specific Options
The following attributes are specific to web services:
Target
target.type: 'fargate' | 'ecs-ec2'
- Example:
"target": {"type": "fargate"}
- Defaults to
fargate
- Fargate is a fully managed, pay-as-you-go compute engine that lets you focus on building apps without managing servers. It’s the easiest to use. The tradeoffs are that it does not support GPUs or custom instance types, and can be up to 1.5 times more expensive than ECS+EC2, depending on how well you optimize the EC2 compute.
- ECS+EC2 is AWS’s version of Kubernetes. It gives you advance control over the cluster instance type and supports GPUs. It enables leveraging Reserved Instances for 50% or more savings. The tradeoffs are that 1) you have to manage the instance size to ensure there is enough CPU and memory for your app, 2) autoscaling is up to 2x slower if you don’t have empty EC2 instances on standby, and 3) you have to manage the config options optimize compute across instances to minimize wasted resources.
If target is fargate
: no other fields
If target is ecs-ec2
:
target.clusterInstanceSize: string
- Example:
"clusterInstanceSize": "t3.medium"
- Supported values: all non-ARM based instance sizes. See all instance options.
target.clusterMinInstances: number
- Example:
"clusterMinInstances": 1
- Minimum
1
- Fastest deploys are possible when this is at least 2x the number of app instances running
- Faster autoscaling is enabled when this is higher than minimum app instances so that machines are already running
target.clusterMaxInstances: number
- Example:
"clusterMaxInstances": 5
- Minimum same as
clusterMinInstances
- Must be high enough to accommodate 2x your app max instances count, otherwise deploys may fail
App CPU
cpu: number
- Example:
"cpu": 0.25
- Required
- Minimum value: 0.125
- This is the AWS
vCPU
unit for each service instance. It does not correspond to number of cores. It’s an abstract unit of CPU power defined by Amazon - Supported values:
- If target
fargate
:0.25, 0.5, 1, 2, 4, 8, 16
- For more details on Fargate configuration, see AWS’s Fargate pricing page
- If target
ecs-ec2
: range:0.125
to10
or the vCPU ofclusterInstanceSize
, whichever is less
- If target
App Memory
memory: number
- Example:
"memory": 1
- Required
- Minimum value: 0.125
- In gigabytes (or if value >= 512, then it is in megabytes)
- Supported values:
- If target
fargate
:- With
cpu: 0.25
-0.5, 1, 2
- With
cpu: 0.5
-1...4
(intervals of 1) - With
cpu: 1
-2...8
(intervals of 1) - With
cpu: 2
-4...16
(intervals of 1) - With
cpu: 4
-8...30
(intervals of 1) - With
cpu: 8
-16...60
(intervals of 4) - With
cpu: 16
-32...120
(intervals of 8)
- With
- If target
ecs-ec2
: range:0.125
to memory ofclusterInstanceSize
minus agent memory (0.25GB for instances ≤10GB, 0.5GB for >10GB)
- If target
App GPU
gpu: integer
- Example:
"gpu": 1
- Optional, with default:
0
- Range: 0 to 16
- This is how many GPUs to expose to your container
- Supported values:
- If target
fargate
:0
or unset - If target
ecs-ec2
: Range0
to the GPU ofclusterInstanceSize
(requires a GPU compatible instance size)
- If target
Storage
storage: int
- Example:
"storage": 20
- Support values:
20-200
- This is the ephemeral storage available to all containers running on your task. For example, this storage will be shared between your main application container and any sidecar containers (like the DataDog agent) if you are using them.
- By default, AWS sets this value to 20GB.
- For more details, see AWS’s Fargate task storage page
- Note: Storage is not permitted with ecs-ec2 target type
Number of App Instances
minInstances: int
- Example:
"minInstances": 1
- Optional with default:
1
- Supported values:
1+
- The minimum number of instances you want to be running. A minimum of 2 means there will be two containers running code from the same image.
maxInstances: int
- Example:
"maxInstances": 2
- Optional with default:
1
- Supported values:
1+
- Must be greater than or equal to
minInstances
- The maximum number of instances you want to be running. ECS will autoscale the number of instances based on your traffic up to this maximum. This number effectively sets a limit on AWS cost you may incur.
Autoscaling
autoscaling: object
- Example:
"autoscaling": {
"cpuThreshold": 60,
"memoryThreshold": 60,
"cooldownTimerSecs": 300,
"requestsPerTarget": 1000
},
- Optional
- Enables autoscaling for your service. For more, see our autoscaling guide.
For each service’s autoscaling configuration, you can configure the following attributes:
- cpuThreshold - The CPU threshold at which to scale up or down. For example,
60
would mean that if the average CPU usage across all instances is greater than 60%, then we will scale up. If it is less than 60%, then we will scale down. - memoryThreshold - The memory threshold at which to scale up or down. For example,
60
would mean that if the average memory usage across all instances is greater than 60%, then we will scale up. If it is less than 60%, then we will scale down. - cooldownTimerSecs - The cooldown timer in seconds. This is the amount of time to wait after scaling up or down before scaling again. For example,
300
would mean that we will wait 5 minutes after scaling up or down before scaling again. - requestsPerTarget - The number of requests per target. This is the number of requests per minute that each instance can handle. For example,
1000
would mean that each instance can handle 1000 requests per minute.
Domain and Port
domain: string
-
Example:
"domain": "www.example.com"
-
Optional, defaults to a random url like
123456789.cloudfront.net
-
Wildcard domains are supported:
"domain": "*.example.com"
The httphost
header will contain the specific domain that’s being used. -
Must be a valid domain name
-
See our recommendation and detailed setup info for custom domains
port: number
-
Example:
"port": 8080
-
Optional with default:
3000
-
The internal HTTP port that your server is listening to. We’ll direct incoming traffic to this.
-
We automatically set the
PORT
environment variable to whatever you configure here
Health Check
healthCheckPath: string
- Example:
"healthCheckPath": "/health"
- Optional with default:
"/"
- Must begin with a ’/’ character and can only contain printable ASCII characters without spaces
- HTTP status codes that signals healthy:
200-399
- This is used during deployment to ensure the server is healthy before traffic is routed to it. And during runtime, to automatically replace unhealthy servers. If you notice that your app is in a cycle of working and not working, it could be your health check path is returning an error causing the to keep restarting your server.
healthCheckGracePeriodSecs: number
- Example:
"healthCheckGracePeriodSecs": 20
- Optional with default:
0
- Range:
0
to2147483647
- The time the ECS service waits before allowing health checks from the load balancer for new servers. This is used during deploy and during autoscaling. Adding a high value will increase the time it takes for new servers to start receiving traffic. This might negatively impact your service if all servers crash, as it will take longer to replace them. You should build your containers in a way that reduce any start up activities, and the servers should immediately start and be ready to serve traffic.
- Recommended to only increase if you have a slow server that takes significant time to start up
healthCheckTimeoutSecs: number
- Example:
"healthCheckTimeoutSecs": 2
- Optional with default:
5
- Range:
2
to120
- Recommended to be as low as possible to quickly detect unhealthy servers
- The server must respond to the health check request within this time, otherwise the health check will fail.
healthCheckIntervalSecs: number
- Example:
"healthCheckIntervalSecs": 30
- Optional with default:
30
- Range:
5
to300
, must be greater thanhealthCheckTimeoutSecs
- Recommended to be as low as possible to speed up deploy and autoscaling
- The interval between health checks. Reducing this value will increase the load on your server, and increasing it will increase the time it takes to discover an unhealthy server.
Container Insights
containerInsights: boolean
- Example:
"containerInsights": true
- Optional with default:
false
- Enables AWS Container Insights for your service. This will send metrics to CloudWatch for your service. For more, see our Container Insights guide.
Sticky Sessions
stickySessionsEnabled: boolean
- Example:
"stickySessionsEnabled": true
- Optional with default:
false
- Sticky sessions will route all requests from a client to the same container. Do not enable unless you have a special requirement for this because it reduces the efficiency of the load balancer.
stickySessionsDurationSecs: number
- Example:
"stickySessionsDurationSecs": 3600
- Optional with default:
86400
(24 hours) - The time period, in seconds, during which requests from a client should be routed to the same container.
Docker Labels
dockerLabels: Record<string, string>
- Example:
"dockerLabels": {"com.example.vendor": "ACME"}
- Optional
- Will apply the set labels to the container
Version History Count
versionHistoryCount: number
- Example:
"versionHistoryCount": 15
- Optional with default:
10
- How many previous container images to keep in ECR. This determines how far back you can rollback. ECR storage is $0.10 per GB / month, so this configuration is balance between cost and rollback history.
Runtime-only Environment variables
includeEnvVariablesInBuild: boolean
- Example:
"includeEnvVariablesInBuild": false
- Optional with default:
true
- Exclude environment variables from the build environment - see the Configuring Environment Variables page for more details.
Sidecars
sidecars: array
- Example:
"sidecars": [
{
"name": "open-telemetry-collector",
"image": "otel/opentelemetry-collector-contrib:0.83.0",
"cpuAllotment": 0.1,
"memoryAllotment": 0.25,
"enableNetworking": true,
"ports": [4318],
"logging": false,
"essential": false,
"dockerLabels": {},
"envVariables": {}
}
]
- Optional
- Array of sidecar container configurations
- Each sidecar container supports:
name
(required): string - The name of the sidecar containerimage
(required): string - The URL to the image for the sidecar containercpuAllotment
(required): number - The absolute amount of CPU to allocate (minimum 0)memoryAllotment
(required): number - The absolute amount of memory to allocate in GB (minimum 0)enableNetworking
: boolean - Whether to enable networking (default: true)ports
: number[] - Array of ports to expose (optional)logging
: boolean - Whether to enable logging (default: false)dockerLabels
:Record<string, string>
- Docker labels to set (optional)essential
: boolean - Whether the container is essential (default: false)startCommand
: string | string[] - Command to run when starting the container (optional)envVariables
: object - Environment variables for the container (optional)
Logging
logging: object
- Optional
- Fields:
cloudwatchLogsEnabled
: boolean (default: true) - Whether to enable CloudWatch loggingcloudwatchLogsRetentionDays
: number (optional) - Number of days to retain logs- Must be one of: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653
ecsLogsMetadataEnabled
: boolean (default: false) - Whether to add ECS metadata to logsfirelens
: object (optional) - Firelens configuration- See Firelens docs and examples for more details
- Fields:
configSource
: string (required) - Either"inline"
or"file"
configFilePath
: string (required if configSource is"file"
) - Path to the config file in repoconfig
: array (required if configSource is"inline"
) - Array of plugin configurations:name
: string (required) - Name of the output plugin (e.g., “datadog”)match
: string (required) - Pattern to match from log stream (e.g., ”*”)options
: object (required) - Plugin-specific options (e.g.,{"api_key": "1234"}
)
- When using
configSource: "inline"
:{ "firelens": { "configSource": "inline", "config": [ { "name": "datadog", "match": "*", "options": { "api_key": "1234", "dd_tags": "project:fluentbit" } } ] } }
- When using
configSource: "file"
:{ "firelens": { "configSource": "file", "configFilePath": "firelens.conf" } }
Privileged Mode
privileged: boolean
- Example:
"privileged": true
- Optional with default:
false
- Only supported for
ecs-ec2
target type - When enabled, the container will run with elevated privileges
Integrations
integrations: object
Under the integrations
key, you can configure integrations with third-party services. At this time, the only supported integration is with Sentry.
Upload Sentry Source Maps
uploadSentrySourceMap: boolean
- Example:
"integrations": { "uploadSentrySourceMap": true }
- Optional with default:
false
- Enables uploading source maps to Sentry. This is useful for debugging errors in production. For more, see our Sentry guide.
Extra options for Nixpacks build type
basePath?: string
(only supported when buildType: nixpacks
)
- Example:
"basePath": "./apps/frontend"
- Optional, defaults to
.
- The directory containing your application code, relative to the repository root
- Allows you to specify in which folder the following build commands should run
installCommand: string
- Example:
"installCommand": "./install.sh"
- Optional, intelligent default based on your language and framework detected at the
basePath
- What we use to install dependencies for your build
buildCommand: string
- Example:
"buildCommand": "blitz build"
- Optional, intelligent default based on your language and framework detected at the
basePath
- What we use to build your app
postBuildCommand: string
- Example:
"postBuildCommand": "./postBuildCommand.sh"
- Optional, Empty by Default
- Used as a build hook to run any operation after your build is complete
- Note:
buildCommand
must be set forpostBuildCommand
to be used
startCommand: string
- Example:
"startCommand": "blitz start"
- Optional, intelligent default based on your language and framework detected at the
basePath
- What we use to start your app
Extra options for Dockerfile build type
dockerfilePath: string
- Example:
"dockerfilePath": "packages/web/Dockerfile"
- Relative path to the Dockerfile from your repo root
- It’s recommended to use
ENTRYPOINT
instead ofCMD
for your start command - You can authenticate with Docker Hub by adding your Docker Hub credentials as
DOCKER_USERNAME
andDOCKER_PASSWORD
environment variables. If these env variables are present, we’ll rundocker login
with them. This will prevent Docker Hub rate limit issues.
dockerContext: string
- Example:
"dockerContext": "packages/web"
- Optional with default: the directory containing the Dockerfile
- The build context for the Docker build. This is the directory that will be sent to the Docker daemon for building the image.
startCommand: Array<string>
- Example:
"startCommand": ["node", "index.js"]
- Optional
- You can set this to override the CMD in your Dockerfile
- The command must be split into array parts
injectEnvVariablesInDockerfile: boolean
- Example:
"injectEnvVariablesInDockerfile": false
- Optional with default:
true
- Whether to inject environment variables automatically into Dockerfile or not
- It’s recommended to use Docker build secrets to control how environment variable are used during build, check the guide here
Extra options for From Service build type
containerImage.fromService: string
- Example:
"containerImage": { "fromService": "my-api" }
- Required (non-empty string)
- The Given ID of the service that will be used as the source for the container image. The service specified here needs to be built by Flightcontrol.
Extra options for From Repository build type
Example:
"containerImage": {
"registryId": "ecr-9l03731",
"repository": "node:18-slim",
"tag": "latest"
}
containerImage.registryId: string
- Example:
"registryId": "ecr-9l03731"
- Required (non-empty string)
- Registry ID in Flightcontrol, you can find this on the Registries page under Organization Settings
containerImage.repository: string
- Example:
"repository": "node:18-slim"
- Required (non-empty string)
- This is the URI of the image repository you wish to access
containerImage.tag?: string
- Example:
"tag": "latest"
- Optional with default:
"latest"
- Must be non-empty string when provided
- This is the tag of the image from the repository that you would like to use