As a full-stack developer and DevOps engineer well-versed in both Windows and Linux environments, I often get asked how to set up Docker Compose and use it effectively for local development.
In this comprehensive 3200+ word guide, I‘ll cover everything you need to know as a fellow developer to get Docker Compose running on Windows, demonstrate its capabilities through examples, and offer best practices for integrating Compose as you move applications to production.
Understanding Docker and Compose Architecture
Before we install, let‘s briefly review core Docker architecture and where Compose fits in.

Docker utilizes a client-server model:
-
Docker daemon – Container runtime that manages images, containers, builds, and more. This runs on each Docker host machine.
-
REST API – API for interacting with daemon to instruct it what containers to create, delete, run commands inside, etc.
-
Docker client – Client tool (CLI) used to communicate with daemon through REST API.
When you run docker build, docker run etc. on your machine, the Docker CLI talks to the daemon.
So what is Docker Compose?
On its own, Docker lets you run one container at a time. With microservices architectures, applications require multiple containers like databases, queues, web servers etc.
This is where Docker Compose comes in – it lets you:
-
Define multi-container environments in a YAML file – Outline all the services an app needs to run.
-
Start all with one command (
docker-compose up) – Single command to bring up or down whole application stacks.
So Compose makes dealing with complex multi-service containers MUCH easier.
Now let‘s look at installing it on Windows!
Prerequisites
Docker adoption has accelerated greatly thanks to improvements in UX and availability on major platforms:
| Year | Total Docker Pulls |
|---|---|
| 2019 | 75+ billion |
| 2020 | 133+ billion |
Over 4 million Docker apps have been shared between developers.
Docker Desktop enables having Docker easily on Windows 10/11 for development usage.
To install Compose, first download and install Docker Desktop if you don‘t already have it. This includes the latest versions of:
- Docker Engine
- Docker CLI
- Docker Compose
- Kubernetes
- Credential Guard
So Docker Desktop is our gateway to Compose on Windows.
Double click to install the downloaded installer pkg. Keep default options and hit OK.
After install, Docker starts automatically. Verify status in system tray – you should see whale icon.
Now let‘s confirm Compose installation.
Checking Docker Compose Version
Once Docker Desktop launches, open PowerShell or command prompt to check Compose version:
docker-compose --version
You should see the latest stable release:
docker-compose version 1.29.2, build 5becea4c
Success! Docker handles pulling the latest Compose release so we always stay up-to-date.
Now we can use it to run multi-container apps.
A Simple Docker Compose Demo
Let‘s walk through a Compose demo to see it in action.
We‘ll build and run a Python Flask app with Redis for showing page view counts.
First, make a folder for project code:
mkdir my-compose-demo
cd my-compose-demo
We need three files – app.py, requirements.txt and Dockerfile:
app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host=‘redis-server‘, port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr(‘hits‘)
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route(‘/‘)
def index():
count = get_hit_count()
return ‘Hello World! I have been seen {} times.\n‘.format(count)
This code increments a Redis counter to track page views.
requirements.txt
flask
redis
Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
Our Flask app is defined. Now let‘s Dockerize it.
Create a docker-compose.yml file:
version: ‘3.9‘
services:
web:
build: .
ports:
- ‘5000:5000‘
volumes:
- .:/code
redis:
image: ‘redis:alpine‘
This Compose file defines two services:
web– Builds a container from the Dockerfile to run our Flask app coderedis– Container from official Redis image to store counters
Now build and launch the full app stack:
docker-compose up -d
Visit localhost:5000 to test the app!
Refresh to increment the visits counter stored in Redis. You should see the number go up each time.

When done, stop and clean up containers:
docker-compose down
And that‘s it! With just one command, we configured and launched a multi-container application stack with Docker Compose.
Now let‘s look at more ways to use Compose capabilities for other complex apps.
Sample Project: Running WordPress with Docker Compose
For a more comprehensive example, let‘s walk through using Compose to run WordPress – one of the world‘s most popular CMS platforms with over 455 million websites using it.
WordPress needs both a web server and database. So it‘s a perfect use case for Docker Compose.
Here is the YAML configuration to run WordPress with MySQL in Docker:
version: "3.9"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
This defines two services:
MySQL Database:
- Uses official MySQL 5.7 image
- Sets up credentials and
wordpressdatabase - Stores data to local volume for persistence on restart
WordPress Container:
- Depends on MySQL container
- Uses latest WordPress image
- Passes DB creds as environment variables
- Exposes port 8000 to host
Networking allows linking these containers automatically so WordPress can access the database.
Run the containers:
docker-compose up -d
Compose pulls images, builds containers, exposes ports, injections vars, and handles networking between MySQL and WordPress.
After startup completes, visit localhost:8000 to access and configure WordPress!

