Deployment guide

Apollo config

Overview

Apollo is an open source distributed configuration management center. Applications fetch typed, versioned configuration at runtime and pick up changes without a redeploy. Operators get per-environment and per-cluster namespaces, release and rollback history, grey-scale (canary) releases and a complete audit trail of every change.

A web portal manages all of it, so configuration stops living in scattered property files and becomes a governed, reviewable resource.

The SecureAnyCloud image installs Apollo 2.5.2 from the official release distribution under /opt/apollo. It runs the full three-service topology on a single VM, backed by an on-box MySQL 8.0 with both Apollo schemas already created and seeded:

Component Port Bound to Role

apollo-portal 8070 all interfaces the web console you sign in to

apollo-configservice 8080 127.0.0.1 serves configuration to client apps, hosts the Eureka meta server

apollo-adminservice 8090 127.0.0.1 privileged management API used by the portal

mysqld 3306 127.0.0.1 ApolloConfigDB and ApolloPortalDB

Only the portal is reachable from the network. Apollo's config service is unauthenticated by default. Any caller that knows an application ID can read that application's configuration unless per-namespace access keys are enabled. The admin service is a privileged API intended only for the portal.

Shipping either one open to the network would be unsafe, so this image binds both to the loopback interface. Step 9 explains how to deliberately expose the config service to your own application subnet when you are ready to onboard client applications.

Secure by default: Apollo's published sample data seeds the portal user apollo with the well-known password admin. This image ships neither that password nor any other usable login. Cleanup locks the account outright.

An apollo-config-firstboot.service oneshot runs once before the Apollo services start. It generates a unique portal administrator password, a unique database password and a unique database root password for your VM, and writes them to a root-only file. No two instances share a credential.

What you get:

  • Apollo 2.5.2 (Apache-2.0) under /opt/apollo, installed from the official release zips with published checksums verified
  • MySQL 8.0 with the ApolloConfigDB and ApolloPortalDB schemas created and seeded
  • apollo-portal, apollo-configservice and apollo-adminservice running as the dedicated apollo system user on Java 17
  • apollo-config-firstboot.service, which generates every credential per VM on first boot
  • Per-VM credentials written to /root/apollo-config-credentials.txt (mode 0600, root only)
  • OpenJDK 17 runtime, apt-managed for security updates

Prerequisites

  • An Azure subscription with permission to create virtual machines
  • An SSH key pair for administrative access
  • A VM size with at least 8 GiB of memory. Apollo runs three JVMs alongside MySQL, so Standard_B2ms (2 vCPU, 8 GiB) is the recommended minimum for real workloads.
1

Deploy from the Azure Portal

In the Azure Portal, choose Create a resource. Search for Apollo Config on Ubuntu 24.04 LTS from SecureAnyCloud, and select Create.

Choose your subscription, resource group and region. Set the VM size to Standard_B2ms or larger. Select SSH public key as the authentication type, with the username azureuser.

Under Inbound port rules, allow SSH (22), then add port 8070 for the Apollo portal. Select Review + create.

2

Deploy from the Azure CLI

Restrict both SSH and the portal to your own management network. Do not open them to the internet.

RG="apollo-config-prod"; LOCATION="eastus"; VM_NAME="apollo-config-01" IMAGE_URN="sac1647283583153:apollo-config-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name apollo-vnet --address-prefix 10.90.0.0/16 --subnet-name apollo-subnet --subnet-prefix 10.90.1.0/24 az network nsg create -g "$RG" --name apollo-nsg az network nsg rule create -g "$RG" --nsg-name apollo-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name apollo-nsg --name allow-portal --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 8070 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:apollo-config-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2ms --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name apollo-vnet --subnet apollo-subnet --nsg apollo-nsg --public-ip-sku Standard

Deployment takes two to three minutes. The first boot generates your credentials and starts the Apollo services.

3

Connect over SSH

ssh azureuser@<vm-ip>
4

Verify the services are running

Four units make up the appliance. All four should report active.

systemctl is-active mysql apollo-configservice apollo-adminservice apollo-portal
5

Confirm the listener posture

This is the security property worth checking on any configuration server. Only the portal on 8070 and SSH on 22 accept connections from the network. The config service, the admin service and MySQL are bound to the loopback interface, so they cannot be reached from off the VM.

ss -tlnp | grep -E ':8070|:8080|:8090|:3306|:22 ' | sed 's/ */ /g'

Addresses shown as [::ffff:127.0.0.1] are IPv4-mapped loopback. This is how a Java listener bound to 127.0.0.1 is reported.

6

Retrieve your per-VM credentials

There is no shared default login. On first boot, the image generated a unique portal administrator password for this VM and stored it in a root-only file.

