🦆 Prerequisites: Get Your Ducks in a Row
Before we dive in:
Requirement | Why You Need It |
---|---|
✅ Azure subscription | Need Credits |
✅ Docker basics | Containerization knowledge |
✅ Git workflows | Version control fundamentals |
✅ GitHub repo | Fork this repo |
☕ Coffee | Optional but highly recommended |
Microservices Architecture:
🏗️ Step 1: Azure DevOps Foundation
Why Azure DevOps?
- 🔥 Industry standard for enterprise CI/CD
- 💎 Free private repos (up to 5 users)
- 🚀 Seamless Azure integration
Quick Setup:
- 🌐 Head to Azure DevOps
- 🆕 Create new project
- 🔗 Link your forked
example-voting-app
repo
🏪 Step 2: Container Registry - Your Image Vault
The Solution: Azure Container Registry (ACR)
- 🔒 Private & secure
- ⚡ Geo-replication
- 🔗 Native Azure integration
Think of ACR as: Your private, VIP parking garage for containers!
Quick Create:
Navigate to Container Registry → Create
Oops! 🤦♂️ Need a Resource Group first. Let's fix that...
📁 Step 3: Resource Group - Organization Master
What it is: Think digital folder that keeps all your Azure resources organized.
Why it matters:
- 💰 Cost tracking per project
- 🗂️ Easy cleanup (delete group = delete everything)
- 🎯 Access management in one place
Naming convention: rg-voting-app-prod
(descriptive + environment)
🤖 Step 4: Self-Hosted Agent - Your Build Butler
Hosted vs Self-Hosted: The Truth
Hosted Agents | Self-Hosted Agents |
---|---|
💸 Pay per minute | 💰 Free after VM cost |
🐌 Queue times | ⚡ Instant builds |
🔒 Limited customization | 🔧 Full control |
Setup Process:
- 🖥️ Create Ubuntu VM in Azure
- ⚙️ Azure DevOps → Project Settings → Agent Pools → Add pool
- 📋 Follow installation steps
🔐 Security: Personal Access Token (PAT)
Why PAT? Secure communication between agent and Azure DevOps.
Steps:
- Profile picture → Personal Access Tokens
- Create token with required scopes
Security Note: Full access scope = demo only. Production = minimal required permissions! ⚠️
💍 Step 5: Crafting My Preciouuuuss Pipeline
"One pipeline to build them all, one pipeline to find them, one pipeline to bring them all, and in the registry bind them." – DevOps Gandalf
Pipeline Creation Magic ✨
Azure DevOps makes this stupid easy:
- Pipelines → New Pipeline
- Azure Repos Git
- Select repository
- Docker - build and push to ACR
Look at all the infinity of tasks available! Probably all frequently used tasks are already developed here. But you know, if something's missing, you can always create it yourself!
Dockerize and Push Our Vote Microservice
🐳 Creating the Vote Pipeline
Now let's create a dedicated pipeline for our vote microservice. This pipeline will:
- ✅ Trigger only on vote/ changes (efficient builds)
- ✅ Build the Python Flask app using Docker
- ✅ Push to Azure Container Registry securely
- ✅ Tag with build number for version tracking
Pipeline Configuration:
trigger:
paths:
include:
- vote/* # Only triggers when vote microservice changes
resources:
- repo: self
variables:
dockerRegistryServiceConnection: '2833cab0-ae52-474d-97fd-43a2db870ebe'
imageRepository: 'vote' # For each service one repository (worker, result)
containerRegistry: 'sharker3312.azurecr.io'
dockerfilePath: '$(Build.SourcesDirectory)/vote/Dockerfile' # Dockerfile PATH
tag: '$(Build.BuildId)'
pool:
name: 'self-host' # Using our self-hosted agent
stages:
- stage: Build
displayName: Build and push stage
jobs:
- job: Build
displayName: Build
steps:
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
latest
🚨 REALITY CHECK: When Things Go BOOM! 💥
Because let's be honest - your first pipeline run is going to fail spectacularly, and that's perfectly normal! 😅
🔥 THE MOMENT OF TRUTH 🔥
You hit that "Run Pipeline" button with all the confidence in the world, and then...
Problem Solved: Our agent needs Docker to build those containers! Let's fix that:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# Add agent user to docker group (no sudo needed for docker)
sudo usermod -aG docker $USER
Don't worry about errors - they're just DevOps giving you a chance to learn something new! 🧠
🏷️ Tagging Strategy Explained:
Tag | Example | Purpose |
---|---|---|
Build ID | vote:12345 |
Specific version tracking |
Latest | vote:latest |
Always points to newest build |
🔄 Step 7: Worker & Result Microservices
👷♂️ The Worker Pipeline
imageRepository: 'worker' # Changed from 'vote'
dockerfilePath: '$(Build.SourcesDirectory)/worker/Dockerfile' # Changed path
Also update your trigger path:
trigger:
paths:
include:
- worker/* # Only triggers when worker microservice changes
📊 The Result Pipeline
Same story, different microservice! For the Result app, just modify:
imageRepository: 'result' # Changed from 'vote'
dockerfilePath: '$(Build.SourcesDirectory)/result/Dockerfile' # Changed path
And update your trigger:
trigger:
paths:
include:
- result/* # Only triggers when result microservice changes
Pro tip: 🧙♂️ With this approach, each microservice has its own dedicated pipeline that only triggers when that specific service changes! Talk about efficiency!
At this moment we've got all our pipelines functioning beautifully:
🔄 Step 8: Redis & PostgreSQL - The Missing Pieces
🤔 What about Redis and PostgreSQL?
No need to reinvent the wheel! For these components:
- 🐘 PostgreSQL - Using official public image from Docker Hub
- 🔄 Redis - Using official public image from Docker Hub
Why use public images?
- 🏆 Production-ready containers maintained by experts
- 🛡️ Security updates automatically rolled out
- 💰 Cost-efficient - no need to maintain our own images
🚢 What's Next?
But the real question is: What do we do with these container images once they're in our registry?
Well, this is just the beginning of our DevOps journey! Now we need a way to manage these containers through a single orchestration service.
Maybe Kubernetes - the container orchestration superhero! 🦸♂️
Top comments (0)