Service
A Service is a horizontally-scalable collection of durable Processes.
Processes that belong to a Service are automatically restarted upon termination.
Services can be scaled to a static count or autoscaled in a range based on metrics.
Service Definition
services:
web:
build: .
health: /check
port: 5000
scale: 3
services:
grpc:
build: .
port: grpc:5551
grpcHealthEnabled: true
services:
web:
agent: false
annotations:
- test.annotation.org/value=foobar
build:
manifest: Dockerfile
path: .
certificate:
duration: 2160h
command: bin/web
deployment:
minimum: 25
maximum: 100
domain: ${WEB_HOST}
dnsConfig:
ndots: 5
environment:
- FOO
- BAR=qux
health:
grace: 10
interval: 5
path: /check
timeout: 3
liveness:
path: /liveness/check
grace: 15
interval: 5
timeout: 3
successThreshold: 1
failureThreshold: 3
internal: false
initContainer:
command: "bin/migrate"
ingressAnnotations:
- nginx.ingress.kubernetes.io/limit-rpm=10
labels:
convox.com/test: true
lifecycle:
preStop: "sleep 10"
postStart: "sleep 10"
port: 5000
ports:
- 5001
- port: 5002
protocol: udp
privileged: false
scale:
count: 1-3
limit:
cpu: 500
memory: 1024
cpu: 250
memory: 512
targets:
cpu: 50
memory: 80
external:
- name: "datadogmetric@default:web-requests"
averageValue: 200
singleton: false
sticky: true
termination:
grace: 45
test: make test
timeout: 180
tls:
redirect: true
whitelist: 10.0.0.128/16,192.168.0.1/32
| Attribute | Type | Default | Description |
|---|---|---|---|
| agent | boolean | false | Set to true to declare this Service as an Agent |
| annotations | list | A list of annotation keys and values to populate the metadata for the deployed pods and their serviceaccounts | |
| accessControl | map | Specification of the pod access control management. Currently only IAM using AWS pod identity is supported | |
| build | string/map | . | Build definition (see below) |
| certificate | map | Define certificate parameters | |
| command | string | CMD of Dockerfile | The command to run to start a Process for this Service |
| deployment | map | Manual control over deployment parameters | |
| domain | string | A custom domain(s) (comma separated) to route to this Service | |
| dnsConfig | map | DNS configuration for the service | |
| environment | list | A list of environment variables (with optional defaults) to populate from the Release environment | |
| grpcHealthEnabled | boolean | false | Enables gRPC health checking (configures both readiness and liveness probes). Must follow the gRPC health protocol. See Health Checks. |
| health | string/map | / | Health check definition (see below) |
| liveness | map | Liveness check definition (see below). By default it is disabled. If it fails then service will restart | |
| startupProbe | map | Startup probe definition. Set path (HTTP) or tcpSocketPort (TCP) to enable. All timing parameters are inherited from the liveness check; setting timing fields directly on startupProbe has no effect. See Health Checks |
|
| image | string | An external Docker image to use for this Service (supersedes build) | |
| ingressAnnotations | list | A list of annotation keys and values to add in ingress resource. Check below for reserved annotation keys | |
| initContainer | map | Runs a container to completion before the main service container starts. Use for migrations, dependency checks, or setup tasks (see initContainer below) | |
| internal | boolean | false | Set to true to make this Service only accessible inside the Rack |
| internalRouter | boolean | false | Set to true to make this Service only accessible using the internal load balancer. Requires the rack parameter internal_router to also be true. |
| init | boolean | true | Set to false to disable the init process for this Service. When enabled, an init process runs as PID 1 and handles signal forwarding and zombie process reaping |
| labels | map | Custom labels for k8s resources. See here for syntax and character set. The following keys are reserved: system, rack, app, name, service, release, type |
|
| lifecycle | map | The prestop and poststart hooks enable running commands before terminating and after starting the container, respectively | |
| configMounts | list | Mount configuration files into the container filesystem. See Config Mounts | |
| nodeAffinityLabels | map | Node affinity rules for workload placement. See Workload Placement | |
| nodeSelectorLabels | map | Node selector labels for workload placement. See Workload Placement | |
| port | string | The port that the default Rack balancer will use to route incoming traffic. For grpc service specify the scheme: grpc:5051 |
|
| ports | list | A list of ports available for internal service discovery or custom Balancers. Supports TCP (default) and UDP protocols | |
| privileged | boolean | false | Set to true to allow Processes of this Service to run as root inside their container. Use with caution as this grants elevated permissions |
| resources | list | A list of Resources to make available to this Service (e.g. databases) | |
| scale | map | 1 | Define scaling parameters (see below) |
| singleton | boolean | false | Set to true to prevent extra Processes of this Service from being started during deployments |
| sticky | boolean | false | Set to true to enable sticky sessions |
| termination | map | Termination related configuration | |
| test | string | A command to run to test this Service when running convox test | |
| timeout | number | 60 | Timeout period (in seconds) for reading/writing requests to/from your service |
| tls | map | TLS-related configuration | |
| volumes | list | List of Volumes to mount (short-form string syntax, e.g. /data) |
|
| volumeOptions | list | List of volumes to attach with service (advanced configuration, see below) | |
| whitelist | string | Comma delimited list of CIDRs, e.g. 10.0.0.0/24,172.10.0.1, to allow access to the service |
Environment variables declared on
convox.ymlwill be populated for a Service.
The
drainattribute is deprecated. Usetermination.graceinstead.
annotations
You can use annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. On Convox, annotations will reflect in pods and service accounts.
Here are some examples of information that can be recorded in annotations:
- Build, release, or image information like timestamps, release IDs, git branch, PR numbers, image hashes, and registry address.
- Fields managed by a declarative configuration layer. Attaching these fields as annotations distinguishes them from default values set by clients or servers, and from auto-generated fields and fields set by auto-sizing or auto-scaling systems.
- User or tool/system provenance information, such as URLs of related objects from other ecosystem components.
- Configure a service to assume an AWS IAM Role via IRSA. For example:
environment:
- PORT=3000
services:
web:
annotations:
- eks.amazonaws.com/role-arn=arn:aws:iam::accountID:role/yourOwnIAMRole
domain: ${HOST}
build: .
port: 3000
accessControl
| Attribute | Type | Default | Description |
|---|---|---|---|
| awsPodIdentity | map | The specification for IAM Role for AWS Pod Identity. This will only work if pod identity is enable on the rack. |
services:
web:
build: .
port: 3000
accessControl:
awsPodIdentity:
policyArns:
- "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
- "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
accessControl.awsPodIdentity
| Attribute | Type | Default | Description |
|---|---|---|---|
| policyArns | list | The list of policy ARNs for the IAM role |
Pod identity must be enabled on rack before specifying this.
build
| Attribute | Type | Default | Description |
|---|---|---|---|
| args | list | Build arguments to pass during the build. See Build Arguments | |
| manifest | string | Dockerfile | The filename of the Dockerfile |
| path | string | . | The path (relative to convox.yml) to build for this Service |
Specifying build as a string will set the path and leave the other values as defaults.
certificate
| Attribute | Type | Default | Description |
|---|---|---|---|
| duration | string | 2160h | Certificate renew frequency period |
| id | string | ID of the generated certificate to use instead of creating a new certificate. If specified, the duration value will not have any effect, since the certificate is already generated |
deployment
| Attribute | Type | Default | Description |
|---|---|---|---|
| maximum | number | 200 | The maximum percentage of Processes to allow during rolling deploys. Defaults to 100 for agents and singletons. |
| minimum | number | 50 | The minimum percentage of healthy Processes to keep alive during rolling deploys. Defaults to 0 for agents and singletons. |
dnsConfig
| Attribute | Type | Default | Description |
|---|---|---|---|
| ndots | int | The ndots option for the dns config |
ingressAnnotations
This accepts list of strings where in each string annotation key and value is separated by = sign:
services:
web:
build: .
port: 3000
ingressAnnotations:
- nginx.ingress.kubernetes.io/limit-rpm=10
- nginx.ingress.kubernetes.io/enable-access-log=false
Reserved annotation keys:
alb.ingress.kubernetes.io/schemecert-manager.io/cluster-issuercert-manager.io/durationnginx.ingress.kubernetes.io/backend-protocolnginx.ingress.kubernetes.io/proxy-connect-timeoutnginx.ingress.kubernetes.io/proxy-read-timeoutnginx.ingress.kubernetes.io/proxy-send-timeoutnginx.ingress.kubernetes.io/server-snippetnginx.ingress.kubernetes.io/affinitynginx.ingress.kubernetes.io/session-cookie-namenginx.ingress.kubernetes.io/ssl-redirectnginx.ingress.kubernetes.io/whitelist-source-range
initContainer
An init container runs to completion before the main service container starts. Use init containers to perform setup tasks such as database migrations, waiting for upstream dependencies, or preparing configuration. If the init container exits with a non-zero status, the pod will restart and retry it.
The init container automatically receives:
- All service environment variables
- All service resource connections (e.g.
DATABASE_URL) - An
INIT_CONTAINER=trueenvironment variable
| Attribute | Type | Default | Description |
|---|---|---|---|
| image | string | service image | An external Docker image to run. If not set, uses the service image |
| command | string | The command to run. Required for the init container to be created | |
| configMounts | list | Mount configuration files into the init container. See Config Mounts | |
| volumeOptions | list | List of volumes to attach (see volumeOptions) |
Database Migrations
Run migrations before the application starts:
services:
web:
build: .
port: 3000
resources:
- database
initContainer:
command: "bin/migrate"
The init container connects to the database using the same resource credentials as the main service.
Waiting for Dependencies
Use a lightweight image to block startup until upstream services are ready:
services:
api:
build: .
port: 3000
initContainer:
image: busybox:1.36
command: |
sh -c '
echo "Waiting for service-a...";
until wget -qO /dev/null http://service-a:8080/healthz 2>/dev/null; do sleep 5; done;
echo "service-a ready";
echo "Waiting for service-b...";
until wget -qO /dev/null http://service-b:9000/health 2>/dev/null; do sleep 5; done;
echo "service-b ready";
echo "All dependencies ready!"'
This ensures the main container only starts after its dependencies are healthy. Specifying a minimal image like busybox avoids building dependency-checking logic into your application image.
lifecycle
| Attribute | Type | Default | Description |
|---|---|---|---|
| preStop | string | Command to run before the container is terminated | |
| postStart | string | Command to run immediately after the container starts |
Use lifecycle hooks to manage graceful shutdown and post-start initialization:
services:
web:
build: .
port: 3000
lifecycle:
preStop: "sleep 10"
postStart: "/bin/sh -c 'echo started > /tmp/ready'"
The preStop hook runs before a container receives the SIGTERM signal during shutdown. A common pattern is to add a brief sleep to allow in-flight requests to complete and load balancers to deregister the pod:
lifecycle:
preStop: "sleep 10"
The postStart hook runs immediately after the container starts, in parallel with the main process. Use it for tasks like cache warming or service registration.
See Health Checks for configuring readiness, liveness, and startup probes that work alongside lifecycle hooks.
health
| Attribute | Type | Default | Description |
|---|---|---|---|
| grace | number | interval |
The number of seconds to wait for a Process to start before starting health checks. Defaults to the value of interval |
| interval | number | 5 | The number of seconds between health checks |
| path | string | / | The path to request for health checks |
| timeout | number | interval - 1 |
The number of seconds to wait for a successful response. Defaults to interval minus one |
| disable | bool | false | Set to true to disable the health check entirely |
Specifying health as a string will set the path and leave the other values as defaults.
liveness
| Attribute | Type | Default | Description |
|---|---|---|---|
| grace | number | 10 | The number of seconds to wait for a Process to start before starting liveness checks |
| interval | number | 5 | The number of seconds between health checks |
| path | string | The path to request for health checks | |
| timeout | number | 5 | The number of seconds to wait for a successful response |
| successThreshold | number | 1 | The number of consecutive successful checks required to consider the probe successful |
| failureThreshold | number | 3 | The number of consecutive failed checks required before restarting the container |
If you want to enable liveness check, you have to specify path and others are optional
scale
| Attribute | Type | Default | Description |
|---|---|---|---|
| count | number | 1 | The number of Processes to run for this Service. For autoscaling use a range, e.g. 1-5 |
| cpu | number | 250 | The number of CPU units to reserve for Processes of this Service where 1000 units is a full CPU |
| gpu | map | The number/type of GPUs to reserve for Processes of this Service | |
| memory | number | 512 | The number of MB of RAM to reserve for Processes of this Service |
| targets | map | Target metrics to trigger autoscaling | |
| keda | map | KEDA event-driven autoscaling configuration. See KEDA | |
| vpa | map | Vertical Pod Autoscaler configuration. See VPA | |
| limit | map | The maximum cpu or memory usage limit |
Specifying scale as a number will set the count and leave the other values as defaults.
scale.gpu
| Attribute | Type | Default | Description |
|---|---|---|---|
| count | number | The number of GPUs to reserve for Processes of this Service | |
| vendor | string | nvidia | The GPU vendor to target for Processes of this Service |
Specifying gpu as a number will set the count and leave the vendor as default. Specifying a gpu value and not specifying the cpu or memory to reserve will remove their defaults to purely reserve based on GPU. You should ensure that your Rack is running on GPU enabled instances (of the correct vendor) before specifying the gpu section in your convox.yml
scale.targets
| Attribute | Type | Default | Description |
|---|---|---|---|
| cpu | number | The percentage of CPU utilization to target for Processes of this Service | |
| memory | number | The percentage of memory utilization to target for Processes of this Service | |
| external | map | The array of the external metrics based on which it will scale the Service |
scale.limit
| Attribute | Type | Default | Description |
|---|---|---|---|
| cpu | number | The number of CPU units to limit for Processes of this Service where 1000 units is a full CPU | |
| memory | number | <scale.memory> | The number of MB of RAM to limit for Processes of this Service |
scale.targets.[]external
| Attribute | Type | Default | Description |
|---|---|---|---|
| name | string | The name of the metric | |
| matchLabels | map | Key-value labels for the metrics | |
| averageValue | number | The target value of the average of the metric across all relevant pods | |
| value | number | The target value of the metric |
services:
web:
build: .
port: 3000
scale:
count: 1-3
targets:
external:
- name: "datadogmetric@default:web-requests"
averageValue: 200
termination
| Attribute | Type | Default | Description |
|---|---|---|---|
| grace | number | 30 | The number of seconds to wait for Processes to gracefully exit before killing them |
tls
| Attribute | Type | Default | Description |
|---|---|---|---|
| redirect | boolean | true | Whether or not HTTP requests should be redirected to HTTPS using a 308 response code |
[]volumeOptions
| Attribute | Type | Default | Description |
|---|---|---|---|
| emptyDir | map | Configuration for emptyDir volume | |
| awsEfs | map | Configuration for AWS Efs volume. To use this you have to enable efs csi driver in the rack |
[]volumeOptions.emptyDir
| Attribute | Type | Default | Description |
|---|---|---|---|
| id | string | Required. Id of the volume. | |
| mountPath | string | Required. Path in the service file system to mount the volume | |
| medium | string | Optional. Specifies the emptyDir medium. Allowed values: "Memory" or "" |
environment:
- PORT=3000
services:
web:
build: .
port: 3000
volumeOptions:
- emptyDir:
id: "test-vol"
mountPath: "/my/test/vol"
[]volumeOptions.awsEfs
| Attribute | Type | Default | Description |
|---|---|---|---|
| id | string | Required. Id of the volume. | |
| mountPath | string | Required. Path in the service file system to mount the volume | |
| accessMode | string | Required. Specifies the access mode for the volume. Allowed values are: ReadWriteOnce, ReadOnlyMany, ReadWriteMany |
|
| storageClass | string | Storage class for the EFS volume | |
| volumeHandle | string | Use an existing EFS access point instead of provisioning a new one. See Volumes |
environment:
- PORT=3000
services:
web:
build: .
port: 3000
volumeOptions:
- awsEfs:
id: "efs-1"
accessMode: ReadWriteMany
mountPath: "/my/data/"
Command Line Interface
Listing Services
$ convox services -a myapp
SERVICE DOMAIN PORTS
web web.convox.0a1b2c3d4e5f.convox.cloud 443:5000
Scaling a Service
$ convox scale web --count 3 --cpu 250 --memory 1024 -a myapp
Scaling web... OK
Restarting a Service
$ convox services restart web -a myapp
Restarting web... OK
Restarting a Service will begin a rolling restart with graceful termination of each Process of the Service.
See Also
- Agents for running a single process on every node (DaemonSet-style workloads)
- Health Checks for configuring readiness and liveness probes
- Scaling for autoscaling, VPA, and workload placement