Lab 1: Create Dockerfile for Java App 📝
Objective: Create Dockerfile and build container image
Time: 30 minutes
Exercise 1.1: Create Dockerfile
1
Navigate to Calculator Project
cd $env:USERPROFILE\Desktop\testing-demo\calculator
2
Create Dockerfile
notepad Dockerfile
Add Dockerfile content:
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/calculator-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Save and close
3
Build JAR File First
mvn clean package -DskipTests
[INFO] BUILD SUCCESS
[INFO] Total time: 15.234 s
dir target\*.jar
calculator-1.0-SNAPSHOT.jar
4
Build Docker Image
docker build -t calculator:1.0 .
Sending build context to Docker daemon 15.87MB
Step 1/5 : FROM openjdk:11-jre-slim
Step 2/5 : WORKDIR /app
Step 3/5 : COPY target/calculator-*.jar app.jar
Step 4/5 : EXPOSE 8080
Step 5/5 : ENTRYPOINT ["java", "-jar", "app.jar"]
Successfully built abc123def456
Successfully tagged calculator:1.0
5
Verify Image Created
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
calculator 1.0 abc123def456 30 seconds ago 220MB
openjdk 11-jre xyz789abc123 2 weeks ago 200MB
6
Run Container Locally
docker run -d -p 8080:8080 --name calculator-app calculator:1.0
a1b2c3d4e5f6...
docker ps
CONTAINER ID IMAGE STATUS PORTS
a1b2c3d4e5f6 calculator:1.0 Up 5 seconds 0.0.0.0:8080->8080/tcp
curl http://localhost:8080
docker logs calculator-app
docker stop calculator-app
docker rm calculator-app
✅ Checkpoint: Docker image built and tested locally
Lab 2: Multi-Stage Dockerfile 🏗️
Objective: Create optimized Dockerfile that builds AND runs app
Time: 25 minutes
Exercise 2.1: Create Multi-Stage Dockerfile
1
Create Multi-Stage Dockerfile
notepad Dockerfile.multistage
FROM maven:3.8-openjdk-11 AS build
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /build/target/*.jar app.jar
RUN useradd -m appuser
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
Save and close
2
Build Multi-Stage Image
docker build -f Dockerfile.multistage -t calculator:1.0-optimized .
Step 1/12 : FROM maven:3.8-openjdk-11 AS build
Step 2/12 : WORKDIR /build
...
Step 12/12 : ENTRYPOINT ["java", "-jar", "app.jar"]
Successfully built xyz123abc456
Successfully tagged calculator:1.0-optimized
3
Compare Image Sizes
docker images calculator
REPOSITORY TAG SIZE
calculator 1.0 220MB (basic)
calculator 1.0-optimized 185MB (multi-stage) ✅
Multi-stage is smaller! Build tools not included in final image
✅ Checkpoint: Optimized multi-stage Docker image created
Lab 3: Push Image to Azure Container Registry 🏪
Objective: Store container image in Azure Container Registry
Time: 35 minutes
Exercise 3.1: Create Azure Container Registry
1
Create ACR (Azure Portal or CLI)
az login
az group create --name myResourceGroup --location eastus
az acr create `
--resource-group myResourceGroup `
--name myCalculatorACR `
--sku Basic
{
"loginServer": "mycalculatoracr.azurecr.io",
"name": "myCalculatorACR",
"provisioningState": "Succeeded"
}
💡 ACR Name Rules:
- 5-50 characters
- Alphanumeric only (no hyphens)
- Globally unique
2
Login to ACR
az acr login --name myCalculatorACR
Login Succeeded
3
Tag Image for ACR
docker tag calculator:1.0 mycalculatoracr.azurecr.io/calculator:1.0
docker images mycalculatoracr.azurecr.io/calculator
REPOSITORY TAG IMAGE ID
mycalculatoracr.azurecr.io/calculator 1.0 abc123def456
4
Push Image to ACR
docker push mycalculatoracr.azurecr.io/calculator:1.0
The push refers to repository [mycalculatoracr.azurecr.io/calculator]
5f70bf18a086: Pushed
1.0: digest: sha256:abc123... size: 1234
5
Verify in ACR
az acr repository list --name myCalculatorACR
[
"calculator"
]
az acr repository show-tags --name myCalculatorACR --repository calculator
[
"1.0"
]
✅ Checkpoint: Container image stored in Azure Container Registry
Lab 4: Build Docker Image in Azure Pipeline 🔧
Objective: Automate Docker build and push in CI/CD pipeline
Time: 40 minutes
Exercise 4.1: Create Service Connection to ACR
1
Create Service Connection
- Azure DevOps → Project Settings → Service connections
- Click "+ New service connection"
- Select "Docker Registry"
- Choose "Azure Container Registry"
- Select your subscription
- Select your ACR:
myCalculatorACR
- Name:
ACR-Connection
- Click "Save"
Exercise 4.2: Create Docker Build Pipeline
1
Create Pipeline YAML
notepad azure-pipelines-docker.yml
Complete Docker pipeline:
trigger:
- main
variables:
dockerRegistryServiceConnection: 'ACR-Connection'
imageRepository: 'calculator'
containerRegistry: 'mycalculatoracr.azurecr.io'
dockerfilePath: 'Dockerfile'
tag: '$(Build.BuildId)'
stages:
- stage: Build
displayName: 'Build and Push Docker Image'
jobs:
- job: BuildJob
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Maven@3
displayName: 'Build JAR'
inputs:
mavenPomFile: 'pom.xml'
goals: 'clean package -DskipTests'
- task: Docker@2
displayName: 'Build and Push Image'
inputs:
command: 'buildAndPush'
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
latest
Save and close
2
Commit and Run Pipeline
git add Dockerfile azure-pipelines-docker.yml
git commit -m "Add Docker build pipeline"
git push
3
Monitor Pipeline
- Create pipeline in Azure DevOps
- Watch execution:
- ✅ Build JAR with Maven
- ✅ Build Docker image
- ✅ Push to ACR
- ✅ Tag as "latest" and with build ID
4
Verify in ACR
az acr repository show-tags --name myCalculatorACR --repository calculator
[
"1234",
"latest"
]
✅ Checkpoint: Docker build automated in pipeline, image in ACR
Lab 5: Deploy Container to Azure 🚀
Objective: Deploy container to Azure Container Instances
Time: 30 minutes
Exercise 5.1: Deploy to ACI
1
Add Deployment Stage
notepad azure-pipelines-docker.yml
Add deployment stage after build:
- stage: Deploy
displayName: 'Deploy to ACI'
dependsOn: Build
jobs:
- deployment: DeployACI
environment: 'Production'
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- task: AzureCLI@2
displayName: 'Deploy Container'
inputs:
azureSubscription: 'Azure-Subscription'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Delete old container if exists
az container delete \
--resource-group myResourceGroup \
--name calculator-app \
--yes || true
# Create new container
az container create \
--resource-group myResourceGroup \
--name calculator-app \
--image $(containerRegistry)/$(imageRepository):$(Build.BuildId) \
--cpu 1 \
--memory 1 \
--registry-login-server $(containerRegistry) \
--registry-username $(acrUsername) \
--registry-password $(acrPassword) \
--dns-name-label calculator-app-demo \
--ports 8080
# Show container info
az container show \
--resource-group myResourceGroup \
--name calculator-app \
--query "{FQDN:ipAddress.fqdn,State:instanceView.state}" \
--output table
2
Add ACR Credentials as Variables
- Go to Pipelines → Library
- Create variable group:
acr-credentials
- Add variables:
acrUsername - Your ACR username
acrPassword - Your ACR password (mark as secret 🔒)
Get ACR credentials:
az acr credential show --name myCalculatorACR
{
"passwords": [
{
"name": "password",
"value": "xxxxxxxxxxxxx"
}
],
"username": "myCalculatorACR"
}
3
Reference Variable Group
Add to Deploy stage in YAML:
- stage: Deploy
variables:
- group: acr-credentials
jobs:
- deployment: DeployACI
4
Run Complete Pipeline
git add .
git commit -m "Add ACI deployment"
git push
Pipeline will:
- Build JAR with Maven
- Build Docker image
- Push to ACR
- Deploy to ACI
- Container running in Azure! 🎉
5
Access Deployed Container
az container show `
--resource-group myResourceGroup `
--name calculator-app `
--query "ipAddress.fqdn" `
--output tsv
calculator-app-demo.eastus.azurecontainer.io
start http://calculator-app-demo.eastus.azurecontainer.io:8080
✅ Checkpoint: Container deployed and running in Azure!
🎯 Lab Summary
What You've Accomplished:
- ✅ Created Dockerfile for Java application
- ✅ Built Docker images locally
- ✅ Created multi-stage Dockerfile (optimized)
- ✅ Created Azure Container Registry
- ✅ Pushed images to ACR
- ✅ Automated Docker build in pipeline
- ✅ Deployed container to Azure Container Instances
Container Workflow Mastered:
- Develop: Write code locally
- Dockerize: Create Dockerfile
- Build: Create container image
- Push: Store in ACR
- Deploy: Run in ACI/AKS
🎉 Day 18 Complete!
You've mastered Docker container deployments!
Ready for Day 19: Kubernetes & AKS Deployments