Installation & Deployment
Overview
This guide walks you through installing and running the TR-069 Emulator — a Spring Boot application (Java 25) that simulates TR-069/CWMP CPE devices for testing ACS implementations. Docker is the recommended deployment method: it ships a self-contained image that runs the emulator in headless web mode and exposes the browser-based control panel and REST API.
The deployment consists of:
-
TR-069 Emulator — Spring Boot service started with
--web-mode(no desktop Swing GUI), serving the Web UI, the REST API and Swagger UI on port8555. -
Connection Request listener — an HTTP listener on port
9999that lets the ACS initiate sessions with emulated devices. -
Docker container — pre-built image from the Harbor registry or loaded from an archive.
-
Parameter trees — XML device-model files under
/app/parameterstreeinside the container, baked into the image and optionally mounted as a volume for customization.
|
The emulator runs as a single container and needs no database of its own to start.
It connects outbound to your ACS (the host/port you configure in the UI), and — when Connection Request is enabled — accepts inbound requests from the ACS on port |
Prerequisites
System Requirements
-
Docker Engine 20.10+
-
Docker Compose 2.0+ (optional — only for the Compose deployment option)
-
Minimum 1 GB RAM (2+ GB recommended; significantly more for large device counts — see Production / Load-Test Checklist)
-
500 MB free disk space for the image and logs
|
JDK 25 is only required for local Maven builds and for running the desktop GUI without Docker. Docker deployment does not need a JDK on the host machine. |
Supported Operating Systems
-
Linux (recommended)
-
macOS
-
Windows (Docker Desktop, or native Java for the desktop GUI)
Before starting, make sure:
-
Docker Engine 20.10+ is installed. If Docker is not installed, follow the Docker Installation Guide.
-
You have network access from the emulator to your ACS (HTTP/HTTPS host and port).
-
If you will use Connection Request, the ACS can reach the emulator host on port
9999— see Connection Request Host.
Quick Start
For experienced users who already have Docker installed.
# 1. Authenticate with the registry (first time only)
docker login hub.friendly-tech.com
# 2. Run the emulator (the image is pulled automatically if missing)
docker run -d \
--name tr069-emulator \
-p 8555:8555 \
-p 9999:9999 \
hub.friendly-tech.com/emulator/tr069:latest
# 3. Verify (returns 200 with "Running" or "Stopped")
curl -s http://localhost:8555/api/status
After startup the Web UI is available at http://localhost:8555.
|
Port |
Getting the Docker Image
Option A: Pull from Harbor Registry (recommended)
# Authenticate with the registry
docker login hub.friendly-tech.com
# Pull the latest image (optional -- "docker run" / "docker compose up"
# will pull it automatically on first use)
docker pull hub.friendly-tech.com/emulator/tr069:latest
To pin to a specific release tag instead of latest:
docker pull hub.friendly-tech.com/emulator/tr069:<version>
|
|
Option B: Transfer Image to an Offline Server
Use this option when the target server has no internet access. The image is pulled on a machine that does have Harbor access, exported to a tar archive, transferred to the offline server, and loaded there.
-
On a machine with Harbor access, log in and pull the image for the target server’s architecture:
docker login hub.friendly-tech.com docker pull --platform linux/amd64 \ hub.friendly-tech.com/emulator/tr069:latestAn explicit
--platformmatching the offline target server’s architecture is required if the image is multi-arch. Without--platform,docker pullselects the host architecture, which may not match the target. Replacelinux/amd64with the platform of your offline target (linux/arm64, etc.). -
Save the pulled image to a tar archive and compress it:
docker save hub.friendly-tech.com/emulator/tr069:latest \ -o tr069-emulator.tar gzip tr069-emulator.tar -
Transfer
tr069-emulator.tar.gzto the offline server (e.g., viascpor removable media). -
On the offline server, load the image:
gzip -dc tr069-emulator.tar.gz | docker load
Option C: Build from Source (developers only)
# Build the application JAR (Java 25 + Maven)
mvn clean package -DskipTests
# Build the Docker image (uses the bundled Dockerfile)
docker build -t tr069-emulator:latest .
|
The |
After loading, pulling or building, verify the image is available:
docker images | grep tr069
Parameter Trees & Configuration
Parameter Trees Directory
Device data models are defined by XML files in the parameterstree/ directory (/app/parameterstree inside the container).
These files are listed, selected, uploaded and deleted from the Web UI and the REST API.
parameterstree/ ├── cpe_params.xml # default tree (EmulatorParameter PARAMS_XML) ├── cpe_params_big_tree.xml ├── device_Technicolor.xml ├── Huawei_HG8245Q2.xml ├── base/ │ ├── tr-098.xml # InternetGatewayDevice. root model │ └── tr-181.xml # Device. root model └── ... (other device XML files)
The base/ subdirectory holds canonical TR-098 (InternetGatewayDevice.) and TR-181 (Device.) trees used by the "start by protocol" flow (REST POST /apiV2/startProtocol).
Each file defines the TR-069 data model — parameter paths, values, types and writability:
<?xml version="1.0" encoding="UTF-8"?>
<device>
<parameter>
<name>Device.DeviceInfo.Manufacturer</name>
<value>MyCompany</value>
<type>string</type>
<writable>false</writable>
</parameter>
<!-- More parameters... -->
</device>
|
A bind mount on |
Runtime Configuration Files
The emulator persists runtime state to property files in its working directory (/app), not to a separate configuration directory:
| File | Description |
|---|---|
|
Persisted emulator start parameters — ACS protocol/host/port/URL path, group/concurrency/delay counts, and option toggles. Written when you click Save / Save Config in the UI. |
|
Definitions of auto-updating parameters (the Updatable Parameters feature). |
To keep this state across container re-creation, mount the working directory (or the individual files) as a volume — see Deployment.
Connection Request Host
When running in Docker, the emulator must report an externally reachable address to the ACS so the ACS can send Connection Requests back to the emulated device.
Set the CONNECTION_REQUEST_HOST environment variable to the host IP or hostname the ACS can reach:
docker run -d \
--name tr069-emulator \
-p 8555:8555 \
-p 9999:9999 \
-e CONNECTION_REQUEST_HOST=192.168.1.100 \
hub.friendly-tech.com/emulator/tr069:latest
This sets the Connection Request URL reported to the ACS to http://192.168.1.100:9999/{serial} (the variable maps to the JVM property -Dconnection.request.address).
|
If |
Deployment
Option 1: docker run
docker run -d \
--name tr069-emulator \
-p 8555:8555 \
-p 9999:9999 \
-e CONNECTION_REQUEST_HOST=192.168.1.100 \
--restart unless-stopped \
hub.friendly-tech.com/emulator/tr069:latest
To customize parameter trees and persist runtime state, extract the defaults first and mount volumes:
# Extract the default parameter trees from the image
docker create --name tmp-tr069 hub.friendly-tech.com/emulator/tr069:latest
docker cp tmp-tr069:/app/parameterstree ./parameterstree
docker rm tmp-tr069
# Run with the parameter trees mounted (and persist runtime state)
docker run -d \
--name tr069-emulator \
-p 8555:8555 \
-p 9999:9999 \
-e CONNECTION_REQUEST_HOST=192.168.1.100 \
-v "$(pwd)/parameterstree:/app/parameterstree" \
--restart unless-stopped \
hub.friendly-tech.com/emulator/tr069:latest
Option 2: Docker Compose
Create a docker-compose.yml file:
services:
tr069-emulator:
image: hub.friendly-tech.com/emulator/tr069:latest
container_name: tr069-emulator
ports:
- "8555:8555" # Web UI + REST API
- "9999:9999" # Connection Request listener
environment:
- SPRING_PROFILES_ACTIVE=prod
- JAVA_OPTS=-Xms512m -Xmx1g
- CONNECTION_REQUEST_HOST=192.168.1.100 (1)
volumes:
- ./parameterstree:/app/parameterstree (2)
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8555/api/status"]
interval: 30s
timeout: 3s
start_period: 30s
retries: 3
| 1 | Replace with the IP address reachable by your ACS. Remove the line to use auto-detection. |
| 2 | Optional. Mounting replaces the built-in trees — populate the directory first (see Option 1). |
Start with:
docker compose up -d
docker compose logs -f tr069-emulator
Verify Installation
After starting the container, run the following checks:
# 1. Check container status
docker ps -f name=tr069-emulator
# Expected: container "Up" with 0.0.0.0:8555->8555/tcp and 0.0.0.0:9999->9999/tcp
# 2. Liveness check (returns 200 once the service is up)
curl -s http://localhost:8555/api/status
# Expected: "Running" or "Stopped"
# 3. Emulator status (Load Test) / active devices (Single Mode)
curl -s http://localhost:8555/api/status # "Running" or "Stopped"
curl -s http://localhost:8555/apiV2/activeEmulators # [] on a fresh start
# 4. Application logs
docker logs tr069-emulator --tail 50
# Look for the Spring Boot "Started ..." line
# 5. Web UI and Swagger UI (open in a browser)
# http://localhost:8555 # landing page (choose a mode)
# http://localhost:8555/load # Load Test Mode
# http://localhost:8555/single # Single Emulator Mode
# http://localhost:8555/swagger-ui.html # interactive REST API
# http://localhost:8555/v3/api-docs # OpenAPI spec
|
Use |
Environment Variables
| Variable | Description | Default | Required |
|---|---|---|---|
|
Web UI / REST API port inside the container |
|
No |
|
Active Spring profile |
|
No |
|
JVM options (heap sizing, GC, heap-dump on OOM). Increase the heap for large device counts. |
|
No |
|
External IP/hostname reported to the ACS for Connection Requests. Maps to |
(auto-detect) |
No |
|
Default ACS URL pre-filled in the UI start forms |
No |
|
|
Container timezone |
|
No |
|
Built on Spring Boot 3.5.6 / Java 25. The Connection Request listener defaults to HTTP on port |
|
|
Manual Installation (without Docker)
Use this when you want to run the emulator directly on a host with Java 25 installed — either in headless web mode or as the desktop GUI.
Build from Source
-
Clone the repository:
git clone https://github.com/Friendly-Technologies/TR069_Emulator.git cd TR069_Emulator -
Build with Maven:
mvn clean package -DskipTests
Run in Web Mode (headless)
Web mode serves the same browser UI and REST API as the Docker container.
java -jar target/FTCpeEmulator.jar --web-mode
Then open http://localhost:8555.
|
Run from the project root so the |
Container Management
| Command | Description |
|---|---|
|
Start the emulator in the background |
|
Stop / start the container |
|
Restart the application |
|
Follow application logs |
|
Open a shell inside the container |
|
List the available parameter-tree files |
|
View CPU / memory usage |
|
Show the container’s environment variables |
Updating
# 1. (Optional) back up parameter trees and runtime state
docker cp tr069-emulator:/app/parameterstree ./parameterstree-backup
docker cp tr069-emulator:/app/start_params.properties ./start_params.properties.bak
# 2. Pull the new image
docker pull hub.friendly-tech.com/emulator/tr069:latest
# 3. Recreate the container
docker rm -f tr069-emulator
docker run -d \
--name tr069-emulator \
-p 8555:8555 \
-p 9999:9999 \
-e CONNECTION_REQUEST_HOST=192.168.1.100 \
-v "$(pwd)/parameterstree:/app/parameterstree" \
--restart unless-stopped \
hub.friendly-tech.com/emulator/tr069:latest
# 4. Verify (returns 200 with "Running" or "Stopped")
curl -s http://localhost:8555/api/status
|
If you are not mounting |
Production / Load-Test Checklist
| # | Item | Notes |
|---|---|---|
1 |
Restart policy |
Use |
2 |
Connection Request host |
Set |
3 |
Heap sizing |
Raise |
4 |
Persistence |
Mount |
5 |
Health check |
Configure a healthcheck against |
6 |
Timezone |
Set |
Troubleshooting
Start with quick diagnostics:
docker logs tr069-emulator --tail 100
docker inspect tr069-emulator --format '{{json .Config.Env}}'
docker exec tr069-emulator ls -la /app/parameterstree
Common Issues
ACS cannot reach the device (Connection Request fails)
Symptom: The ACS reports Connection Request timeouts; the device only informs on its own schedule.
Solution:
-
Set
CONNECTION_REQUEST_HOSTto an address the ACS can reach (not the container’s internal IP). See Connection Request Host. -
Publish port
9999(-p 9999:9999) and ensure no firewall blocks it.
Parameter-tree dropdown is empty / "file not found"
Symptom: No XML files in the dropdown, or a device fails to start with a missing-tree error.
Check:
docker exec tr069-emulator ls /app/parameterstree
Solution:
-
If you mounted
/app/parameterstree, ensure the directory actually contains XML files (a mount replaces the built-in trees). -
Re-extract the defaults (see Deployment, Option 1) or upload a tree from the UI.
Web UI not reachable on port 8555
Symptom: The browser cannot connect to http://localhost:8555.
Check:
docker ps -f name=tr069-emulator
curl -s http://localhost:8555/api/status
Solution:
-
Confirm the port mapping (
-p 8555:8555) and that the container isUp.
Port Reference
| Port | Protocol | Description |
|---|---|---|
8555 |
HTTP |
Web UI, REST API, and Swagger UI |
9999 |
HTTP |
Connection Request listener (ACS-initiated sessions) |
| Outbound traffic to the ACS (HTTP/HTTPS on the host/port you configure in the UI) does not need to be published from the container. |
Related Documentation
-
Load Test Mode — bulk device simulation
-
Single Emulator Mode — granular per-device control
-
REST API Reference — automation and scripting