Skip to main content
Terraform Basics
CHAPTER 12

Terraform and Docker

Updated: May 15, 2026
25 min read

# CHAPTER 12

Terraform and Docker

1. Introduction

While Terraform is famous for managing massive cloud providers like AWS and Azure, its architecture is provider-agnostic. If a technology has an API, Terraform can manage it. Docker is the industry standard for packaging and running applications. Instead of clicking buttons in the Docker Desktop GUI or typing long docker run commands in the terminal, we can use Terraform to mathematically define our local and remote containerized environments. In this chapter, we will explore the Terraform Docker provider, learning how to pull images, orchestrate containers, and manage local infrastructure entirely through code.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand how Terraform interacts with the Docker Daemon API.
  • Configure the kreuzwerker/docker provider.
  • Use Terraform to pull Docker images from remote registries.
  • Provision and configure Docker containers using HCL.
  • Manage container networking and port mapping via Terraform.

3. Beginner-Friendly Explanation

Imagine organizing a shipping yard.
  • The Old Way (Docker CLI): You stand in the yard with a megaphone, yelling: "Bring me a blue shipping container! Put it on port 80! Now bring me a red container!" If you go home and come back the next day, you have to yell all the instructions again to get the same setup.
  • The Terraform Way: You write a manifest (HCL code) listing exactly which containers you want and where they should sit. You hand the manifest to the yard manager (Terraform). The manager reads the list, moves the containers perfectly into place, and ensures they never move.

4. Configuring the Docker Provider

To manage Docker, Terraform needs to talk to the Docker Daemon running on your computer (or a remote server). We use the community-maintained kreuzwerker/docker provider.
hcl
1234567891011121314
terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

# Configure the provider to talk to the local Docker engine
provider "docker" {
  host = "npipe:////./pipe/docker_engine" # Windows Path
  # host = "unix:///var/run/docker.sock" # Linux/Mac Path
}

5. Managing Images and Containers

Once connected, we can define Docker Images (the blueprint) and Docker Containers (the running application).
hcl
1234567891011121314151617
# 1. Pull the Image from Docker Hub
resource "docker_image" "nginx_image" {
  name         = "nginx:latest"
  keep_locally = false # Delete the image when the container is destroyed
}

# 2. Run the Container
resource "docker_container" "nginx_container" {
  name  = "my-terraform-webserver"
  image = docker_image.nginx_image.image_id # Implicit dependency!
  
  # Map Port 80 inside the container to Port 8080 on your laptop
  ports {
    internal = 80
    external = 8080
  }
}

6. Mini Project: Deploy Docker Containers using Terraform

Let's build a multi-container environment: A WordPress website connected to a MySQL database, entirely orchestrated by Terraform on your local machine.

Step-by-Step Architecture Concept:

hcl
12345678910111213141516171819202122232425262728293031323334353637383940
# Pull Images
resource "docker_image" "mysql" { name = "mysql:5.7" }
resource "docker_image" "wordpress" { name = "wordpress:latest" }

# Create a Docker Network so they can talk to each other
resource "docker_network" "wp_net" {
  name = "wordpress_network"
}

# Build the Database
resource "docker_container" "db" {
  name  = "wp_database"
  image = docker_image.mysql.image_id
  
  # Connect to the custom network
  networks_advanced { name = docker_network.wp_net.name }
  
  env = [
    "MYSQL_ROOT_PASSWORD=somewordpress",
    "MYSQL_DATABASE=wordpress"
  ]
}

# Build the Website
resource "docker_container" "wp" {
  name  = "wp_website"
  image = docker_image.wordpress.image_id
  networks_advanced { name = docker_network.wp_net.name }
  
  ports {
    internal = 80
    external = 8080
  }
  
  env = [
    "WORDPRESS_DB_HOST=wp_database:3306", # Matches the DB container name!
    "WORDPRESS_DB_USER=root",
    "WORDPRESS_DB_PASSWORD=somewordpress"
  ]
}

*Run terraform apply. Open your browser to localhost:8080. You will see a fully functioning WordPress installation! When you are done, run terraform destroy to instantly wipe the database, the website, and the network.*

7. Real-World Scenarios

A development team was struggling with local environments. Getting a new developer's laptop set up with the correct versions of PostgreSQL, Redis, and Elasticsearch took two days of reading outdated Wiki guides. The DevOps engineer deleted the Wiki and wrote a single main.tf file using the Docker provider. New developers simply cloned the repository and ran terraform apply. Terraform automatically reached out to Docker, downloaded the exact container versions, configured the port mappings, and established the internal networking in 60 seconds, perfectly matching the production environment.

8. Best Practices

  • Terraform vs. Docker Compose: The mini-project above looks very similar to a docker-compose.yml file. If you are *only* managing local containers, docker-compose is usually better. However, if your architecture requires creating an AWS RDS Database, an S3 bucket, *and* a local Docker container for testing, Terraform is vastly superior because it can orchestrate all three providers simultaneously in the exact same state file.

9. Security Recommendations

  • Registry Authentication: In our examples, we pulled public images from Docker Hub. In an enterprise, images are stored in private registries (like AWS ECR). You must explicitly configure the docker provider block with a registryauth block, supplying the username and password required to securely pull your company's proprietary code.

10. Troubleshooting Tips

  • Socket Permissions: On Linux/Mac, the most common error is Cannot connect to the Docker daemon. This means Terraform does not have permission to talk to the docker.sock file. Ensure Docker Desktop is running, and that your user is added to the docker user group on your operating system.

11. Exercises

  1. 1. What is the purpose of the keeplocally = false argument in the dockerimage resource?
  1. 2. How does Terraform establish communication between two separate Docker containers using HCL?

12. FAQs

Q: Can I use Terraform to build the Docker image from a Dockerfile? A: While possible using null
resources and local-exec provisioners, it is an anti-pattern. Terraform is an *infrastructure* orchestrator, not a *build* tool. You should use a CI/CD pipeline (like GitHub Actions) to run docker build and push it to a registry. Terraform should then pull the pre-built image.

13. Interview Questions

  • Q: Contrast the operational use cases of docker-compose versus the Terraform Docker provider. When would an engineering team prioritize one tool over the other?
  • Q: Describe the HCL configuration required to provision a multi-container architecture where a frontend container securely communicates with a backend database container via an isolated Docker network.

14. Summary

In Chapter 12, we proved that Terraform's power extends beyond massive cloud data centers. By leveraging the Docker provider, we applied the exact same declarative HCL syntax to orchestrate lightweight, ephemeral containers on our local machines. We mastered the lifecycle of pulling immutable images from remote registries, defining container environment variables, and establishing complex, isolated bridge networking. This demonstrates Terraform's unparalleled flexibility as a universal control plane for any API-driven infrastructure.

15. Next Chapter Recommendation

Docker containers are great for local development, but in production, running a single container isn't highly available. Enterprises run thousands of containers orchestrated by the ultimate cloud technology. Proceed to Chapter 13: Terraform and Kubernetes.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·