Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

A Java CI/CD pipeline becomes much easier to manage when the application, build process, tests, and runtime environment are treated as repeatable assets. Azure DevOps provides the repository, pipeline automation, credentials management, and release workflow needed to move code from commit to deployment with fewer manual steps.

Docker adds consistency by packaging the Java application and its runtime dependencies into a container image that can be built once and deployed across environments. Combined with Azure Pipelines, it allows every change to be compiled, tested, containerized, tagged, and pushed to a registry in a predictable way.

This guide walks through setting up a practical pipeline for a Java application, from preparing the project and Dockerfile to configuring Azure DevOps, running automated checks, publishing images, and deploying the containerized app reliably.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Prerequisites and Project Setup

Before creating the pipeline, prepare the Java application, Azure DevOps project, Docker environment, and container registry access. The setup does not need to be complex, but each part should be in place so the pipeline can compile the app, run tests, build a Docker image, and publish that image without manual steps.

#1 Best Overall
Sale
Redragon Mechanical Gaming Keyboard Wired, 11 Programmable Backlit Modes, Hot-Swappable Red Switch, Anti-Ghosting, Double-Shot PBT Keycaps, Light Up Keyboard for PC Mac
  • Brilliant Color Illumination- With 11 unique backlights, choose the perfect ambiance for any mood. Adjust light speed and brightness among 5 levels for a comfortable environment, day or night. The double injection ABS keycaps ensure clear backlight and precise typing. From late-night tasks to immersive gaming, our mechanical keyboard enhances every experience
  • Support Macro Editing: The K671 Mechanical Gaming Keyboard can be macro editing, you can remap the keys function, set shortcuts, or combine multiple key functions in one key to get more efficient work and gaming. The LED Backlit Effects also can be adjusted by the software(note: the color can not be changed)
  • Hot-swappable Linear Red Switch- Our K671 gaming keyboard features red switch, which requires less force to press down and the keys feel smoother and easier to use. It's best for rpgs and mmo, imo games. You will get 4 spare switches and two red keycaps to exchange the key switch when it does not work.
  • Full keys Anti-ghosting- All keys can work simultaneously, easily complete any combining functions without conflicting keys. 12 multimedia key shortcuts allow you to quickly access to calculator/media/volume control/email
  • Professional After-Sales Service- We provide every Redragon customer with 24-Month Warranty , Please feel free to contact us when you meet any problem. We will spare no effort to provide the best service to every customer

Required tools and accounts

  • Azure DevOps organization and project: Create or use an existing project where the repository and pipeline will live.
  • Java Development Kit: Use a JDK version that matches the application, such as JDK 17 or JDK 21.
  • Maven or Gradle: The examples in this workflow can use either build tool, as long as the project has a repeatable command for packaging and testing.
  • Docker: Install Docker locally so you can validate the image before automating it in Azure Pipelines.
  • Container registry: Use Azure Container Registry, Docker Hub, or another registry that Azure DevOps can authenticate against.
  • Git: The application source should be committed to a Git repository hosted in Azure Repos or connected from GitHub.

For a typical Java web service, the repository should contain the application source, a build descriptor, tests, and eventually a Dockerfile. A Maven-based project will usually include a pom.xml file, while a Gradle-based project will include build.gradle or build.gradle.kts. The pipeline will rely on these files to restore dependencies, run tests, and produce a deployable artifact such as a JAR file.

Recommended repository structure

Path Purpose
src/main/java Application source code.
src/test/java Unit and integration tests that will run during the pipeline.
pom.xml or build.gradle Build configuration, dependencies, plugins, and test commands.
Dockerfile Instructions for packaging the Java application into a container image.
azure-pipelines.yml Pipeline definition for build, test, image creation, and publishing.

If you are starting from an empty project, create a simple Spring Boot, Quarkus, Micronaut, or plain Java service and confirm that it builds locally. For Maven, run mvn clean package. For Gradle, run ./gradlew clean build on Linux or macOS, or gradlew.bat clean build on Windows. The command should complete successfully and produce a JAR file under a directory such as target or build/libs.

