Configuration File
Processes
The [[processes]] section is used to define the different processes that make up your application. You can define multiple processes, such as a web server or a background worker.
Each process is defined as a separate [[processes]] table.
# Configuration file with a processes section
app = 'myapp'
# App process
[[processes]]
name = 'app'
command = 'php artisan serve'
size = 'small'
[processes.http]
internal_port = 8080
[[processes.ports]]
port = 9090
protocol = 'tcp'
[[processes.ports]]
port = 53
protocol = 'udp'
[processes.autoscaling]
min_replicas = 1
max_replicas = 5
[[processes.autoscaling.metrics]]
resource = 'cpu'
avg_utilization = 70
[[processes.autoscaling.metrics]]
resource = 'memory'
avg_value = '512Mi'
[processes.liveness]
type = 'http'
path = '/up'
port = 8080
initial_delay_seconds = 30
timeout_seconds = 5
period_seconds = 10
success_threshold = 1
failure_threshold = 3
[processes.readiness]
type = 'tcp'
port = 9090
initial_delay_seconds = 40
timeout_seconds = 4
period_seconds = 8
success_threshold = 2
failure_threshold = 4
# Worker process
[[processes]]
name = 'worker'
command = 'php artisan queue:work'
[processes.resources]
[processes.resources.requests]
cpu = '500m'
memory = '256Mi'
[processes.resources.limits]
cpu = '1'
memory = '512Mi'
[processes.liveness]
type = 'exec'
command = 'php artisan health:check'
initial_delay_seconds = 20
timeout_seconds = 15
period_seconds = 30
success_threshold = 1
failure_threshold = 3
[processes.readiness]
type = 'exec'
command = 'php artisan health:check'
initial_delay_seconds = 22
timeout_seconds = 18
period_seconds = 32
success_threshold = 2
failure_threshold = 4
Common fields
name: The name of the process. (Required)command: The command to execute to start the process, as a string or an array. See Commands for how it is run. If not specified, Deckrun will use theCMDinstruction from yourDockerfile.
Naming a Process
The name field is used to identify each process and must adhere to the following rules:
- Uniqueness: Each process name must be unique within the
[[processes]]list in yourdeckrun.tomlfile. Duplicate names will cause a validation error. - Formatting: The name must consist of lowercase alphanumeric characters and dashes.
- Length: The name must be between 3 and 63 characters long.
These conventions ensure that process names are valid and compatible with the underlying infrastructure.
Sizing your process
You can define the CPU and memory for a process using either pre-defined sizes or custom resource allocation. You cannot use both at the same time.
Understanding Resource Units
You might be wondering what 250m of CPU or 256Mi of memory means. Let's break it down.
CPU
CPU resources are measured in "millicores" or "millicpu". 1000m is equivalent to one full CPU core. So, 250m represents a quarter of a CPU core (0.25).
Memory
Memory is measured in bytes. The Mi suffix stands for "Mebibytes", which is a standard unit for memory (1 Mebibyte = 2^20 bytes).
For a more in-depth explanation of resource units in Kubernetes, you can refer to the official Kubernetes documentation.
Using pre-defined sizes
The size attribute allows you to select from a pre-defined set of CPU and memory resources. This is the simplest way to allocate resources to your process.
Below is a table with the available sizes and their corresponding CPU and memory resources.
| Size | CPU | Memory |
|---|---|---|
| pico | 250m | 256Mi |
| nano | 500m | 256Mi |
| micro | 500m | 512Mi |
| mini | 1000m | 512Mi |
| small | 1000m | 1Gi |
| medium | 2000m | 2Gi |
| standard | 2000m | 4Gi |
| large | 4000m | 8Gi |
| xlarge | 4000m | 12Gi |
| xxlarge | 6000m | 16Gi |
| xxxlarge | 8000m | 32Gi |
Check actual usage
Once your application is running, use deck apps resources to see real-time CPU and memory consumption per pod alongside your configured requests and limits. This helps you right-size your processes over time. See Resource usage for details.
Using custom resource allocation
If you need more control over the resources, you can use the [processes.resources] section.
Note: Deckrun enforces minimum resource requests to ensure stable application performance. The minimum CPU request is
100m, and the minimum memory request is32Mi. Any values specified below these thresholds will be rejected during validation.
Note: You cannot use size and [processes.resources] at the same time.
The [processes.resources] section allows you to specify the CPU and memory resources for your process.
requests: The amount of resources that are guaranteed for the process.limits: The maximum amount of resources that the process can use.
Here is an example of how to use the resources section:
# Worker process
[[processes]]
name = 'worker'
command = 'php artisan queue:work'
[processes.resources]
[processes.resources.requests]
cpu = '500m'
memory = '256Mi'
[processes.resources.limits]
cpu = '1'
memory = '512Mi'
processes.http
The [processes.http] section exposes a process to the internet, making it accessible via a public URL.
In Deckrun, only one process can be designated as the main web-facing service. By convention, this process must be named app. The [processes.http] section is only valid for the process named app and will be ignored for any other process.
internal_port: The port inside the container on which your application is listening for HTTP traffic. This field is required.
processes.ports
The [[processes.ports]] section allows you to expose additional ports for your process inside the cluster only. These ports are never published to the internet: Deckrun makes them reachable by your other apps, but creates no public route, load balancer or node port for them.
port: The port to expose. (Required)protocol: The protocol to use (tcporudp). Defaults totcpif not specified.
Internal processes
Sometimes you want a process that other apps can call but that is never reachable from the internet, such as an internal microservice. To do this, define its ports with [[processes.ports]] and leave out [processes.http].
[processes.http] is the only thing that publishes a process to the internet, and it only works on the process named app, through the app's domains. A process with [[processes.ports]] and no [processes.http] stays private, even if its app has domains.
app = 'billing'
[[processes]]
name = 'api'
command = './billing-api'
size = 'small'
[[processes.ports]]
port = 8080
protocol = 'tcp'
Calling an internal process
Deckrun gives each process with ports an internal address named <app-name>-<process-name>. Other apps in the same cluster can reach the example above at:
curl http://billing-api:8080
Security considerations
"Internal" means not reachable from the internet. Inside the cluster there is no isolation between apps, so any app running in the same cluster can call an internal process. If your service handles sensitive operations, add authentication between your services, such as a shared token stored in a secret.
Port Validation
When configuring ports in Deckrun, all port numbers must be valid and within the standard TCP/UDP range.
- Valid Range: Port numbers must be between
1and65535. - Affected Fields: This validation applies to
processes.http.internal_portand theportfield in any[[processes.ports]]definition.
Specifying a port number outside of this valid range (such as 0, a negative number, or a number greater than 65535) will cause a validation error during the deployment process.
processes.autoscaling
The [processes.autoscaling] section allows you to configure autoscaling for your process, automatically adjusting the number of replicas based on observed metrics.
min_replicas: The minimum number of replicas that should be running at all times. (Required)max_replicas: The maximum number of replicas that the autoscaler can create. (Required)
Both min_replicas and max_replicas are required fields and must be positive integers greater than zero. The value of min_replicas must be less than or equal to max_replicas.
Note: Autoscaling is only effective when resource requests are defined for the process. This is because the autoscaler calculates utilization targets based on these requests. You can set resource requests either by selecting a
sizeor by specifying them explicitly in the[processes.resources]section. If you configure autoscaling without defining resource requests, Deckrun will return a validation error.
processes.autoscaling.metrics
To define autoscaling triggers, you must specify one or more metrics in the [[processes.autoscaling.metrics]] table array. Deckrun supports scaling based on CPU and memory usage.
There are two primary ways to define a metric target:
- Average Utilization (
avg_utilization): This scales the process based on the average percentage of a resource request being used across all replicas. This is most commonly used for CPU. - Average Value (
avg_value): This scales the process based on the average absolute value of a resource being consumed across all replicas. This is the standard way to scale based on memory.
CPU Scaling
To scale based on CPU, you define a metric with resource = 'cpu' and set a target average utilization percentage with avg_utilization. The autoscaler will add more replicas when the average CPU usage across all pods exceeds this threshold.
# Scale up when CPU usage averages over 70%
[processes.autoscaling]
min_replicas = 1
max_replicas = 5
[[processes.autoscaling.metrics]]
resource = 'cpu'
avg_utilization = 70
In this example, Deckrun will ensure the number of replicas is adjusted so that the average CPU usage for the process remains around 70% of what was requested (either via the size parameter or the resources.requests.cpu field).
Memory Scaling
To scale based on memory, you define a metric with resource = 'memory' and set a target average value with avg_value. This value represents the target memory consumption in Mebibytes (Mi).
# Scale up when memory usage averages over 512Mi
[processes.autoscaling]
min_replicas = 1
max_replicas = 5
[[processes.autoscaling.metrics]]
resource = 'memory'
avg_value = '512Mi'
In this example, the autoscaler will add replicas if the average memory consumption across all pods for this process exceeds 512 Mebibytes.
You can also combine metrics. The autoscaler will trigger a scale-up if any of the metric thresholds are breached.
# Scale up if CPU averages > 70% OR memory averages > 256Mi
[processes.autoscaling]
min_replicas = 2
max_replicas = 10
[[processes.autoscaling.metrics]]
resource = 'cpu'
avg_utilization = 70
[[processes.autoscaling.metrics]]
resource = 'memory'
avg_value = '256Mi'
You must provide at least one metric in the
[[processes.autoscaling.metrics]]table for the autoscaler to function.Only one metric per resource type is allowed. For example, you cannot define two separate CPU metrics, even if one uses
avg_utilizationand the other usesavg_value. Doing so will result in a validation error for duplicate metrics. For instance, the following configuration is invalid because it defines two metrics for thecpuresource:# Invalid configuration: two metrics for the same resource [[processes.autoscaling.metrics]] resource = "cpu" avg_utilization = 70 [[processes.autoscaling.metrics]] resource = "cpu" avg_value = "200m"
Each [[processes.autoscaling.metrics]] block is subject to the following rules:
- The
resourcefield must be either"cpu"or"memory". Any other value will be considered invalid. - You must set exactly one of
avg_utilizationoravg_value. Providing both or neither will result in an error. - For CPU metrics (
resource = "cpu"):- If using
avg_utilization, the value must be an integer percentage between1and100. Values outside this range are invalid. - If using
avg_value, the value must be a valid CPU resource quantity string, such as"200m".
- If using
- For Memory metrics (
resource = "memory"):avg_valueis the recommended field and must be a valid memory resource quantity string, such as"256Mi"or"1Gi".- While
avg_utilizationis permitted for memory, it must be an integer percentage between1and100.
- Any incorrectly formatted values will cause a validation error.
Health Checks
Deckrun uses liveness, readiness and startup probes to monitor the health of your application's containers.
- Liveness Probe: Checks if the container is running. If it fails, Deckrun restarts the container.
- Readiness Probe: Checks if the container is ready to accept traffic. If it fails, the container is removed from service discovery until it passes again.
- Startup Probe: Checks if the container has finished starting. Until it passes, the liveness and readiness probes don't run. If it doesn't pass in time, Deckrun restarts the container. See Startup Probes.
The liveness, readiness and startup probes are configured with the same set of options.
Configuration Fields
type: The type of probe to perform. This is a required field and must be one ofhttp,tcp, orexec.path: The HTTP path to request forhttpprobes. This field is required forhttpprobes.port: The port to connect to forhttpandtcpprobes.command: The command to execute forexecprobes, as a string or an array (see Commands). This field is required forexecprobes.initial_delay_seconds: The number of seconds to wait after the container starts before performing the first probe. Cannot be negative.timeout_seconds: The number of seconds after which the probe times out. Cannot be negative.period_seconds: The frequency (in seconds) at which to perform the probe. Cannot be negative.success_threshold: The minimum number of consecutive successes required for the probe to be considered successful after a failure. Cannot be negative.failure_threshold: The number of consecutive failures after which the probe is considered to have failed. Cannot be negative.
Note on Liveness and Startup Probes: For
livenessandstartupprobes, thesuccess_thresholdmust be1. These probes only need to succeed once to confirm the container is running or has started, so a higher value is not permitted.
Probe Types and Port Configuration
The behavior of health checks can vary depending on the type you choose.
HTTP Probes
- Requirement: An
httpprobe can only be used on a process that is exposed via HTTP, meaning a[processes.http]section must be defined for it. - Port: The
portfor anhttpprobe is implicitly set to the value ofprocesses.http.internal_port. You do not need to specify it, but if you do, it must match theinternal_port.
# HTTP probe example
[processes.liveness]
type = 'http'
path = '/up'
TCP Probes
- Port: The
portfor atcpprobe must be one of the TCP ports exposed by the process. This can be either theprocesses.http.internal_port(if defined) or a port listed in the[[processes.ports]]section withprotocol = 'tcp'. If the specified port is not exposed by the process, or is only exposed as UDP, Deckrun will return a validation error.
# TCP probe example
[processes.readiness]
type = 'tcp'
port = 9090
Exec Probes
exec probes run a command inside your container and do not have any port-related requirements.
- Requirement: An
execprobe requires thecommandfield to be specified.
# Exec probe example
[processes.liveness]
type = 'exec'
command = 'php artisan health:check'
To run a probe that needs shell features, use the array form:
# Exec probe using a shell
[processes.readiness]
type = 'exec'
command = ['sh', '-c', 'test -f /tmp/ready']
Startup Probes
Use a startup probe when your app takes a while to boot, for example because it warms caches, loads large files or waits for other services on start. Without one, you have to choose between a strict liveness probe that restarts the app before it finishes starting, and a loose one (a long initial_delay_seconds or a high failure_threshold) that also takes longer to detect a hung app for as long as it runs.
A startup probe solves this. While it hasn't passed yet, the liveness and readiness probes don't run, so they can't restart the app or mark it unhealthy. As soon as it passes once, it stops running, and the liveness and readiness probes take over with their usual settings.
The time your app has to start is initial_delay_seconds + period_seconds × failure_threshold. It's a maximum, not a wait: the probe passes as soon as your app responds, so a fast boot isn't slowed down.
[[processes]]
name = 'app'
[processes.http]
internal_port = 8080
# Up to 2 minutes to start (5s × 24), checking every 5 seconds
[processes.startup]
type = 'http'
path = '/up'
period_seconds = 5
timeout_seconds = 3
failure_threshold = 24
# Once started, a hung app is restarted after about 30 seconds
[processes.liveness]
type = 'http'
path = '/up'
[processes.readiness]
type = 'http'
path = '/up'
To choose the values, measure how long your app takes to become ready and give it 2 to 3 times that.
Keep the startup time under 4 minutes
A deploy waits up to 5 minutes for the new version of your processes to become ready, including pulling the image and scheduling the containers. If the startup probe allows more time than that, a deploy can be marked as failed while your app is still starting.
Requires deck v1.4.0 or later
Startup probes need deck v1.4.0 or later. Older versions of deck ignore the [processes.startup] section without an error, so the probe isn't applied. Run deck version to check yours.