Container
The container resource defines Docker containers that run as part of your lab’s sandbox environment. Containers provide isolated environments for running applications, services, and tools that participants interact with during the lab.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "container" "name" { image { name = "ubuntu:22.04" }}
Full Syntax
Section titled “Full Syntax”resource "container" "name" { image { name = "image:tag" }
# Optional configurations entrypoint = ["executable", "param1"] command = ["arg1", "arg2"] environment = { KEY = "value" } labels = { label = "value" } dns = ["8.8.8.8", "8.8.4.4"] privileged = false max_restart_count = 3
# Network configuration network { id = resource.network.main.meta.id ip_address = "10.0.0.5" aliases = ["db", "database"] }
# Resource constraints resources { cpu = 1000 # 1 CPU = 1000 cpu_pin = [0, 1] memory = 512 # MB
gpu { driver = "nvidia" device_ids = ["0"] } }
# Volumes volume { source = "/host/path" destination = "/container/path" type = "bind" read_only = false }
# Ports port { local = "8080" host = "8080" protocol = "tcp" }
port_range { range = "3000-3010" enable_host = true protocol = "tcp" }
# Security capabilities { add = ["SYS_ADMIN"] drop = ["NET_RAW"] }
# User configuration run_as { user = "1000" group = "1000" }
# Health check health_check { timeout = "10s"
http { address = "http://localhost/health" method = "GET" } }}
Resource Structure
Section titled “Resource Structure”container├─ image (required)│ └─ name├─ basic configuration│ ├─ entrypoint, command│ ├─ environment, labels, dns│ ├─ privileged, max_restart_count├─ networking│ └─ network[] (repeatable)│ ├─ id, ip_address, aliases├─ storage│ └─ volume[] (repeatable)│ ├─ source, destination, type│ └─ read_only, bind_propagation, selinux_relabel├─ port exposure│ ├─ port[] (repeatable)│ │ ├─ local, remote, host, protocol, open_in_browser│ └─ port_range[] (repeatable)│ ├─ range, enable_host, protocol├─ resource limits│ └─ resources│ ├─ cpu, cpu_pin, memory│ └─ gpu│ ├─ driver, device_ids├─ security│ ├─ capabilities│ │ ├─ add[], drop[]│ └─ run_as│ ├─ user, group└─ monitoring └─ health_check ├─ timeout ├─ http[] (address, method, body, headers, success_codes) ├─ tcp[] (address) └─ exec[] (command, script, exit_code)
Fields
Section titled “Fields”Field | Required | Type | Description |
---|---|---|---|
image | ✓ | block | Docker image configuration |
entrypoint | list(string) | Override the default entrypoint | |
command | list(string) | Command to run in the container | |
environment | map(string) | Environment variables | |
labels | map(string) | Docker labels | |
dns | list(string) | Custom DNS servers | |
privileged | bool | Run container in privileged mode. Defaults to false. | |
max_restart_count | number | Maximum restart attempts. Defaults to 0. | |
network | block | Network attachments (repeatable) | |
volume | block | Volume mounts (repeatable) | |
port | block | Port mappings (repeatable) | |
port_range | block | Port range mappings (repeatable) | |
resources | block | Resource constraints | |
capabilities | block | Linux capabilities configuration | |
run_as | block | User/group configuration | |
health_check | block | Container health check |
Image Configuration
Section titled “Image Configuration”container → image
Configures the Docker image to use for the container.
Field | Required | Type | Description |
---|---|---|---|
name | ✓ | string | Docker image name with optional tag |
username | string | Docker registry username for private repositories | |
password | string | Docker registry password for private repositories |
Network Configuration
Section titled “Network Configuration”container → network
Defines network attachments for the container. This block can be repeated to attach the container to multiple networks.
Field | Required | Type | Description |
---|---|---|---|
id | ✓ | reference to network | Reference to the ID of a network resource |
ip_address | string | Static IP address. Auto-assigned if not specified. | |
aliases | list(string) | Network aliases for the container |
Storage Configuration
Section titled “Storage Configuration”container → volume
Configures volume mounts for the container. This block can be repeated to mount multiple volumes.
Field | Required | Type | Description |
---|---|---|---|
source | ✓ | string | Source path on host or volume name |
destination | ✓ | string | Mount path inside container |
type | string | Volume type: “bind”, “volume”, or “tmpfs”. Defaults to “bind”. | |
read_only | bool | Mount as read-only. Defaults to false. | |
bind_propagation | string | Bind propagation: “shared”, “private”, “slave”, “rslave”, “rprivate” | |
bind_propagation_non_recursive | bool | Non-recursive bind mount. Defaults to false. | |
selinux_relabel | string | SELinux relabeling: “shared” or “private” |
Port Configuration
Section titled “Port Configuration”container → port
Defines port mappings between the container and host. This block can be repeated to expose multiple ports.
Field | Required | Type | Description |
---|---|---|---|
local | ✓ | string | Container port |
remote | string | Remote port of the service | |
host | string | Host port | |
protocol | string | Protocol: “tcp” or “udp”. Defaults to “tcp”. | |
open_in_browser | string | Path to open in browser when host port is defined |
Port Range Configuration
Section titled “Port Range Configuration”container → port_range
Defines port range mappings for exposing multiple consecutive ports. This block can be repeated for multiple port ranges.
Field | Required | Type | Description |
---|---|---|---|
range | ✓ | string | Port range (e.g., “3000-3010”) |
enable_host | bool | Enable host port mapping. Defaults to false. | |
protocol | string | Protocol: “tcp” or “udp”. Defaults to “tcp”. |
Resource Constraints
Section titled “Resource Constraints”container → resources
Configures CPU, memory, and GPU resource limits for the container.
Field | Required | Type | Description |
---|---|---|---|
cpu | number | CPU limit (1 CPU = 1000) | |
cpu_pin | list(number) | Pin container to specific CPU cores | |
memory | number | Memory limit in MB | |
gpu | block | GPU resource configuration |
GPU Configuration
Section titled “GPU Configuration”Configures GPU resources for containers that need hardware acceleration for machine learning, graphics processing, or other compute-intensive tasks.
Field | Required | Type | Description |
---|---|---|---|
driver | ✓ | string | GPU driver to use (e.g., “nvidia”) |
device_ids | ✓ | list(string) | GPU device IDs to allocate |
Security Configuration
Section titled “Security Configuration”container → capabilities
Configures Linux capabilities for fine-grained privilege control.
Field | Required | Type | Description |
---|---|---|---|
add | list(string) | Capabilities to add. Defaults to empty list. | |
drop | list(string) | Capabilities to remove. Defaults to empty list. |
User Configuration
Section titled “User Configuration”container → run_as
Specifies the user and group under which the container runs.
Field | Required | Type | Description |
---|---|---|---|
user | ✓ | string | Username or UID |
group | ✓ | string | Group name or GID |
Health Monitoring
Section titled “Health Monitoring”container → health_check
Configures health checks to monitor container status and availability.
Field | Required | Type | Description |
---|---|---|---|
timeout | string | Health check timeout. Defaults to ”30s”. | |
http | block | HTTP health check (repeatable) | |
tcp | block | TCP health check (repeatable) | |
exec | block | Execute command health check (repeatable) |
HTTP Health Check
Section titled “HTTP Health Check”container → health_check → http
Defines an HTTP-based health check that sends requests to specified endpoints.
Field | Required | Type | Description |
---|---|---|---|
address | ✓ | string | HTTP endpoint URL |
method | string | HTTP method. Defaults to “GET”. | |
body | string | Request body | |
headers | map(list(string)) | HTTP headers | |
success_codes | list(number) | Expected success codes. Defaults to [200]. |
TCP Health Check
Section titled “TCP Health Check”container → health_check → tcp
Defines a TCP-based health check that verifies network connectivity.
Field | Required | Type | Description |
---|---|---|---|
address | ✓ | string | TCP address to check |
Exec Health Check
Section titled “Exec Health Check”container → health_check → exec
Defines a command-based health check that executes a script or command to determine container health.
Field | Required | Type | Description |
---|---|---|---|
command | list(string) | Command to execute | |
script | string | Script to execute | |
exit_code | number | Expected exit code. Defaults to 0. |
Computed Attributes
Section titled “Computed Attributes”These attributes are set by the system after the container is created:
Field | Type | Description |
---|---|---|
container_name |
string | Fully qualified domain name for the container |
image.id |
string | Unique identifier for the image |
network[].name |
string | Network name as created by the system |
network[].assigned_address |
string | IP address assigned by the system |
Validation Rules
Section titled “Validation Rules”- Volume source paths are made absolute relative to the config file location
- For bind mounts, the source path must exist on the host
- Port mappings must use valid port numbers (1-65535)
- CPU values should be multiples of 1000 for whole CPUs
- Memory values are in megabytes
Examples
Section titled “Examples”Basic Container
Section titled “Basic Container”resource "container" "ubuntu" { image { name = "ubuntu:22.04" }}
Web Application Container
Section titled “Web Application Container”resource "container" "webapp" { image { name = "myapp:latest" }
environment = { NODE_ENV = "production" PORT = "3000" }
port { local = "3000" host = "8080" }
resources { cpu = 2000 # 2 CPUs memory = 1024 # 1GB }
health_check { timeout = "5s"
http { address = "http://localhost:3000/health" method = "GET" } }}
Database Container with Volume
Section titled “Database Container with Volume”resource "container" "postgres" { image { name = "postgres:15" }
environment = { POSTGRES_PASSWORD = "secret" POSTGRES_DB = "myapp" }
volume { source = "postgres-data" destination = "/var/lib/postgresql/data" type = "volume" }
port { local = "5432" }
network { id = resource.network.backend.meta.id aliases = ["db", "database"] }}
Development Container with Multiple Networks
Section titled “Development Container with Multiple Networks”resource "container" "devbox" { image { name = "instruqt/devbox:latest" }
privileged = true
network { id = resource.network.frontend.meta.id ip_address = "10.0.1.10" }
network { id = resource.network.backend.meta.id ip_address = "10.0.2.10" }
volume { source = "./code" destination = "/workspace" type = "bind" }
volume { source = "/var/run/docker.sock" destination = "/var/run/docker.sock" type = "bind" }
capabilities { add = ["SYS_PTRACE"] }
run_as { user = "developer" group = "developer" }}
GPU-Enabled Container
Section titled “GPU-Enabled Container”resource "container" "ml_workspace" { image { name = "tensorflow/tensorflow:latest-gpu" }
resources { cpu = 4000 memory = 8192
gpu { driver = "nvidia" device_ids = ["0", "1"] } }
environment = { CUDA_VISIBLE_DEVICES = "0,1" }}
Best Practices
Section titled “Best Practices”- Image Tags: Always specify explicit image tags rather than using
latest
- Resource Limits: Set appropriate CPU and memory limits to prevent resource exhaustion
- Health Checks: Configure health checks for services to ensure availability
- Non-Root Users: Use the
run_as
block to run containers as non-root users when possible - Volume Types: Use named volumes for persistent data and bind mounts for development files
- Network Aliases: Use meaningful aliases for service discovery
- Environment Variables: Use environment variables for configuration instead of hardcoding values