Azure  

Hosting Persistent DevOps Tools on an Azure Windows VM using Docker

Exposing standard development tools like Jenkins, RabbitMQ, and Redis to the public cloud can be challenging. Developers often lose data when containers restart or find themselves blocked by layers of cloud and OS-level network security.

This comprehensive guide details how to provision a production-ready, persistent workspace on an Azure Windows Virtual Machine using Docker. You will learn how to configure isolated, stateful containers, bypass both Windows Server and Azure firewalls, and securely connect to your utilities from anywhere in the world.

Architecture Overview

To achieve an isolated development workflow, the environment uses a layered access topology:

[ Local Browser ] 
       │ (Public Traffic via Port 8085, 15672, 5540)
       ▼
┌────────────────────────────────────────────────────────┐
│ Azure Cloud Infrastructure                            │
│  └─ Network Security Group (NSG) Inbound Rules         │
│         │                                              │
│         ▼                                              │
│   ┌────────────────────────────────────────────────┐   │
│   │ Azure Windows Virtual Machine                 │   │
│   │  └─ Windows Advanced Guest Firewall Rules      │   │
│   │         │                                      │   │
│   │         ▼                                      │   │
│   │   ┌────────────────────────────────────────┐   │   │
│   │   │ Docker Engine Desktop Daemon           │   │   │
│   │   │  ├─ Jenkins Container     (:8085)      │   │   │
│   │   │  ├─ RabbitMQ Container    (:15672)     │   │   │
│   │   │  └─ Redis Insight Container (:5540)     │   │   │
│   │   │         │                              │   │   │
│   │   │         ▼                              │   │   │
│   │   │   [ Persistent Named Volumes ]         │   │   │
│   │   └────────────────────────────────────────┘   │   │
│   └────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────┘

Phase 1: Establish Remote Connection & Prepare Host Runtime

  1. Launch your local Remote Desktop Connection (RDP) client.

  2. Input the target Azure public IP address and connect using your provisioned administrative credentials.

  3. Once the desktop session initializes, navigate to the official Docker portal to download the Docker Desktop for Windows executable installer.

  4. Run the installer. Ensure that the WSL 2 Configuration or the underlying Hyper-V Windows Feature engine checkbox is ticked depending on your Windows Server kernel capabilities.

  5. Complete installation and execute a system restart if prompted by the installer. Following initialization, launch Docker Desktop and confirm the engine state reads Running in the application tray interface.

Phase 2: Deploying the Stateful Docker Core Service Mesh

By default, standard containerized file systems are ephemeral; destroying a container drops its internal state. To retain pipelines, user groups, and messages across lifecycle failures, we declare managed state volumes (-v) directly bound to the guest host application space.

Open Windows PowerShell inside your RDP window with elevated Run as Administrator permissions, and run the following deployment script block:

PowerShell

# Deploy Persistent Jenkins LTS Engine
docker run -d `
  --name jenkins-lts `
  -p 8085:8080 `
  -p 50000:50000 `
  -v jenkins_home_data:/var/jenkins_home `
  jenkins/jenkins:lts-jdk21

# Deploy Persistent RabbitMQ with Management Dashboard Plugin
docker run -d `
  --name rabbitmq-dashboard `
  -p 5672:5672 `
  -p 15672:15672 `
  -v rabbitmq_data:/var/lib/rabbitmq `
  rabbitmq:4-management

# Deploy Persistent Redis Insight Unified Web Dashboard UI
docker run -d `
  --name redis-insight `
  -p 5540:8001 `
  -v redis_insight_data:/db `
  redis/redisinsight:latest

Parameter Breakdown

  • -d: Runs the running instance detached in background mode.

  • -p [HostPort]:[ContainerPort]: Binds the container runtime application interfaces safely to target Windows network sockets. Note that Jenkins maps to an external port 8085 to sidestep native corporate 8080 port collisions, and Redis Insight routes host 5540 directly to internal upstream web entrypoint 8001.

  • -v [VolumeName]:[InternalPath]: Creates a physical abstraction layer on the Windows storage subsystem to preserve container configurations permanently.

