Manage Docker on a Raspberry Pi with Terraform
Use Terraform to provision and manage Docker containers on a Raspberry Pi over SSH.
Introduction
30 Second Summary
Imagine you could set up and tear down an entire server environment on a remote machine without ever logging into it. That is the promise of Infrastructure as Code.
In this project, you will use Terraform on your Mac to remotely provision Docker containers on a Raspberry Pi over SSH. You will write configuration files, deploy a web server and cache, modify the setup, and destroy everything with a single command.
What You'll Build
A Terraform project that connects to your Raspberry Pi's Docker daemon over SSH and provisions a multi-container environment with an Nginx web server and a Redis cache on a shared network.
By the end of this project, you'll have:
- A working Terraform project with main.tf, variables.tf, and outputs.tf that manages remote Docker containers on your Pi.
- A running Nginx web server accessible from your local network, plus a Redis container on the same Docker network.
- Hands-on experience with the full Infrastructure as Code lifecycle: init, plan, apply, modify, and destroy.
- Secret Mission: Add persistent storage for Redis and scale Nginx to multiple replicas using Terraform's count meta-argument.
Are there any prerequisites?
You need a Raspberry Pi with Docker installed and SSH key-based access from your Mac. You also need Terraform installed on your Mac. Step 1 walks you through verifying each of these.
Verify Your Setup
Before writing any Terraform code, you need to confirm that your tools are in working order.
Terraform must be available on your Mac at version 1.2 or higher, and your Mac needs to reach the Raspberry Pi over SSH without a password prompt. Once both checks pass, you'll create a project folder to hold your Terraform configuration files.
In this step, get ready to:
- Confirm Terraform 1.2+ is installed on your Mac.
- Verify password-free SSH access to your Raspberry Pi.
- Create the project directory for your Terraform files.
Verify Terraform on your Mac
Terraform is the Infrastructure as Code tool you'll use to manage Docker containers on your Pi from your Mac. You need version 1.2 or higher for the configuration syntax this project uses.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal and press Enter to open it.
- Check your Terraform version by running this command:
terraform -version
You should see output starting with Terraform v followed by a version number of 1.2.0 or higher. The latest version is 1.15.5.
Don't see a version number?
If you see a "command not found" error, Terraform is not installed or not on your system PATH. Install it with Homebrew by running:
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
If you see a version lower than 1.2.0, upgrade by running:
brew update
brew upgrade hashicorp/tap/terraform
help me install Terraform on my Mac
Verify SSH connectivity to your Pi
Terraform's Docker provider connects to your Raspberry Pi over SSH. This means your Mac must be able to reach the Pi without a password prompt, using key-based authentication.
- Test your SSH connection and confirm Docker is available on the Pi by running this command:
ssh pi@raspberrypi.local "docker --version"
This should immediately print the Docker version installed on your Pi without asking for a password. Note your Pi's hostname (raspberrypi.local) or IP address. You'll use it in the next step.
Getting a password prompt?
If SSH asks for a password, your key-based authentication is not set up yet. Copy your SSH key to the Pi by running:
ssh-copy-id pi@raspberrypi.local
Enter your Pi's password when prompted. After this completes, try the original command again. It should connect without a password.
If you see "Could not resolve hostname", your Pi might use a different address. Try using your Pi's IP address instead (check your router's connected devices list).
help me set up SSH key-based access to my Raspberry Pi
Create the project directory
With your tools verified, it's time to create a folder for your Terraform project files.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir terraform-docker-pi
cd terraform-docker-pi
- Confirm the folder was created by running:
pwd
You should see a path ending in terraform-docker-pi.
Not seeing the right path?
Make sure you ran both mkdir and cd as separate commands. If you combined them with && and the first command failed, the second won't run.
If the folder already exists from a previous attempt, that's fine. Just run cd ~/Desktop/terraform-docker-pi to move into it.
help me create my Terraform project directory
Your tools are confirmed and your project folder is ready. Next up, you'll write the Terraform configuration that tells your Mac how to manage Docker containers on the Pi.
Write the Terraform Configuration
Your setup is verified. Terraform is ready on your Mac, and your Raspberry Pi is reachable over SSH.
Now you'll write the Terraform configuration files that describe your desired infrastructure. Terraform reads these .tf files and turns them into real Docker containers running on your Pi.
In this step, get ready to:
- Create main.tf with the provider configuration that connects Terraform to your Pi's Docker daemon over SSH.
- Define Docker image and container resources for an Nginx web server.
- Create variables.tf to keep your configuration flexible.
Create main.tf with the Terraform block and Docker provider
Every Terraform project starts with two declarations: which providers you need, and how those providers connect to their targets. HCL (HashiCorp Configuration Language) is the declarative language you write these in.
- Create and open a new file called main.tf in your terminal editor by running:
vim main.tf
Use your preferred editor
If you prefer a different terminal editor, use emacs main.tf or nano main.tf instead.
- Add the following Terraform block and provider configuration to the file:
# Declare the Docker provider dependency
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 4.0"
}
}
required_version = ">= 1.2"
}
# Connect to the Pi's Docker daemon over SSH
provider "docker" {
host = "ssh://${var.pi_user}@${var.pi_host}"
ssh_opts = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]
}
What does this code do?
The terraform block tells Terraform to download the kreuzwerker/docker provider (version 4.x) and requires Terraform 1.2+ to run the project.
The provider "docker" block configures how Terraform connects to Docker. The host argument uses an SSH URL that points at your Pi, and ssh_opts disables strict host checking so the connection doesn't stall on a fingerprint prompt.
Why SSH instead of TCP?
Docker can listen on a TCP port, but that requires configuring TLS certificates on the Pi. SSH reuses the key-based access you already verified in Step 1. No extra setup needed.
You won't see a visible change yet. The next chunk adds the Docker resources that this provider manages.
Add the Docker image and container resources
Terraform resources describe the actual infrastructure you want to exist. You need two: one to pull the Nginx image and one to run a container from it.
- Add the following resource blocks below the provider block in main.tf:
# Pull the Nginx image on the Pi
resource "docker_image" "nginx" {
name = "nginx:alpine"
}
# Run an Nginx container with port 8080 exposed
resource "docker_container" "webserver" {
name = "webserver"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 8080
}
restart = "unless-stopped"
}
What does this code do?
The docker_image resource tells Terraform to pull nginx:alpine onto the Pi. This is a lightweight Nginx image that supports ARM architectures like the Raspberry Pi.
The docker_container resource creates a container named webserver from that image. It maps port 8080 on the Pi to port 80 inside the container. The restart = "unless-stopped" setting ensures the container restarts automatically if the Pi reboots.
- Save and close main.tf.
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before moving on.
ⓧ I'd like to double check the full code
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 4.0"
}
}
required_version = ">= 1.2"
}
provider "docker" {
host = "ssh://${var.pi_user}@${var.pi_host}"
ssh_opts = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]
}
resource "docker_image" "nginx" {
name = "nginx:alpine"
}
resource "docker_container" "webserver" {
name = "webserver"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 8080
}
restart = "unless-stopped"
}
Create variables.tf
The provider block references var.pi_user and var.pi_host. Terraform needs a separate file declaring these variables with types and defaults.
- Create and open variables.tf by running:
vim variables.tf
- Add the following variable declarations to the file:
# The hostname or IP of your Raspberry Pi
variable "pi_host" {
description = "Hostname or IP address of the Raspberry Pi"
type = string
default = "raspberrypi.local"
}
# The SSH user on your Pi
variable "pi_user" {
description = "SSH username for the Raspberry Pi"
type = string
default = "pi"
}
What does this code do?
Each variable block declares an input that other .tf files can reference with the var. prefix. The default values mean you don't have to type them every time you run Terraform.
If your Pi uses a different hostname or username, change the defaults here. The rest of the configuration stays the same.
- Save and close variables.tf.
- Verify both files are valid HCL by running:
terraform fmt
- If the command produces no output, your files are already correctly formatted. If it prints a filename, that file was reformatted for you.
- Confirm both files exist by running:
ls *.tf
- You should see main.tf and variables.tf listed in the output.
Seeing a syntax error from terraform fmt?
Check for mismatched braces or brackets in your main.tf. Each opening { needs a matching } and each opening [ needs a matching ].
Also verify that string values are wrapped in double quotes, not single quotes. HCL requires double quotes for all strings.
help me fix a terraform fmt syntax error in my main.tf file
✔️ Awesome, I've got everything!
Great. Double check you've saved both files before moving on.
ⓧ I'd like to double check the full code
variable "pi_host" {
description = "Hostname or IP address of the Raspberry Pi"
type = string
default = "raspberrypi.local"
}
variable "pi_user" {
description = "SSH username for the Raspberry Pi"
type = string
default = "pi"
}
Why use variables instead of hardcoding?
Variables make your configuration reusable. If your Pi's hostname changes or you want to point Terraform at a different machine, you update one file instead of hunting through every reference.
Your configuration is written and formatted. Next up, you'll initialize the project, let Terraform download the Docker provider, and deploy your first container to the Pi.
Initialize, Deploy, and Verify
Your Terraform configuration is written and ready to go. You have a provider pointing at your Pi over SSH, an image to pull, and a container to run.
Now it's time to bring your infrastructure to life. Terraform's workflow has three stages: initialize the project to download providers, plan to preview changes, then apply to make them real on your Pi.
In this step, get ready to:
- Initialize the Terraform project and download the Docker provider.
- Deploy the Nginx container to your Raspberry Pi.
- Verify the web server is accessible from your Mac's browser.
Initialize and plan
Before Terraform can manage anything, it needs to download the provider plugin that knows how to talk to Docker. This is what terraform init does.
- Download the Docker provider by running this command:
terraform init
You should see output ending with:
Terraform has been successfully initialized!
What does this command do?
Terraform reads the required_providers block in your main.tf and downloads the kreuzwerker/docker provider plugin into a hidden .terraform directory.
It also creates a .terraform.lock.hcl file that records the exact provider version installed. This ensures consistent builds across machines.
Seeing a network error?
Terraform needs internet access to download the provider from the Terraform Registry. Check that your Mac is connected to the internet and try again.
help me troubleshoot terraform init failing
Now preview what Terraform will create on your Pi.
- Preview the resources Terraform will create by running:
terraform plan
At the bottom of the output, you should see a summary line showing 2 resources to add: one image pull and one container.
What does the plan show?
The plan output lists every resource Terraform intends to create, with a + symbol next to each one. It shows docker_image.nginx (the image to pull) and docker_container.webserver (the container to start).
The plan summary at the bottom reads: Plan: 2 to add, 0 to change, 0 to destroy. Nothing is running yet. Terraform only makes changes when you explicitly apply.
Plan failing with a connection error?
Terraform tries to connect to your Pi during the plan phase. Make sure your Pi is powered on and reachable from your Mac.
- Verify your Pi is reachable by running ssh pi@raspberrypi.local "echo connected" in a separate terminal.
- If that fails, double-check the pi_host default value in variables.tf matches your Pi's actual hostname or IP.
help me fix a terraform plan SSH connection error
Apply the configuration
The plan looks good. Time to make it real. The terraform apply command sends instructions to your Pi's Docker daemon over SSH, pulling the image and starting the container.
- Deploy your infrastructure by running:
terraform apply
- Terraform shows the same plan output, then asks for confirmation. Type yes and press Enter.
Terraform connects to your Pi, pulls the nginx:alpine image, and starts the webserver container. You should see output ending with Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
What just happened?
Terraform used your Mac's SSH connection to reach the Docker daemon on your Pi. It pulled the Nginx image and started a container, all without you ever logging into the Pi manually.
A terraform.tfstate file now exists on your Mac. This state file records what Terraform created on the remote Pi, so it can track changes and clean up later.
Apply failed with a permission error?
Your Pi user needs permission to run Docker commands. Make sure the pi user is in the docker group on your Raspberry Pi.
- Check by running ssh pi@raspberrypi.local "groups" and looking for docker in the output.
- If it's missing, run ssh pi@raspberrypi.local "sudo usermod -aG docker pi" then reboot the Pi.
help me fix Docker permission errors on my Raspberry Pi
Verify the web server is running
Your Nginx container should now be serving traffic on port 8080 of your Pi. Let's confirm it's accessible from your Mac.
- Open your browser and navigate to:
http://raspberrypi.local:8080
You should see the default Nginx welcome page with the heading "Welcome to nginx!" in your browser.
- Alternatively, verify from your terminal by running:
curl http://raspberrypi.local:8080
This prints the raw HTML of the Nginx welcome page to your terminal, confirming the container is serving traffic.
Page not loading?
- Check the container is actually running on the Pi by running ssh pi@raspberrypi.local "docker ps". You should see a container named webserver in the list.
- If your Pi uses a different hostname or IP, replace raspberrypi.local with the address you used in variables.tf.
- Make sure nothing else on your network is using port 8080.
help me troubleshoot why I can't reach Nginx on my Raspberry Pi
Your first piece of remote infrastructure is live. You wrote code on your Mac and Terraform turned it into a running container on your Pi. Next up, you'll expand the setup with a Docker network and a Redis container.
Add a Network and Redis Container
Your Nginx container is running on the Pi, proving that Terraform can manage remote Docker resources over SSH.
Right now, your container is isolated. Real applications need multiple services that talk to each other. In this step, you will create a Docker network so containers can communicate by name, then add a Redis cache container alongside your web server.
In this step, get ready to:
- Add a Docker network and connect the Nginx container to it.
- Add a Redis container on the same network.
- Create an outputs file and apply all changes to the Pi.
Add a Docker network to main.tf
Containers on the same Docker network can reach each other using their container name as a hostname. Without a shared network, your containers would be isolated from each other.
- In your terminal editor, open main.tf.
- Add this network resource below the docker_image "nginx" block:
resource "docker_network" "app_network" {
name = "terraform-net"
}
- Now find your docker_container "webserver" resource. Add a networks_advanced block between the ports block and the restart line:
networks_advanced {
name = docker_network.app_network.name
}
What does this do?
The docker_network resource creates a named network called terraform-net on your Pi's Docker daemon.
The networks_advanced block inside the container resource attaches that container to the network. Any container on terraform-net can reach any other container on the same network by name.
- Save main.tf.
- Confirm the formatting is valid by running:
terraform fmt
If your HCL is well-formatted, this command prints nothing. If it prints a filename, Terraform auto-fixed spacing for you.
Seeing an error from terraform fmt?
A syntax error means you have a missing brace, a stray quote, or incorrect indentation. Check that the networks_advanced block has its own opening { and closing }, and that it sits inside the docker_container "webserver" block (not outside it).
Help me fix a terraform fmt error in my main.tf network configuration.
Add the Redis container
Redis is an in-memory data store commonly used as a cache. Adding it to your Terraform config demonstrates how to manage multiple containers on the same network.
- In main.tf, add the Redis image and container resources below your docker_network "app_network" block (and above docker_container "webserver"):
resource "docker_image" "redis" {
name = "redis:alpine"
}
- Then add the Redis container resource at the very end of main.tf, after the docker_container "webserver" block:
resource "docker_container" "cache" {
name = "cache"
image = docker_image.redis.image_id
networks_advanced {
name = docker_network.app_network.name
}
restart = "unless-stopped"
}
What does this code do?
The docker_image "redis" resource pulls the redis:alpine image onto your Pi. Alpine-based images are small and work well on the Pi's ARM architecture.
The docker_container "cache" resource starts a Redis container named cache on the same terraform-net network. Your Nginx container can now reach Redis at the hostname cache.
- Save main.tf.
- Run terraform fmt again to confirm no syntax issues.
Seeing a syntax error?
Make sure each resource block has matching braces. The networks_advanced block must be nested inside the container block, not at the top level.
Help me fix a syntax error in my Redis container resource.
✔️ Awesome, I've got everything!
Great. Double check you have saved main.tf before moving on.
ⓧ I'd like to double check the full code
Here is the complete main.tf at this point:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 4.0"
}
}
required_version = ">= 1.2"
}
provider "docker" {
host = "ssh://${var.pi_user}@${var.pi_host}"
ssh_opts = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]
}
resource "docker_image" "nginx" {
name = "nginx:alpine"
}
resource "docker_image" "redis" {
name = "redis:alpine"
}
resource "docker_network" "app_network" {
name = "terraform-net"
}
resource "docker_container" "webserver" {
name = "webserver"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 8080
}
networks_advanced {
name = docker_network.app_network.name
}
restart = "unless-stopped"
}
resource "docker_container" "cache" {
name = "cache"
image = docker_image.redis.image_id
networks_advanced {
name = docker_network.app_network.name
}
restart = "unless-stopped"
}
Create outputs.tf and apply
Terraform outputs let you extract useful values from your infrastructure after it is deployed. You will create an outputs file that surfaces the web server URL and container names.
- Create a new file called outputs.tf in the same terraform-docker-pi directory and add the following:
output "webserver_url" {
description = "URL to access the Nginx web server"
value = "http://${var.pi_host}:8080"
}
output "containers" {
description = "Names of managed containers"
value = [docker_container.webserver.name, docker_container.cache.name]
}
What do these outputs do?
The webserver_url output builds the full URL using your Pi's hostname variable. After apply, Terraform prints this so you know where to access your server.
The containers output lists both managed container names, giving you a quick inventory of what Terraform is managing on the Pi.
- Save outputs.tf.
- Format both files by running:
terraform fmt
- Deploy all the changes to your Pi by running:
terraform apply
- Type yes when prompted to confirm.
What should I see in the plan?
Terraform's plan shows it will create the Docker network, pull the Redis image, and start the cache container. It will also update the existing webserver container to attach it to the new network.
After apply completes, Terraform prints your output values including the web server URL and container names.
- Verify both containers are running on the Pi by running:
ssh pi@raspberrypi.local "docker ps"
You should see both webserver and cache listed in the output, confirming Terraform provisioned them on the Pi over SSH.
Only seeing one container?
If cache is missing, check that your docker_container "cache" resource uses docker_image.redis.image_id (not the image name string). Terraform needs the reference to know it should pull the image first.
If terraform apply failed entirely, look for error messages about SSH connectivity. Make sure your Pi is still reachable with ssh pi@raspberrypi.local.
Help me troubleshoot my terraform apply for Docker containers.
✔️ Awesome, I've got everything!
Great. Make sure you have saved outputs.tf and confirmed both containers are running.
ⓧ I'd like to double check the full code
Here is the complete outputs.tf:
output "webserver_url" {
description = "URL to access the Nginx web server"
value = "http://${var.pi_host}:8080"
}
output "containers" {
description = "Names of managed containers"
value = [docker_container.webserver.name, docker_container.cache.name]
}
Your Pi is now running a multi-container setup managed entirely from your Mac. Next up, you will modify the configuration, inspect Terraform state, and tear everything down with a single command.
Modify, Inspect State, and Destroy
You have a working multi-container environment running on your Pi. Now comes the real power of Infrastructure as Code: making changes to running infrastructure by editing a file and re-applying.
In this step, you will modify the Nginx port, watch Terraform detect the change and recreate only the affected container, inspect the state that tracks your remote resources, and finally tear everything down with a single command.
In this step, get ready to:
- Change the Nginx container's port and re-apply the configuration.
- Inspect Terraform state to see how it tracks remote resources.
- Destroy all infrastructure on the Pi with one command.
Change the Nginx container port
When you change a resource attribute that cannot be updated in-place, Terraform must destroy and recreate that resource. Port mappings on a Docker container are one such attribute. Changing the external port forces Terraform to replace the container.
- In main.tf, scroll down to the docker_container.webserver resource.
- Find this line inside the ports block:
external = 8080
- Replace 8080 with 9090, so the line now looks like this:
external = 9090
- Save main.tf.
- Preview the change by running this command:
terraform plan
You should see Terraform report that it must replace the webserver container. The plan shows a destroy-then-create action because port changes cannot be applied to a running container.
- Apply the change by running:
terraform apply
- Type yes when prompted to confirm.
What just happened?
Terraform detected that the port changed from 8080 to 9090, determined it could not update the container in-place, and replaced it. The Redis container and Docker network were untouched because nothing in their configuration changed.
This is a core IaC principle: you describe the desired end-state, and Terraform figures out the minimum set of changes to get there.
- Verify the web server responds on the new port by running:
curl http://raspberrypi.local:9090
You should see the default Nginx welcome page HTML in your terminal output.
Not seeing the Nginx page on port 9090?
- Make sure you saved main.tf before running terraform apply.
- Confirm you changed external = 8080 to external = 9090 (not the internal line).
- If your Pi uses a different hostname or IP, substitute that in the URL.
Help me troubleshoot why my Nginx container isn't responding on port 9090 after terraform apply.
✔️ Awesome, I've got everything!
Great. Double check you have saved main.tf with the port set to 9090.
ⓧ I'd like to double check the full code
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 4.0"
}
}
required_version = ">= 1.2"
}
provider "docker" {
host = "ssh://${var.pi_user}@${var.pi_host}"
ssh_opts = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]
}
resource "docker_image" "nginx" {
name = "nginx:alpine"
}
resource "docker_image" "redis" {
name = "redis:alpine"
}
resource "docker_network" "app_network" {
name = "terraform-net"
}
resource "docker_container" "webserver" {
name = "webserver"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 9090
}
networks_advanced {
name = docker_network.app_network.name
}
restart = "unless-stopped"
}
resource "docker_container" "cache" {
name = "cache"
image = docker_image.redis.image_id
networks_advanced {
name = docker_network.app_network.name
}
restart = "unless-stopped"
}
Inspect Terraform state
Terraform stores the mapping between your configuration and the real resources on your Pi in a local state file. You can query this state to see exactly what Terraform is managing.
- List all managed resources by running:
terraform state list
You should see a list of all five resources, one per line:
docker_container.cache
docker_container.webserver
docker_image.nginx
docker_image.redis
docker_network.app_network
- Inspect the webserver container's details by running:
terraform state show docker_container.webserver
You should see all the container's attributes: the image ID, port mappings, network attachments, and restart policy.
Why does this matter?
Terraform tracks the remote Pi's Docker state in a local file on your Mac (terraform.tfstate). This is how it knows what exists, what changed, and what to destroy. Without this state file, Terraform would have no memory of what it created.
In team environments, this state is stored remotely (in a backend like S3 or Terraform Cloud) so everyone shares the same source of truth.
Destroy all resources
The final piece of the IaC lifecycle is tearing down infrastructure. With one command, Terraform removes every resource it created on your Pi.
- Destroy all managed infrastructure by running:
terraform destroy
What will Terraform ask?
Terraform will show a plan listing every resource it intends to remove, then prompt you with a confirmation. Only typing yes will proceed. There is no undo.
- Type yes when prompted to confirm the destruction.
- Verify the containers are gone by running:
ssh pi@raspberrypi.local "docker ps"
You should see no Terraform-managed containers in the output. The webserver, cache, network, and images have all been removed from your Pi.
- Confirm the state is empty by running:
terraform state list
This should produce no output, confirming that Terraform's state is clean.
Destroy failed or containers still showing?
- If the SSH connection timed out, check that your Pi is still reachable with ping raspberrypi.local.
- If docker ps still shows containers, they may have been created manually outside of Terraform. Only Terraform-managed containers are removed by terraform destroy.
Help me debug why terraform destroy didn't remove my containers.
Secret mission
Persistent Storage and Multiple Replicas
Your Terraform project can provision containers, but what about data that needs to survive container restarts? And what if one Nginx instance isn't enough? In this mission, you'll add a Docker volume for Redis persistence and use Terraform's count meta-argument to spin up multiple Nginx replicas on different ports.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely on your local Mac and Raspberry Pi, so there are no ongoing cloud costs. Decide whether to keep your containers running on the Pi, pause them to free up resources, or delete everything entirely.
Resources you used:
- Docker containers, images, network, and volume on your Raspberry Pi (managed by Terraform).
- The terraform-docker-pi project directory on your Mac.
Keep everything running
No action needed. Choose this if you're still actively experimenting with your Terraform configuration or plan to extend the project further.
- Your Nginx replicas and Redis container continue running on the Pi.
- The terraform-docker-pi directory stays on your Mac with your Terraform state intact.
- You can run terraform destroy at any time later to tear everything down.
Pause - I'll come back to this later
Shut down the containers on your Pi to free up its memory and CPU, but keep your project files on your Mac so you can re-apply later.
- Navigate to your project directory and run this command to remove all containers, the network, the volume, and pulled images from the Pi:
cd ~/Desktop/terraform-docker-pi
terraform destroy
- Type yes when prompted to confirm.
- Your terraform-docker-pi directory stays on your Mac. When you're ready to resume, run terraform apply to recreate everything.
Delete - I don't want to use this again
Remove all project resources from your Pi and delete the project files from your Mac.
- First, destroy all Docker resources on the Pi by running:
cd ~/Desktop/terraform-docker-pi
terraform destroy
- Type yes when prompted to confirm.
- Then delete the project directory from your Mac:
cd ~/Desktop
rm -rf terraform-docker-pi
- Verify the folder is gone by running:
ls ~/Desktop | grep terraform
- You should see no output, confirming the directory has been removed.
That's a Wrap!
That's a Wrap!
Nice work! You just built a complete Terraform project that manages real remote infrastructure on your Raspberry Pi, all from the comfort of your Mac's terminal.
You've learned how to:
- Build a Terraform project that provisions and manages Docker containers on a remote Raspberry Pi over SSH.
- Create a multi-container environment with Nginx and Redis on a shared Docker network, using variables and outputs to keep the configuration flexible.
- Run the full Infrastructure as Code lifecycle: init, plan, apply, modify, and destroy remote infrastructure with single commands.
- Secret Mission: Used count to scale Nginx replicas across multiple ports and Docker volumes for persistent Redis data.
Ready to quiz yourself?