๐ Dockerizing Flask โ Why It Matters
Dockerizing a Flask app bundles the source, dependencies, and runtime into a single immutable image. This guarantees that the same environment runs everywhere, from a developer laptop to a production VM.
๐ Table of Contents
- ๐ Dockerizing Flask โ Why It Matters
- ๐จ Build the Image
- ๐ฆ Image Layers
- ๐ง Terraform Basics โ How Terraform Works
- ๐ State Management
- ๐งฉ Provider Configuration
- ๐ Infrastructure as Code โ Deploying with Terraform
- ๐ Automated Docker Install
- ๐ก Network Configuration
- ๐ Running the Container โ Automation Details
- ๐ฉ Final Thoughts
- โ Frequently Asked Questions
- Can I use a different cloud provider?
- How do I update the Flask code without rebuilding the image?
- Is the EC2 instance automatically terminated when I destroy the stack?
- ๐ References & Further Reading
๐ง Terraform Basics โ How Terraform Works
Terraform reads declarative HCL files, builds a dependency graph, and issues API calls that create, modify, or destroy cloud resources.
# main.tf
terraform { required_version = ">= 1.5" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }
} provider "aws" { region = "us-east-1"
}
What this does:
- terraform { โฆ } : pins the Terraform version and declares required providers.
- provider "aws": configures the AWS SDK with the target region.
According to the Terraform documentation, the provider block is evaluated before any resources, ensuring credentials and region are set for subsequent API calls.
๐ State Management
Terraform stores the desired state in a .tfstate file (JSON format). During terraform apply, it reads the current state, diffs it against the configuration, and generates a plan that contains only the required changes. This delta approach minimizes API calls and prevents accidental resource drift. (Also read: โ๏ธ Terraform create AWS EC2 instance with Python environment)
๐งฉ Provider Configuration
Explicitly setting region overrides the default fallback to the environment variable AWS_DEFAULT_REGION, which can differ between CI pipelines and local machines. Consistent region selection is essential for reproducible terraform deploy python flask docker runs.
Key point: Terraformโs planโapply cycle provides a preview of every change, so you never apply a configuration blindly.
๐ Infrastructure as Code โ Deploying with Terraform
The Terraform configuration creates an EC2 instance, installs Docker, and starts the Flask container automatically. (Also read: ๐ Automate MySQL backup restore with python inside docker containers made easy)
# ec2.tf
resource "aws_instance" "flask_host" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" # User data runs on first boot; it installs Docker and runs the container user_data = <<-EOF #!/bin/bash set -e apt-get update apt-get install -y docker.io systemctl start docker docker pull ${var.docker_image} docker run -d -p 80:5000 ${var.docker_image} EOF tags = { Name = "flask-app" } vpc_security_group_ids = [aws_security_group.flask_sg.id]
}
What this does:
- ami : selects an Ubuntu image via a data source (defined elsewhere).
- instance_type : chooses a lowโcost instance suitable for a small Flask service.
-
user_data : runs a cloudโinit script that installs Docker, pulls the image defined by
var.docker_image, and runs it on port 80. - vpc_security_group_ids : attaches a security group that permits inbound HTTP traffic.
Automating the install ensures the instance is ready the moment it boots, eliminating manual steps and making the terraform deploy python flask docker process repeatable. (Also read: ๐ Python generators vs iterators in data pipelines โ which one should you use?)
๐ Automated Docker Install
The user_data script runs as root during the first boot. It uses apt-get install -y docker.io to pull Docker Engine from the Ubuntu repository, guaranteeing kernel compatibility. The subsequent docker run -d -p 80:5000 command detaches the container and maps host port 80 to container port 5000, exposing the Flask service. (More onPythonTPoint tutorials)
๐ก Network Configuration
# sg.tf
resource "aws_security_group" "flask_sg" { name = "flask-sg" description = "Allow HTTP inbound" ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
}
What this does:
- ingress : opens port 80 to the internet, allowing the Flask app to receive HTTP requests.
- egress : permits all outbound traffic, which Docker needs for pulling images from Docker Hub.
Using a dedicated security group isolates the Flask host from other workloads and makes network policy changes auditable.
Automating both the OS and container layers removes the โit works on my machineโ gap entirely.
Key point: The combined EC2 + userโdata approach lets Terraform manage the entire lifecycle of a Dockerโbased Flask service without separate provisioning steps.
๐ Running the Container โ Automation Details
After Terraform applies, the EC2 instance runs the Flask container, exposing it on port 80.
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws...
Terraform has been successfully initialized! $ terraform plan
Refreshing the state...
No changes. Your configuration is already up-to-date. $ terraform apply -auto-approve
aws_instance.flask_host: Creating...
aws_instance.flask_host: Still creating... [10s elapsed]
aws_instance.flask_host: Creation complete after 12s [id=i-0abcd1234efgh5678] Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
When the apply finishes, the instance is reachable via its public IP. Verify the Flask endpoint:
$ curl http://$(terraform output -raw public_ip)
{"message":"Hello from Flask!"}
Under the hood, Terraform calls the AWS API to launch the EC2 instance; the cloudโinit daemon then executes the user_data script. Dockerโs daemon processes the docker pull request, downloads the cached layers, assembles the image, and starts the container. Because the image layers remain cached on the host, subsequent Terraform runs that only change the instance type complete faster, illustrating the efficiency of the terraform deploy python flask docker workflow.
Key point: The entire stackโfrom infrastructure provisioning to container runtimeโis defined as code, enabling versionโcontrolled rollbacks and reproducible environments.
๐ฉ Final Thoughts
Using Terraform to provision a Docker host for a Flask application removes manual steps, enforces consistent environments, and provides a single source of truth for both infrastructure and container configuration. The declarative nature of Terraform allows you to track changes in version control, review them before they affect production, and roll back with a single command if a new image introduces a regression.
The practical takeaway is that the same tool you use to spin up VPCs can also manage the lifecycle of a Python Flask container, reducing operational overhead and keeping deployments repeatable.
โ Frequently Asked Questions
Can I use a different cloud provider?
Yes. Terraform supports providers for Azure, Google Cloud, and many others. Replace the aws provider block with the appropriate provider and adjust the resource definitions accordingly.
How do I update the Flask code without rebuilding the image?
Mounting the source directory as a volume in docker run works for rapid iteration, but it defeats the reproducibility advantage of a built image. The recommended approach is to rebuild the image, push a new tag, and update the var.docker_image variable before reโapplying Terraform.
Is the EC2 instance automatically terminated when I destroy the stack?
Terraform tracks the instance as a resource. Running terraform destroy issues an API call to terminate the EC2 instance and delete the associated security group, leaving no orphaned resources.
๐ก Want to practise this hands-on? DigitalOcean gives new accounts $200 free credit for 60 days โ enough to spin up a full Linux/Docker/Kubernetes environment at no cost.
๐ Recommended reading: Best DevOps & cloud books on Amazon โ from Linux fundamentals to Kubernetes in production, curated for working engineers.
๐ References & Further Reading
- Official Flask documentation โ guides on building and testing Flask apps: flask.palletsprojects.com
- Docker Engine installation guide for Ubuntu โ steps used in the userโdata script: docs.docker.com

Top comments (0)