Once the project builds locally, commit the initial files to Git and push them to the remote repository. Use a main branch for stable changes and consider creating short-lived feature branches for Dockerfile and pipeline updates. This keeps the pipeline configuration versioned with the application, making it easier to review changes, roll back broken updates, and reproduce builds across environments.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Creating a Dockerfile for the Java Application

A Dockerfile defines how your Java application is packaged into a runnable container image. For an Azure DevOps pipeline, this file should be predictable, repeatable, and safe to run on a clean build agent. Place the Dockerfile at the root of the repository unless your project uses a dedicated deployment folder, and make sure it aligns with the build tool you selected earlier, such as Maven or Gradle.

For a typical Spring Boot or Jakarta EE service that produces a single JAR file, a multi-stage Dockerfile works well. The first stage compiles the application, while the second stage runs only the packaged artifact. This keeps the final image smaller because build tools, dependency caches, and source files are not copied into the runtime layer.

Example Dockerfile for a Maven-based Java app

FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /app

COPY pom.xml .
COPY src ./src

RUN mvn clean package -DskipTests

FROM eclipse-temurin:21-jre
WORKDIR /app

COPY --from=build /app/target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

This Dockerfile uses Eclipse Temurin Java 21 images for both build and runtime stages. The Maven image compiles the application and creates the JAR under the target directory. The runtime image then copies only that JAR into /app and starts it with java -jar. If your application listens on a different port, update EXPOSE 8080 to match the server port configured in your application properties.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Gradle variant

If the project uses Gradle, adjust the build stage to match the Gradle wrapper included in your repository. Using the wrapper helps keep local builds and Azure Pipelines builds on the same Gradle version.

FROM eclipse-temurin:21-jdk AS build
WORKDIR /app

COPY gradlew .
COPY gradle ./gradle
COPY build.gradle settings.gradle ./
COPY src ./src

RUN chmod +x ./gradlew
RUN ./gradlew clean bootJar -x test

Rank #2
Sale
AULA F75 Pro Wireless Mechanical Keyboard,75% Hot Swappable Custom Keyboard with Knob,RGB Backlit,Pre-lubed Reaper Switches,Side Printed PBT Keycaps,2.4GHz/USB-C/BT5.0 Mechanical Gaming Keyboards
  • Tri-mode Connection Keyboard: AULA F75 Pro wireless mechanical keyboards work with Bluetooth 5.0, 2.4GHz wireless and USB wired connection, can connect up to five devices at the same time, and easily switch by shortcut keys or side button. F75 Pro computer keyboard is suitable for PC, laptops, tablets, mobile phones, PS, XBOX etc, to meet all the needs of users. In addition, the rechargeable keyboard is equipped with a 4000mAh large-capacity battery, which has long-lasting battery life
  • Hot-swap Custom Keyboard: This custom mechanical keyboard with hot-swappable base supports 3-pin or 5-pin switches replacement. Even keyboard beginners can easily DIY there own keyboards without soldering issue. F75 Pro gaming keyboards equipped with pre-lubricated stabilizers and LEOBOG reaper switches, bring smooth typing feeling and pleasant creamy mechanical sound, provide fast response for exciting game
  • Advanced Structure and PCB Single Key Slotting: This thocky heavy mechanical keyboard features a advanced structure, extended integrated silicone pad, and PCB single key slotting, better optimizes resilience and stability, making the hand feel softer and more elastic. Five layers of filling silencer fills the gap between the PCB, the positioning plate and the shaft,effectively counteracting the cavity noise sound of the shaft hitting the positioning plate, and providing a solid feel
  • 16.8 Million RGB Backlit: F75 Pro light up led keyboard features 16.8 million RGB lighting color. With 16 pre-set lighting effects to add a great atmosphere to the game. And supports 10 cool music rhythm lighting effects with driver. Lighting brightness and speed can be adjusted by the knob or the FN + key combination. You can select the single color effect as wish. And you can turn off the backlight if you do not need it
  • Professional Gaming Keyboard: No matter the outlook, the construction, or the function, F75 Pro mechanical keyboard is definitely a professional gaming keyboard. This 81-key 75% layout compact keyboard can save more desktop space while retaining the necessary arrow keys for gaming. Additionally, with the multi-function knob, you can easily control the backlight and Media. Keys macro programmable, you can customize the function of single key or key combination function through F75 driver to increase the probability of winning the game and improve the work efficiency. N key rollover, and supports WIN key lock to prevent accidental touches in intense games