sudo cat /root/apollo-config-credentials.txt 2>/dev/null || echo "credentials are generated on first boot"

The file lists the portal URL, your unique apollo password, the database password and the MySQL root password (mode 0600, owner root). Store it somewhere safe.

7

Confirm the stack is healthy end to end

The portal answers on 8070, and the loopback-bound config service answers its meta server endpoint. The POST /signin endpoint establishes a session with your per-VM administrator password.

curl -s -o /dev/null -w 'portal -> HTTP %{http_code}\n' http://127.0.0.1:8070/
curl -s -o /dev/null -w 'config service -> HTTP %{http_code}\n' http://127.0.0.1:8080/services/config
PW=$(sudo sed -n 's/^APOLLO_PORTAL_PASSWORD=//p' /root/apollo-config-credentials.txt 2>/dev/null)
CJ=$(mktemp)
curl -s -o /dev/null -c "$CJ" -X POST http://127.0.0.1:8070/signin \
  -d username=apollo --data-urlencode "password=${PW:-<portal-password>}"
curl -s -b "$CJ" http://127.0.0.1:8070/user \
  | python3 -c 'import sys;d=sys.stdin.read();print("portal sign in OK" if "userId" in d else "sign in with the password from /root/apollo-config-credentials.txt")' rm -f "$CJ"
8

Sign in to the portal and create your first project

Open http://<vm-ip>:8070/ in your browser and sign in with the username apollo and the password from /root/apollo-config-credentials.txt.

Choose Create project. Enter a department, an App Id that your application will use to identify itself, an App Name and an owner, then submit. Your project now appears on the portal home page.

Open the project to reach its configuration view. Select the DEV environment, choose Add Configuration to add a key and value, then choose Release to publish it.

Released items become visible to client applications immediately. Use the Release History and Rollback controls to review and revert any change.

9

Connect your applications to the config service

Client applications read configuration from the config service on port 8080. This image binds it to the loopback interface, so nothing unauthenticated is exposed by default. An application running on this same VM can use it immediately:

curl -s "http://127.0.0.1:8080/services/config" | head -c 300; echo

To let applications on other machines read configuration, expose the config service deliberately:

  • Enable access keys first. In the portal, open your project and choose Manage AccessKey, then create and enable a key. Client applications must then sign their requests, so knowing an App Id is no longer enough to read configuration.
  • Bind the config service to a routable address. Edit /etc/systemd/system/apollo-configservice.service and change -Dserver.address=127.0.0.1 to the VM's private address, then run sudo systemctl daemon-reload && sudo systemctl restart apollo-configservice.
  • Restrict the network path. Add an Azure network security group rule that allows 8080 only from your application subnet, never from the internet.

Leave the admin service on port 8090 bound to loopback. It is a privileged management API with no authentication of its own, and only the portal on this VM calls it.

10

How secure by default works

Apollo's published sample SQL seeds the portal user apollo with a BCrypt hash of the password admin, a value documented in Apollo's own quick start. An image that shipped that hash would give every customer the same publicly known administrator login.

This image removes it in two stages. During the build, the account is locked. The seeded hash is replaced with a value that no password can match, so the captured image contains no usable portal login at all.

Then, on your VM's first boot and before any Apollo service starts, apollo-config-firstboot.service generates a random portal password, hashes it and writes it into ApolloPortalDB. It also generates fresh per-VM passwords for the Apollo database user and MySQL root. The database credentials are written to a single systemd environment file with an atomic rename, so a partially written file can never leave the services in a broken state.

As a result, the documented apollo / admin login is rejected on every VM launched from this image, and each VM's credentials are unique to it.

The oneshot marks itself complete with a sentinel, so it never re-runs and never re-rotates a credential you have started using:

ls -l /var/lib/sac/data/apollo-config-firstboot.done 2>/dev/null || echo "first boot has not run yet"
sudo ls -l /root/apollo-config-credentials.txt 2>/dev/null || echo "written on first boot"
11

Enable HTTPS

The portal serves plain HTTP on 8070. For production, terminate TLS in front of it. Install a reverse proxy and point it at 127.0.0.1:8070. Obtain a certificate for your domain, then restrict the network security group so that only the proxy port is reachable.

Managing the services

sudo systemctl status apollo-portal --no-pager sudo systemctl restart apollo-portal
sudo journalctl -u apollo-portal -n 50 --no-pager

To restart the whole appliance in dependency order:

sudo systemctl restart apollo-configservice apollo-adminservice apollo-portal

Application logs are written under /var/log/apollo.

Support

This image is published and supported by SecureAnyCloud. For assistance, contact sales@secureanycloud.com. Apollo is a trademark of its respective owners. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Apollo Config on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure