In this post I will demonstrate how to use the terraform docker_container resource from the docker provider to run two docker containers, traefik and nginx and use the random provider to generate a random url for us.
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
+ create
Terraform will perform the following actions:
# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ destroy_grace_seconds = 30
+ entrypoint = (known after apply)
+ env = [
+ "PGID=20",
+ "PUID=501",
]
+ exit_code = (known after apply)
+ gateway = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = "nginx:stable-alpine"
+ init = (known after apply)
+ ip_address = (known after apply)
+ ip_prefix_length = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = "json-file"
+ logs = false
+ memory = 256
+ must_run = true
+ name = "nginx"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "unless-stopped"
+ rm = false
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ tty = false
+ healthcheck {
+ interval = (known after apply)
+ retries = (known after apply)
+ start_period = (known after apply)
+ test = (known after apply)
+ timeout = (known after apply)
}
+ labels {
+ label = "traefik.docker.network"
+ value = "docknet"
}
+ labels {
+ label = "traefik.enable"
+ value = "true"
}
+ labels {
+ label = "traefik.frontend.rule"
+ value = (known after apply)
}
+ labels {
+ label = "traefik.port"
+ value = "80"
}
+ networks_advanced {
+ aliases = [
+ "docknet",
]
+ name = "docknet"
}
+ volumes {
+ container_path = "/etc/nginx/conf.d/app.conf"
+ host_path = "/Users/ruan/personal/terraform-playground/docker-containers/configs/app.conf"
}
+ volumes {
+ container_path = "/etc/nginx/nginx.conf"
+ host_path = "/Users/ruan/personal/terraform-playground/docker-containers/configs/nginx.conf"
}
+ volumes {
+ container_path = "/usr/share/nginx/html"
+ host_path = "/Users/ruan/personal/terraform-playground/docker-containers/html"
}
}
# docker_container.traefik will be created
+ resource "docker_container" "traefik" {
+ attach = false
+ bridge = (known after apply)
+ command = [
+ "--api",
+ "--docker",
+ "--docker.watch",
+ "--entrypoints=Name:http Address::80",
+ "--logLevel=INFO",
]
+ container_logs = (known after apply)
+ destroy_grace_seconds = 30
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ gateway = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = "traefik:1.7.14"
+ init = (known after apply)
+ ip_address = (known after apply)
+ ip_prefix_length = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = "json-file"
+ logs = false
+ memory = 256
+ must_run = true
+ name = "traefik"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "unless-stopped"
+ rm = false
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ tty = false
+ healthcheck {
+ interval = (known after apply)
+ retries = (known after apply)
+ start_period = (known after apply)
+ test = (known after apply)
+ timeout = (known after apply)
}
+ labels {
+ label = "traefik.docker.network"
+ value = "docknet"
}
+ labels {
+ label = "traefik.enable"
+ value = "true"
}
+ labels {
+ label = "traefik.frontend.rule"
+ value = "Host:traefik.localdns.xyz"
}
+ labels {
+ label = "traefik.port"
+ value = "8080"
}
+ networks_advanced {
+ aliases = [
+ "docknet",
]
+ name = "docknet"
}
+ ports {
+ external = 80
+ internal = 80
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
+ volumes {
+ container_path = "/var/run/docker.sock"
+ host_path = "/var/run/docker.sock"
}
}
# docker_image.nginx will be created
+ resource "docker_image" "nginx" {
+ id = (known after apply)
+ latest = (known after apply)
+ name = "nginx:stable-alpine"
+ output = (known after apply)
+ repo_digest = (known after apply)
}
# docker_image.traefik will be created
+ resource "docker_image" "traefik" {
+ id = (known after apply)
+ latest = (known after apply)
+ name = "traefik:1.7.14"
+ output = (known after apply)
+ repo_digest = (known after apply)
}
# docker_network.nginx will be created
+ resource "docker_network" "nginx" {
+ driver = "bridge"
+ id = (known after apply)
+ internal = (known after apply)
+ ipam_driver = "default"
+ name = "docknet"
+ options = (known after apply)
+ scope = (known after apply)
+ ipam_config {
+ aux_address = (known after apply)
+ gateway = (known after apply)
+ ip_range = (known after apply)
+ subnet = (known after apply)
}
}
# random_string.nginx will be created
+ resource "random_string" "nginx" {
+ id = (known after apply)
+ length = 8
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ result = (known after apply)
+ special = false
+ upper = false
}
Plan: 6 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ nginx_container_name = "nginx"
+ nginx_url = (known after apply)
+ traefik_container_name = "traefik"
+ traefik_url = "http://traefik.localdns.xyz/"
Which we can see will create 2 containers, traefik and then nginx, map the configs and html in place and also sets the traefik hostname in the labels for our respective containers so that we can reach them via the specific host headers.
The we can deploy our containers:
1
terraform apply -auto-approve
Which will provide us the output detail defined from our outputs.tf:
Running a docker ps will show our running containers:
1234
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e45158ae8cba nginx:stable-alpine "/docker-entrypoint 3 minutes ago Up 3 minutes 80/tcp nginx
ebdbe42a0fcb traefik:1.7.14 "/traefik --api 3 minutes ago Up 3 minutes 0.0.0.0:80->80/tcp traefik
Cleanup
We can delete our containers by running:
1
terraform destroy -auto-approve
Thank You
Thanks for reading, if you like my content, check out my website or follow me at @ruanbekker on Twitter.