FROM eclipse-temurin:21-jre
WORKDIR /app

COPY --from=build /app/build/libs/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

Keep tests out of the image build when tests already run as a separate Azure Pipelines step. This makes failures easier to diagnose: unit tests fail during the test stage, while Docker build failures usually point to packaging, file paths, or image configuration. In the Maven example, -DskipTests skips test execution during packaging; in the Gradle example, -x test does the same.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add a .dockerignore file

A .dockerignore file prevents unnecessary files from being sent to the Docker daemon during image creation. This speeds up builds and avoids accidentally copying local artifacts into the build context.

.git
.azure-pipelines
target
build
.idea
.vscode
*.iml
*.log
.DS_Store

Review the ignore list for your project structure before committing it. Do not exclude files required by the Dockerfile, such as pom.xml, build.gradle, settings.gradle, gradlew, the gradle directory, or src. Once the Dockerfile and .dockerignore are committed, the Azure pipeline can build the image consistently on every push and tag it with a build number, commit SHA, or release version.

Configuring Azure DevOps Repositories and Service Connections

After the Java project and Dockerfile are in place, the next step is to make Azure DevOps the central point for source control and pipeline access. In Azure DevOps, create a project such as java-docker-cicd, then open Repos and initialize a Git repository. If your application already exists locally, add the Azure DevOps remote and push the main branch. Keep the repository layout simple so the pipeline can locate the build file and Dockerfile without custom path handling.

Recommended repository structure

  • src/ contains the Java application source code and tests.
  • pom.xml or build.gradle defines the Maven or Gradle build.
  • Dockerfile sits at the repository root unless you plan to build multiple images.
  • azure-pipelines.yml will define the CI/CD workflow in a later step.
  • .dockerignore excludes build output, local IDE files, and temporary artifacts from the Docker build context.