Phase 3: Modifying the Guest OS Windows Firewall Topology

Windows Server blocks arbitrary ingress endpoints by default. Run the following command set in your administrative PowerShell window to clear incoming traffic lanes for your newly exposed Docker network endpoints:

PowerShell

# Create Inbound Exception Rules for Docker InfrastructureNew-NetFirewallRule -DisplayName "Docker-Jenkins Inbound" -Direction Inbound -LocalPort 8085 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "Docker-RabbitMQ Inbound" -Direction Inbound -LocalPort 15672 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "Docker-RedisInsight Inbound" -Direction Inbound -LocalPort 5540 -Protocol TCP -Action Allow

Confirm activation by running Get-NetFirewallRule -DisplayName "Docker-*" | Select-Object DisplayName, Enabled, Action.

Phase 4: Configure Cloud Security Architecture in the Azure portal

With host permissions established, you must update Azure’s edge hardware protection policies via the Network Security Group (NSG).

  1. Open your browser on your local workstation and navigate to the Azure Portal.

  2. Locate and open the Virtual Machine blade running your host instance.

  3. Under the left-hand navigation pane, select Settings $\rightarrow$ Networking (or Network Settings).

  4. Select the Add inbound port rule component button to access the security policy dialog panel.

  5. Apply the following settings to build a unified perimeter ruleset:

Config PropertyOperational ValueStructural Impact
SourceAny (or IP Addresses)Controls source origin traffic limits. Using your specific local Public IP here maximizes workspace security.
Source Port Ranges*Permits all source client ports.
Destination Port Ranges8085,15672,5540Opens target container web entrypoints.
ProtocolTCPAligns network delivery with standard HTTP layers.
ActionAllowAuthorizes traffic across edge firewalls.
Priority310Places rule execution early in processing order.
NameAllow_DevOps_Suite_InboundSets standard resource naming identifier.
  1. Click Add and monitor notification center until confirmation reports rule deployment across Azure edge clusters.

Phase 5: Live Verification and Lifecycle Management

You can now connect to your remote DevOps infrastructure from your local machine's web browser.

First-Time Initialization Steps

1. Jenkins Continuous Integration Engine

Navigate to http://<YOUR_AZURE_PUBLIC_IP>:8085. The system will present the Unlock Jenkins interface. To recover your secret setup token, execute this specialized query inside your Azure VM PowerShell terminal:

PowerShell

docker exec jenkins-lts cat /var/jenkins_home/secrets/initialAdminPassword

Copy the long alphanumeric string output from the terminal screen, drop it into the web field entry box, and continue setup to deploy standard plugins.

2. RabbitMQ Message Broker Control Center

Navigate to http://<YOUR_AZURE_PUBLIC_IP>:15672. Access the management shell by supplying the baseline standard authentication credentials:

  • Username: guest

  • Password: guest

3. Redis Insight GUI Console

Navigate to http://<YOUR_AZURE_PUBLIC_IP>:5540. Accept the global end-user licensing agreement agreements to immediately interact with database memory stores via an intuitive web dashboard interface.

Long-Term Maintenance and Lifecycle Operations

Because we linked persistent storage paths through volume mounting arrays during initialization, running updates, routine system maintenance, and cleaning local disk layers is safe and predictable.

Pausing Operations

When suspending development pipelines over long periods to minimize compute impacts or prevent malicious access scans, stop the running instances via:

PowerShell

docker stop jenkins-lts rabbitmq-dashboard redis-insight

The application endpoints will safely go offline, keeping your target app state perfectly suspended within data-safe silos.

Resuming Infrastructure Execution

To spin your services back online without dealing with initial passwords or configuration setups again, run:

PowerShell

docker start jenkins-lts rabbitmq-dashboard redis-insight