How to

How to deploy a Docker stack with Terraform

By the end of this walk through you will have a running stack visible in the Portainer UI, deployed via Terraform.

5 min read
April 16, 2026
Last updated:
April 17, 2026
Table of Contents

Key takeaways

This guide walks you through deploying a Docker Compose stack to Portainer using Terraform.

If you are new to Terraform, the core idea is straightforward: you describe what you want in configuration files, and Terraform figures out how to make it happen. You declare the end state, and Terraform does the work.

Prerequisites

To get started, you’ll need:

• A running Portainer instance with admin access

• At least one Docker environment already connected to Portainer

• Terraform v1.0 or later installed on your local machine

• A Portainer API key

1. Set up your project

Note: The Portainer Terraform provider supports authentication using either an API key or username and password. This example uses API key authentication, which is recommended for automation.

Create a new directory for your Terraform configuration and navigate into it.

mkdir portainer-stack

cd portainer-stack

Create a main.tf file and add the provider configuration below. This tells Terraform where your Portainer instance is and how to authenticate with it.

# main.tf
  
terraform { 
  required_providers {   
    portainer = {     
      source = "portainer/portainer"   
  }
}

provider "portainer" {  
  endpoint = var.portainer_url  
  api_key = var.portainer_api_key
}

Create a variables.tf file to declare the variables used in your configuration:

# variables.tf

variable "portainer_url" {
  description = "The URL of your Portainer instance"
  type = string
}

variable "portainer_api_key" {
  description = "Portainer API key for authentication"
  type = string
  sensitive = true
}

Create a terraform.tfvars file to supply your Terraform configuration variables.

Important: Never commit credentials directly to source control, consider using a secrets manager.

# terraform.tfvars

portainer_url = "https://portainer.example.com"
portainer_api_key = "your-api-key-here"

Now initialise Terraform. This downloads the Portainer provider plugin and prepares your working directory:

terraform init

You should see output confirming the provider has been installed successfully.

2. Look up your environment

Note: The name value must exactly match the name of an existing environment in your Portainer instance. You can find this under Environments in the Portainer UI.

Create a file called data.tf containing your environment name:

# data.tf

data "portainer_environment" "target" {
	name = "my-docker-env"
}

When Terraform runs, it will query your Portainer instance for an environment matching that name and make its ID available to other resources as data.portainer_environment.target.id. You will use this in the next step.

3. Define your stack

Create a file called stack.tf. This is where you define the stack you want Portainer to deploy. In this example we are deploying a simple nginx web server, which is a good starting point for getting familiar with the workflow.

The deployment_type is set to "standalone" to tell Portainer this is a regular Docker Compose deployment, as opposed to Docker Swarm or Kubernetes.

The method is set to "string", which means the manifest content is provided inline, directly in the Terraform configuration.

The endpoint_id references the environment ID found in the previous step using the data source.

stack_file_content uses Terraform’s heredoc syntax (<<-EOT … EOT) to write a multiline string inline. The content is a standard Docker Compose file.

# stack.tf

resource "portainer_stack" "first_stack" {
  name = "my-first-stack"
  deployment_type = "standalone"
  method = "string"
  endpoint_id = data.portainer_environment.target.id
  stack_file_content = <<-EOT
    version: "3.8"  
    services:    
      web:
            image: nginx:latest
            ports:        
              - "8080:80"      
            restart: unless-stopped
  EOT
}

4. Preview the changes with terraform plan

Before making any changes to Portainer, Terraform lets you preview exactly what it intends to do. Run:

terraform plan -out stack.tfplan

Terraform will connect to your Portainer instance, compare the current state to what your configuration describes, and print a summary of what it plans to do.

Each line prefixed with + means that resource will be created.

Lines with ~ indicate updates

Lines with - indicate deletions.

The -out flag saves the plan to a file. This guarantees that when you run apply, Terraform executes exactly what you reviewed and nothing more. If you skip it, Terraform will generate a fresh plan at apply time and ask you to confirm interactively.

5. Deploy the stack with terraform apply

Once you are happy with the plan, apply it:

terraform apply stack.tfplan

Terraform will carry out the actions shown in the plan and report back as each one completes.

Once finished, you will see a summary confirming how many resources were added, changed, or destroyed.

Terraform also writes a state file terraform.tfstate to your project directory. This records what has been created and is how Terraform knows what already exists the next time you run plan or apply. To update your stack later, edit stack.tf and run plan and apply again. Terraform will update the stack in place rather than recreating it from scratch.

Important: The state file can contain sensitive values - do not commit it to source control.

6. Verify the stack is running and optionally remove the stack

Navigate to your environment and select Stacks in the Portainer UI. You should see your stack listed. If you want to remove the stack from Portainer, run terraform destroy. Terraform will show you what will be deleted and ask you to confirm before proceeding.

terraform destroy

Important: Terraform destroy removes everything Terraform manages in your current configuration. Only run this when you intend to fully remove the resources.

Further examples

An extensive list of additional examples - including edge stacks, registries, S3 backups, and more - can be found in the Portainer Terraform provider GitHub repository.

Full provider documentation is available within the Terraform docs.

Try Portainer with 3 Nodes Free

If you're ready to get started with Portainer Business, 3 nodes free is a great place to begin. If you'd prefer to get in touch with us, we'd love to hear from you!

Heading

Tip  / Call out

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

Let our experienced engineers set up and manage your Kubernetes infrastructure for you.

Kubernetes Managed Services
No items found.