Use branch policies before connecting automation. For example, protect main by requiring pull requests, at least one reviewer, and a successful pipeline run before merging. This keeps broken builds and unreviewed Dockerfile changes out of the release branch. If your team uses feature branches, a naming pattern such as feature/*, bugfix/*, and release/* makes pipeline triggers easier to manage later.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Service connections allow Azure Pipelines to authenticate with external systems without storing credentials directly in the YAML file. For a Docker-based Java pipeline, the most common connection is to a container registry such as Azure Container Registry, Docker Hub, or another private registry. In Azure DevOps, open Project settings, select Service connections, then create a new connection for your registry type.

Container registry service connection setup

  1. Select Docker Registry or Azure Resource Manager, depending on how your registry is hosted.
  2. Choose Azure Container Registry if the registry is in the same Azure tenant and subscription.
  3. Grant the connection permission to push images to the target registry.
  4. Name the connection clearly, such as acr-java-prod-connection or dockerhub-java-ci.
  5. Enable pipeline access for the repository or approve access during the first pipeline run.

For Azure Container Registry, prefer identity-based access where possible. The service principal or managed identity behind the service connection should have the AcrPush role on the registry. This is enough for building and publishing images, while avoiding broad subscription-level permissions. If deployments will also be handled by Azure Pipelines, create a separate service connection for the runtime target, such as Azure App Service, Azure Kubernetes Service, or a virtual machine environment.

Connection Used for Suggested permission
Container registry Publishing Java application images AcrPush or registry push access
Azure subscription Deploying infrastructure or app services Scoped contributor access to the target resource group
Kubernetes cluster Applying manifests or Helm charts Namespace-level deployment access

Store non-secret configuration, such as image names and Java versions, as pipeline variables. Store passwords, tokens, and client secrets in secret variables or Azure Key Vault, then link them through a variable group. With the repository prepared and service connections scoped, Azure Pipelines can build the Java application, package it into a Docker image, and push it to the registry using repeatable, auditable credentials.

Building the CI Pipeline with Azure Pipelines

With the repository, Dockerfile, and service connections in place, the next step is to define the continuous integration pipeline. In Azure DevOps, this is typically done with an azure-pipelines.yml file committed to the root of your Java project. Keeping the pipeline definition in source control makes build behavior repeatable across branches and allows changes to the application and delivery process to be reviewed together.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A basic CI pipeline for a containerized Java application should check out the code, set up the required JDK, build the application, create a Docker image, and prepare that image for publishing. For a Maven-based application, the pipeline can use the built-in Maven task or a shell script. For Gradle, use the Gradle task or execute the wrapper included in the repository. The wrapper approach is often preferred because it keeps the build version consistent between local development and Azure Pipelines.

Rank #3
Keychron C2 Full Size Wired Mechanical Keyboard, Brown Switch, Retro
  • The Keychron C2 (non-backlight version) is a 104 keys full size wired retro color keycaps mechanical keyboard made for Mac and Windows. Engineered to maximize your productivity with most popular full size layout with number pad.
  • With a layout optimized for Mac, the C2 has all necessary multimedia and function keys (Num Lock works with Windows only), while compatible with Windows, and comes with a dedicated Siri or Cortana key. Extra keycaps for both Mac and Windows operating systems are included.
  • Designed with reliability in mind, the C2 comes with USB Type-C wired connection with a braid cable, which ensures a constant power supply, and best to fit home and light gaming. Inclined bottom frame and 2 level adjustable feet (6˚ & 9˚) makes the C2 more comfortable to type.
  • The pre-installed tactile Keychron switch providing unrivaled tactile responsiveness with up to 50 million keystroke durable lifespan.
  • Outfitted the C2 Non-Backlight version with retro-inspired color scheme looks as good in the office as it does in the game room.

Example pipeline structure

The following structure shows the main stages commonly used for a Java application packaged as a Docker image. Adapt the branch name, registry connection, image name, and build commands to match your project.

trigger:
branches:
include:
- main

pool:
vmImage: 'ubuntu-latest'

variables:
imageName: 'java-api'
dockerfilePath: 'Dockerfile'
tag: '$(Build.BuildId)'

steps:
- checkout: self

- task: JavaToolInstaller@0
inputs:
versionSpec: '17'
jdkArchitectureOption: 'x64'
jdkSourceOption: 'PreInstalled'

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

- script: ./mvnw clean package -DskipTests
displayName: 'Build Java application'

- task: Docker@2
displayName: 'Build Docker image'
inputs:
command: 'build'
Dockerfile: '$(dockerfilePath)'
repository: '$(imageName)'
tags: |
$(tag)

This pipeline starts whenever code is pushed to the main branch. The hosted Ubuntu agent provides Docker support and works well for most Java container builds. The JavaToolInstaller task selects the JDK version expected by the application, while the Maven command compiles and packages the app into a JAR file. If your project uses Gradle, replace that command with ./gradlew clean build -x test or a similar command that matches your build lifecycle.

Useful pipeline refinements

  • Use build variables: Store values such as image names, tags, and Dockerfile paths in variables so the pipeline is easier to update.
  • Tag images consistently: Use $(Build.BuildId), $(Build.SourceBranchName), or a shortened commit SHA to trace an image back to source code.
  • Separate build and publish steps: Build the image first, then push it in a later step after tests and checks pass.
  • Enable pull request validation: Add branch policies so the pipeline runs before changes are merged into protected branches.

At this stage, the pipeline verifies that the Java project can be compiled and packaged into a Docker image on a clean build agent. That alone catches many environment-specific problems, such as missing files, incorrect JDK versions, invalid Dockerfile paths, or build scripts that only work on a developer workstation. The next step is to expand the pipeline with automated tests and quality checks before allowing the image to move toward publishing and deployment.

Running Tests and Quality Checks in the Pipeline

After the pipeline can compile the Java application and build a Docker image, the next step is to make every run prove that the code is safe to package. Tests and quality checks should run before the image is pushed to a registry, so broken code never becomes a deployable artifact. In Azure Pipelines, this usually means adding separate tasks for unit tests, integration tests, code coverage, static analysis, and publishing test results.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a Maven-based project, the test stage can run with the Maven task or a script step. A typical command is mvn clean verify, which compiles the application, runs unit tests, executes integration tests if configured, and validates the build lifecycle. For Gradle, the equivalent is often ./gradlew clean test check. These commands should run before the Docker build step, because the container image should represent code that has already passed validation.

Adding test execution to the pipeline

A simple Maven test step in azure-pipelines.yml can use the built-in Maven task and publish JUnit results automatically. This gives the team a test directly in the Azure DevOps run page, including failed test names, stack traces, and historical pass rates. If your project writes test reports to a custom location, configure the result pattern so Azure Pipelines can collect them.

  • Maven: test reports are commonly written to target/surefire-reports and target/failsafe-reports.
  • Gradle: test reports are commonly written to build/test-results/test.
  • JUnit XML: Azure Pipelines can publish these reports with the PublishTestResults task.
  • Code coverage: JaCoCo reports can be published with the PublishCodeCoverageResults task.

For example, a Maven pipeline can run mvn clean verify, publish JUnit XML files from **/surefire-reports/TEST-*.xml, and then publish JaCoCo coverage from target/site/jacoco/jacoco.xml. If any test fails, the Maven command should return a non-zero exit code and stop the pipeline. This prevents later tasks, such as Docker image creation and registry publishing, from running against an unhealthy commit.