Now let‘s examine even more features for customizing applications.
Customizing Services: Networks, Volumes, and Resource Limits
When deploying apps to production, there are additional requirements like:
- Isolating services
- Persisting storage
- Controlling CPU/RAM usage
Docker Compose provides control over all these.
Utilizing Custom Networks
Applications often need segmentation between public-facing and backend services:
We can define custom networks in Compose for this:
networks:
frontend:
backend:
services:
webserver:
networks:
- frontend
- backend
mysql:
networks:
backend
This allows restricting access by only adding containers to certain networks.
Persisting Storage with Volumes
Saving state is crucial for databases and other stateful apps.
We can mount volumes to persist data:
volumes:
db-data: {}
services:
db:
image: postgres
volumes:
- db-data:/var/lib/db
Now Postgres data persists across container restarts.
Controlling Resources with Limits
To prevent resource starvation, enforce memory and CPU limits:
services:
web:
deploy:
resources:
limits:
cpus: ‘0.50‘
memory: 100M
This caps the web service at 50% total CPU and 100 MB RAM preventing runaway usage.
As shown, Compose can handle almost all major deployment and orchestration needs including networking, state, and resource allocation.
This brings major productivity boosts for both development AND operations teams. Next let‘s discuss how to integrate it into CI/CD pipelines.
Best Practices for Using Compose in Development and CI/CD
While Compose simplifies configuring local Docker environments, it also has huge benefits for streamlining CI/CD flows:
Here are my top tips as a DevOps engineer for incorporating Compose as you expand to production.
Benefits of Compose for Automated Testing
Creating an identical testing environment is crucial for valid code verification.
Containerization aligns environments across dev, test, prod by packaging all dependencies.
For automated testing, Docker + Compose:
- Allows reliably spinning up complex test environments on-demand
- Enforces consistency across test runs
- Separates concerns by service for easier debugging
By investing in Compose configs, you prevent environment divergence causing build failures down the line.
Storing Compose Files in Git
To promote visibility and collaboration across teams, add Compose files to source control repositories just like application code.
Benefits:
- Allows developers to spin up apps faster by applying configs you define
- Testers can validate environment parity with production
- Ops gains environment context from code vs tribal knowledge
This brings consistency as applications progress across the pipeline.
Parameterizing Environment Differences
Variations WILL exist across environments:
- Resource limits
- Credential secrets
- Networking restrictions
- Domain names
- Port bindings
Use YAML anchors to parameterize these differences:
x-common-params: &common-params
image: webapp
ports:
- "3000"
environment:
DB_NAME: appdb
dev:
<<: *common-params
environment:
<<: *common-params
DB_NAME: devdb
prod:
<<: *common-params
ports:
- "80:3000"
This technique keeps configs DRY avoiding duplication.
Running Compose in CI
As developers merge changes, CI should build images and run containers so as code progresses, everyone uses latest images.
docker-compose build
docker-compose up -d
This bakes in best practice of rebuilding images on code changes.
Following these design patterns will allow smoothing path from development into production.
Now let‘s wrap up with some closing thoughts and next steps.
Conclusion and Next Steps
In this extensive guide, we covered properly installing Docker Compose on Windows, demonstrated Compose functionality through sample apps, and went through best practices for using Compose both locally and in automated pipelines.
Key takeaways:
- Docker Desktop includes Compose so no manual install needed
- Use Compose for simplifying multi-container apps like LAMP, WordPress etc
- Add Compose files to Git for visibility and collaboration
- For production, look into Docker Swarm or Kubernetes
Docker Compose drives major productivity gains through environment standardization.
Next I recommend assessing if Docker Swarm or full-blown orchestrator like Kubernetes could help as you progress to managing containers at scale in production.
Additionally, check out these resources to further leverage Compose:
- Official Docker Samples – Huge repository of open source Compose files for various apps
- Play with Docker – Interactive Docker learning portal for trying more Compose examples through your browser
- Arun Gupta‘s Docker + Kubernetes Course – Great video series covering Docker through Kubernetes usage including Compose
Have feedback or questions? Feel free to reach out via my website www.fullstackdevops.io about anything Docker or cloud native development!


