This article will explain how to use Terraform for automation to set up and deploy Docker containers. We will be using Docker for Windows Desktop to show how to deploy a demo container.
Firstly we will need to set up the Windows Subsystem for Linux if you have not already done so. To do this, follow the instructions here.
If you don’t already have Docker installed, you can download it for free.
During the installation process, you should also check the ‘Use the WSL 2 based engine’. This uses the Windows Subsystem for Linux, which provides better Docker performance.
Once Docker is installed, for our demo purposes, we will need to expose the daemon without TLS.
Go to the Docker Desktop for Windows settings and make sure ‘Expose daemon on TCP:localhost:2375 without TLS’ is ticked. Apply the settings, and Docker will restart.
We will be using the Docker provider as found on the Terraform registry:
The Docker provider is used to interact with Docker containers and images. It uses the Docker API to manage the lifecycle of Docker containers. Because the Docker provider uses the Docker API, it is immediately compatible not only with single server Docker but Swarm and any additional Docker-compatible API hosts.
To set this up, create a file called main.tf
and add the following provider block (latest version 2.23.1 at the time of writing). You can also clone the file from the GitHub repository.
The localhost:2375 is the default address for the Docker daemon.
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "2.23.1"
}
}
}
provider "docker" {
host = "tcp://localhost:2375"
}
Note for reference to connect to a Linux machine with Docker installed you would use the host line:
host = "unix:///var/run/docker.sock"
Next we need to add the container configuration to the main.tf file:
# Creating a Docker Image ubuntu with the latest as the Tag.
resource "docker_image" "ubuntu" {
name = "ubuntu:latest"
}
# Creating a Docker Container using the latest ubuntu image.
resource "docker_container" "webserver" {
image = docker_image.ubuntu.latest
name = "terraform-docker-test"
must_run = true
publish_all_ports = true
command = [
"tail",
"-f",
"/dev/null"
]
}
The docker_image
resource pulls a Docker image to a given Docker host from a Docker Registry. In this case, the latest Ubuntu image.
The docker_container
resource manages the lifecycle of a Docker container. In the above example, we specify the image and name of the container.
Note the must_run
parameter is set to true
, meaning the Docker container will be kept running. publish_all_ports
is used to publish all ports of the container. The command
sets a command to use to start the container.
Here we use the tail
command with the follow option -f
on "/dev/null"
which will constantly run to keep the container alive.
Run terraform init
on the directory that holds the configuration file:
Run terraform plan
and then terraform apply
.
Back in the Docker Desktop for Windows GUI you can see the Container running:
Or on the command line using docker container ls
.
Lets add an NGINX (web server) image and container resource to the main.tf
config file:
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.latest
name = "nginx-test"
ports {
internal = 80
external = 8000
}
}
This specifies the internal and external ports that allow the container to be accessed from the localhost. Run terraform apply
again and accept the changes.
You should now see two containers running, not the ports against the nginx-test container.
Browse to http://localhost:8000/ to view the default web page:
You can also use Terraform to deploy other aspects of Docker containers, such as volumes, secrets, tags, and networking.
resource "docker_network" "private_network" {
name = "my_network"
}
resource "docker_secret" "foo" {
name = "foo"
data = base64encode("{\"foo\": \"s3cr3t\"}")
}
resource "docker_volume" "shared_volume" {
name = "shared_volume"
}
#The source image must exist on the machine running the docker daemon.
resource "docker_tag" "tag" {
source_image = "xxxx"
target_image = "xxxx"
}
To cleanup, type terraform destroy
.
In this article, we have shown how to use Terraform to set up Docker containers on Windows.
If you need any help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box.
Manage Terraform Better with Spacelift
Build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.
Terraform CLI Commands Cheatsheet
Initialize/ plan/ apply your IaC, manage modules, state, and more.