Rank #4
Redragon K521 Upgrade Rainbow LED Gaming Keyboard, 104 Keys Wired Mechanical Feeling Keyboard with Multimedia Keys, One-Touch Backlit, Anti-Ghosting, Compatible with PC, Mac, PS4/5, Xbox
  • 【Dreamy Rainbow Gaming Keyboard】K521 Gaming Keyboard Adopts a Different LED Backlight Design, Upgraded on the Traditional LED Backlight Effect, Making the Light More Penetrating, Giving You a More Dazzling Visual Effect, Making Your Gaming Process More Enjoyable
  • 【One Touch Opens & Visual Feast】The K521 Red Dragon Keyboard has a One-Touch on/off Lighting Button for Added Convenience. It also has a Three-Position Adjustable Breathing Mode and a Four-Position Adjustable Brightness Lighting Mode
  • 【Mechanical Feeling & Fast Tapping】The PC Keyboard Keys are Designed for Mechanical Feeling, Giving You a Better Feel During Use and the Ability to Trigger Keys Quickly, Allowing You to Win All Your Games
  • 【19 Keys Anti-Ghosting Keyboard】Anti-Ghosting Ensures Every Button Can Be Triggered. This Allows You to Trigger Key Combinations In The Game Accurately, And Each Skill Can Be Accurately Released to Increase Your Winning Rate. Redragon K521 Will Be Your Perfect Partner
  • 【12 Multimedia Combination Keys】The K521 Wired Gaming Keyboard is Equipped with 12 Multimedia Keys That Can Greatly Enhance Your Gaming/Office Efficiency and Make It More Convenient to Use

Including static analysis and dependency checks

Quality checks are not limited to automated tests. A practical Java pipeline should also scan for style violations, common bugs, security issues, and vulnerable dependencies. Tools such as Checkstyle, PMD, SpotBugs, and OWASP Dependency-Check can be added to the same validation stage. Configure each tool to run during the Maven or Gradle build, then publish its results after the build completes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Check Common tool Pipeline placement
Unit tests JUnit, Mockito Before Docker build
Coverage JaCoCo After test execution
Static analysis SpotBugs, PMD During verification
Dependency scanning OWASP Dependency-Check, Snyk Before publishing image

Set clear failure rules for these checks. For example, fail the build when unit tests fail, when code coverage drops below the agreed threshold, or when a dependency scan finds a critical vulnerability. These gates keep the Docker registry clean and make each published image more trustworthy. Once this validation stage passes, the pipeline can safely continue to build, tag, and publish the container image.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Publishing Docker Images to a Container Registry

After the pipeline has built the Java application, created the Docker image, and passed the required tests, the next step is to publish that image to a container registry. A registry gives the deployment environment a stable place to pull versioned images from, whether you are deploying to Azure Kubernetes Service, Azure Container Apps, App Service for Containers, or another runtime. In Azure DevOps, the most common target is Azure Container Registry, although the same pattern also works with Docker Hub, GitHub Container Registry, or a private enterprise registry.

