Cloud Native 10 min read

Deploy Apollo Config Center with Docker Compose and Kubernetes: A Step‑by‑Step Guide

This article walks through installing Ctrip's open‑source Apollo configuration center using Docker‑Compose, explains its key features, shows how to deploy it on Kubernetes with Helm, and provides .NET SDK integration examples and practical tips.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Deploy Apollo Config Center with Docker Compose and Kubernetes: A Step‑by‑Step Guide

Preface

Apollo is Ctrip's open‑source distributed configuration management center. This article introduces its Docker‑Compose deployment, installation experience, and usage tips.

Features

Mature and stable

Supports multi‑environment, multi‑cluster, multi‑namespace configuration management

Real‑time (1 s) configuration change notifications

Permission control, inheritance, versioning, gray release, monitoring, etc.

Provides .NET/Java/Go SDKs and HTTP API

Chinese documentation, backed by large enterprises

Simple to use; supports Docker, K8s; official high‑availability solutions available

Usage Situation

Used as a configuration center in microservice projects with stable performance

Memory footprint: ~100 MB fresh install; ~1.5 GB with 20 projects and 80 clients

Separate test and production environments for safety

Chosen for stability and simplicity despite lacking Nacos performance and service discovery

Practice

Preparation

Current version: v2.1

apollo-db: MySQL 5.6.6+ (default port 3306, databases ApolloPortalDB and ApolloConfigDB, default user/password apollo/admin)

apollo-configservice: provides configuration read/push (default port 8080)

apollo-adminservice: provides configuration modify/publish (default port 8090)

apollo-portal: web UI for configuration management (default port 8070, default user/password apollo/admin)

Deureka: service registry (requires eureka.service.url configuration)

Configuration priority: system parameters > environment variables > external files

Install with Docker Compose

This article assumes Docker V24 and Docker‑Compose V2.

Configuration Highlights

Mount logs to ./logs

Fixed image versions: MySQL 5.7, Apollo 2.1.0

MySQL root password: devops666, port mapping 13306:3306

Mount ./initsql for initialization scripts

Apollo services connect to MySQL via service name apollo-db Set service dependencies with depends_on Register services to Deureka with proper URLs

Create Docker network devopsnetwork Web UI default credentials: apollo/admin (change after login)

compose.yml

version: '3.1'
services:
  # Apollo database
  apollo-db:
    image: mysql:5.7
    container_name: apollo_db_5_7
    restart: always
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 'devops666'
    ports:
      - "13306:3306"
    volumes:
      - ./initsql:/docker-entrypoint-initdb.d
      - ./data:/var/lib/mysql
    networks:
      - devopsnetwork

  # Apollo config service
  apollo-configservice:
    container_name: apollo_configservice_2_1
    image: apolloconfig/apollo-configservice:2.1.0
    restart: always
    depends_on:
      - apollo-db
    environment:
      SPRING_DATASOURCE_URL: 'jdbc:mysql://apollo-db:3306/ApolloConfigDB?characterEncoding=utf8'
      SPRING_DATASOURCE_USERNAME: 'root'
      SPRING_DATASOURCE_PASSWORD: 'devops666'
      JAVA_OPTS: "-Deureka.instance.homePageUrl=http://192.168.123.214:8080"
    volumes:
      - ./logs:/opt/logs
    ports:
      - "8080:8080"
    networks:
      - devopsnetwork

  # Apollo admin service
  apollo-adminservice:
    container_name: apollo_adminservice_2_1
    image: apolloconfig/apollo-adminservice:2.1.0
    restart: always
    environment:
      SPRING_DATASOURCE_URL: 'jdbc:mysql://apollo-db:3306/ApolloConfigDB?characterEncoding=utf8'
      SPRING_DATASOURCE_USERNAME: 'root'
      SPRING_DATASOURCE_PASSWORD: 'devops666'
      JAVA_OPTS: "-Deureka.instance.homePageUrl=http://192.168.123.214:8090 -Deureka.service.url=http://192.168.123.214:8080/eureka/"
    depends_on:
      - apollo-db
    ports:
      - "8090:8090"
    volumes:
      - ./logs/:/opt/logs
    networks:
      - devopsnetwork

  # Apollo portal
  apollo-portal:
    image: apolloconfig/apollo-portal:2.1.0
    container_name: apollo_portal_2_1
    restart: always
    environment:
      SPRING_DATASOURCE_URL: 'jdbc:mysql://apollo-db:3306/ApolloPortalDB?characterEncoding=utf8'
      SPRING_DATASOURCE_USERNAME: 'root'
      SPRING_DATASOURCE_PASSWORD: 'devops666'
      APOLLO_PORTAL_ENVS: 'dev'
      DEV_META: 'http://192.168.123.214:8080'
    depends_on:
      - apollo-db
    ports:
      - "8070:8070"
    volumes:
      - ./logs/:/opt/logs
    networks:
      - devopsnetwork

networks:
  devopsnetwork:
    external: true

Deployment Success

Deployed machine IP: 192.168.123.214

Install with Kubernetes

Follow the official documentation; Helm charts are available at apolloconfig/apollo-helm-chart. Key steps:

Initialize the database (create ApolloConfigDB and ApolloPortalDB, set environment and organization in ServerConfig).

Add Apollo repo with Helm.

Install apollo-service and apollo-portal.

Optionally store Apollo configs in a Kubernetes ConfigMap for easy access.

Usage – .NET SDK

.NET SDK

Official package: Com.Ctrip.Framework.Apollo.Configuration Add the package.

Configure Apollo in appsettings.json with MetaServer, AppId, and Namespaces.

Register configuration source:

builder.Configuration.AddApollo(builder.Configuration.GetSection("apollo"));

Inject IConfiguration where needed.

Connection Settings

{
  "apollo": {
    "MetaServer": "http://192.168.123.214:8080",
    "AppId": "devops.test",
    "Namespaces": [ "application" ]
  }
}

Demo Example (dotnet 7.0)

var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddApollo(builder.Configuration.GetSection("apollo"));
app.MapGet("/config", context =>
{
    context.Response.Headers["Content-Type"] = "text/html";
    var configService = context.RequestServices.GetRequiredService<IConfiguration>();
    string? key = context.Request.Query["key"];
    if (string.IsNullOrWhiteSpace(key))
        return context.Response.WriteAsync("Get config: /config?key=test");
    var value = configService[key];
    return context.Response.WriteAsync(value ?? "undefined");
});

Full demo source is available on GitHub.

Pitfalls

Use service name (e.g., apollo-db) for database connections, not container name.

Understand the difference between -Deureka.instance.homePageUrl (service address) and -Deureka.service.url (registry address).

Conclusion

When time permits, read the official documentation to understand the design; it helps avoid confusion when issues arise.

Make incremental progress every day.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesConfiguration ManagementYAMLApolloDocker Composehelmnet
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.