Use a consistent image naming strategy so every pipeline run produces an image that can be traced back to the source revision. A typical format combines the registry login server, repository name, and one or more tags. For example, an image might be published as myregistry.azurecr.io/java-orders-api:20240526.3 and also tagged as myregistry.azurecr.io/java-orders-api:latest. The build-specific tag is useful for rollbacks and audits, while latest can be convenient in lower environments where deployments always track the newest successful build.

Adding the Docker push step

If you created a Docker Registry service connection earlier, the pipeline can authenticate to the registry without storing credentials directly in the YAML file. In Azure Pipelines, the Docker@2 task can build and push in a single command, or you can separate those actions into individual build and push steps. Separating them is often cleaner when tests, scans, or other validation steps need to run between image creation and publishing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

- task: Docker@2
displayName: Push Docker image
inputs:
command: push
containerRegistry: 'acr-service-connection'
repository: 'java-orders-api'
tags: |
$(Build.BuildId)
latest

In this example, acr-service-connection refers to the Azure DevOps service connection configured for the container registry. The repository value is the image repository name inside the registry, and the tags list publishes two tags for the same image. If your earlier Docker build step used the same repository and tags, the push task uploads those layers to the registry. Azure Pipelines also handles Docker login and logout through the service connection, reducing the need for manual scripting.

Using safer image tags

For production delivery, avoid relying only on mutable tags such as latest. A better approach is to publish immutable tags based on the Azure DevOps build ID, Git commit SHA, semantic version, or release number. For example, you can tag an image with $(Build.SourceVersion) to connect it directly to a commit, or with $(Build.BuildNumber) if your pipeline uses a controlled versioning format. This makes it much easier to identify what is running in each environment.

  • $(Build.BuildId): simple unique tag generated for each pipeline run.
  • $(Build.SourceBranchName): useful for non-production images from feature or release branches.
  • $(Build.SourceVersion): maps the image to an exact Git commit.
  • v1.4.2: works well when releases follow semantic versioning.

You can confirm the image was published by opening the container registry in the Azure portal and checking the repository tags, or by running a Docker pull from a machine with access to the registry. At this point, the pipeline has produced a deployable artifact that is independent of the build agent. The next deployment stage only needs the registry name, image repository, and selected tag to run the same Java application consistently across environments.

Deploying the Containerized Java Application

After the pipeline builds, tests, and publishes the Docker image, the next step is to deploy that image to a runtime environment. In Azure DevOps, this is usually handled with a release stage or a deployment job in the same YAML pipeline. The deployment target can be Azure App Service for Containers, Azure Container Apps, Azure Kubernetes Service, or a virtual machine running Docker. For many Java web applications, Azure App Service for Containers is a practical starting point because it can pull directly from Azure Container Registry and manage hosting, scaling, HTTPS, and restarts with minimal infrastructure setup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A deployment stage should reference the same image tag produced during the build stage, rather than using a floating tag such as latest. For example, if the build pushed myapp:$(Build.BuildId), the deployment stage should use that exact tag. This creates traceability between the source commit, pipeline run, Docker image, and deployed application. If an issue is found after release, you can identify the image that was deployed and roll back to a previous known-good tag.

Best Value
Logitech MX Mechanical Wireless Illuminated Keyboard Tactile - Graphite
  • Tactile Quiet mechanical key switches with a satisfying tactile bump you feel - for precise feedback, reactive key reset, and less noise so your typing doesn't disturb those around you
  • Low-profile keys, more comfort: A keyboard layout designed for effortless precision, with a full-size form factor and low-profile mechanical switches for better ergonomics
  • Smart illumination: Backlit keys light up the moment your hands approach the cordless keyboard and automatically adjust to suit changing lighting conditions
  • Faster workflow, more customization: Customize Fn keys, assign backlighting effects, enable Flow cross-computer, multi-device control, and more in the improved Logi Options+ (1)
  • Multi-device, multi-OS: Pair MX Mechanical Bluetooth wireless keyboard with up to 3 devices on nearly any operating system via Bluetooth Low Energy or included Logi Bolt receiver(2)

Example deployment stage for Azure App Service

The following YAML pattern deploys a published Java container image to an Azure Web App for Containers. It assumes that the image has already been pushed to Azure Container Registry and that the pipeline has access through an Azure Resource Manager service connection.

stages:
- stage: Deploy
displayName: Deploy container
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeployWebApp
displayName: Deploy to Azure App Service
environment: production
strategy:
runOnce:
deploy:
steps:
- task: AzureWebAppContainer@1
displayName: Deploy Docker image
inputs:
azureSubscription: 'azure-service-connection'
appName: 'java-container-webapp'
containers: 'myregistry.azurecr.io/java-api:$(Build.BuildId)'

The environment value in the deployment job is useful because Azure DevOps can track deployments per environment and support approvals before production releases. For example, you can configure the production environment to require manual approval from a release owner, while allowing automatic deployment to dev or test. This gives the pipeline a controlled promotion flow without changing the Docker image between environments.

Deployment configuration to verify

  • Registry access: confirm that the Azure service or cluster can pull from the container registry. With Azure Container Registry, this can be done through managed identity, admin credentials, or Kubernetes image pull secrets.
  • Application port: match the container port exposed by the Java application. If the Spring Boot app listens on port 8080, configure the hosting platform to route traffic to port 8080.
  • Environment variables: move runtime settings such as database URLs, active Spring profiles, feature flags, and API endpoints into platform configuration instead of baking them into the image.
  • Secrets: store passwords, tokens, and certificates in Azure Key Vault or the target platform’s secret store, then inject them at runtime.
  • Health checks: configure readiness or health endpoints such as /actuator/health so the platform can detect failed starts and unhealthy containers.

For Kubernetes-based deployments, the pipeline typically updates a Kubernetes manifest or Helm release with the new image tag. The deployment stage can use KubernetesManifest@1 or a Helm task to apply the change to AKS. A basic flow is to create or update the image pull secret, apply the deployment and service manifests, and wait for rollout completion. This approach is better suited for applications that need advanced scaling, service discovery, ingress routing, or mulle replicas across nodes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Once deployment completes, add a lightweight validation step. This can be a script that calls the application’s health endpoint and fails the pipeline if the service does not respond successfully. For production, consider using deployment slots, blue-green deployment, or canary release patterns so that a new Java container can be tested with limited traffic before replacing the current version. Combined with immutable image tags and environment-specific configuration, this gives you a repeatable deployment process that is easy to audit and safer to roll back.

Frequently Asked Questions

Do I need a Microsoft-hosted agent or a self-hosted agent for building Docker images?

Microsoft-hosted Ubuntu agents are usually enough for standard Java and Docker builds because they include Docker and common build tools. Use a self-hosted agent if your build needs private network access, custom security tooling, large dependency caches, or more control over Docker daemon settings.

Where should I store Docker registry credentials in Azure DevOps?

Store registry access through an Azure DevOps service connection rather than hardcoding usernames, passwords, or tokens in YAML. For Azure Container Registry, create an Azure Resource Manager or Docker Registry service connection and reference it from the pipeline task that builds and pushes the image.

Should the pipeline build the Java JAR first or build everything inside the Dockerfile?

Both approaches work, but many teams run Maven or Gradle tests in the pipeline first, then pass the built artifact into the Docker image. A multi-stage Dockerfile is also a strong option because it keeps the final image smaller while making the container build repeatable across local and CI environments.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How should I tag Docker images from an Azure Pipeline?

Use a unique tag for every build, such as the Azure DevOps build ID, Git commit SHA, or semantic version from your release process. Many teams also push a branch-specific tag for convenience, but avoid relying only on latest because it makes rollbacks and audits harder.

How do I deploy the Java container after Azure DevOps pushes it to the registry?

After the image is published, add a deployment stage that updates your target platform, such as Azure App Service for Containers, Azure Kubernetes Service, or a Docker host. The deployment step should reference the exact image tag produced by the build stage so the same tested image is promoted consistently.

Bottom Line

With Azure DevOps and Docker working together, your Java pipeline can move from source code to tested, versioned, deployable container image with far less manual effort. A well-structured repository, clear Dockerfile, automated test stage, and secure registry publishing step give your team a repeatable path to reliable releases.

Your next step is to adapt the pipeline YAML to your application’s build tool, registry, and target environment, then run it on every pull request and merge. From there, refine it with quality gates, environment approvals, and deployment automation as your delivery process matures.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.