A standalone RESTful API server for managing Containerlab deployments, enabling programmatic control and remote management of network labs.
- Lab Management: Deploy, destroy, redeploy, inspect, and list labs
- Node Operations: Execute commands and save configurations
- SSH Access: Connect to lab nodes via SSH through the API server
- Topology Tools: Generate and deploy CLOS topologies
- Network Tools: Manage network emulation, virtual Ethernet pairs, VxLAN tunnels
- Certification Tools: Certificate management
- User Management: Create, update, delete users and manage permissions using Linux system accounts
- Health Monitoring: Check server health status and system metrics
- Logs: Check logs of the nodes, static or streaming
- User Context: Track ownership and manage files within user home directories
- Multitenancy: Support for multiple users with separate access to labs
- Standalone Topology Editing: File-scoped topology endpoints for browser UI integration
- Documentation: Embedded Swagger UI and ReDoc for API exploration
The latest API endpoints documentation is published on GitHub Pages: Containerlab API Server Documentation
| Requirement | Version / Notes |
|---|---|
| Linux | Any modern distribution. The binaries target amd64 and arm64. |
| PAM | Uses the default login PAM service. No extra configuration needed on most distros. |
| User / Group | Users must belong to the configured API or superuser group. The installer creates the default groups. |
| Docker | Required for containerized deployment or when using Docker as container runtime |
Note
The API server uses containerlab as an integrated Go library - no separate containerlab binary installation is required.
Choose the method that matches how long the API server should live:
| Method | Best for | Notes |
|---|---|---|
| Systemd installer | Persistent lab hosts and GUI backends | Recommended for normal use. |
| Containerlab tools command | Quick trials, demos, temporary access | Starts the API server as a container. |
| Direct binary / pull-only | Debugging or custom supervision | You manage config and process lifetime. |
| Docker run | Advanced container-managed deployments | You manage mounts, config, and lifecycle. |
Install the latest release. The installer selects the correct amd64 or arm64 binary automatically:
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo bash -s -- installIf the host needs a proxy to reach GitHub or other external endpoints, export the standard proxy variables and preserve them for the root-side installer:
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=localhost,127.0.0.1
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo -E bash -s -- installThis will:
- Download the binary to
/usr/local/bin/clab-api-server - Create a default configuration at
/etc/clab-api-server/clab-api-server.env - Create a systemd unit at
/etc/systemd/system/clab-api-server.service - Create the default Linux groups
clab_apiandclab_adminsif they do not exist - Generate a random
JWT_SECRETfor new installations
Review the configuration and add users to the API group before starting the service:
sudoedit /etc/clab-api-server/clab-api-server.env
sudo usermod -aG clab_api <username>
sudo systemctl enable --now clab-api-serverFor proxy environments, also add HTTP_PROXY, HTTPS_PROXY, and NO_PROXY to /etc/clab-api-server/clab-api-server.env before starting the service. If you used install --start, restart clab-api-server after editing the file.
For an immediate start with the generated defaults, use install --start.
The systemd service runs as root because the API server controls host container runtime resources, network namespaces, Linux users, and lab files.
By default, managed topology files are stored under each Linux user's ~/.clab directory. To store GUI-created and API-managed lab workspaces somewhere else, set CLAB_LABS_ROOT in /etc/clab-api-server/clab-api-server.env to an absolute path, for example:
CLAB_LABS_ROOT=/var/lib/containerlab/labsWith that setting, files are stored under /var/lib/containerlab/labs/<username>/. ~ expansion is not supported because the service runs as root while authenticating separate Linux users.
Use Containerlab's built-in command for quick trials or temporary API access:
# Start the API server as a container
sudo containerlab tools api-server start [flags]
# Stop the API server container
sudo containerlab tools api-server stop
# Check API server container status
sudo containerlab tools api-server statusThis method automatically handles Docker image pulling, container creation, and environment configuration.
Common flags for the start command include:
--port | -p: Port to expose the API server on (default:8090)--host: Host address for the API server (default:localhost)--labs-dir | -l: Directory to mount as the managed labs root--jwt-secret: JWT secret key for authentication, generated randomly if unset--tls-enable: Enable TLS for HTTPS connections, enabled by default
Note
The standalone systemd install and the Containerlab tools helper both default to port 8090 and HTTPS.
Use pull-only when you only want the architecture-specific binary:
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo bash -s -- pull-onlyThen run it with your own process management:
sudo clab-api-server -env-file /path/to/clab-api-server.envConfigure via environment variables or a .env file. See .env.example and the Configuration Reference for available options.
If using proxy environment variables with a direct sudo run, preserve them with sudo -E.
Run the API server as a Docker container with access to the host resources:
docker run -d \
--name clab-api-server \
--privileged \
--network host \
--pid host \
-e LOG_LEVEL=debug \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/run/netns:/var/run/netns \
-v /var/lib/docker/containers:/var/lib/docker/containers \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/shadow:/etc/shadow:ro \
-v /etc/group:/etc/group:ro \
-v /etc/gshadow:/etc/gshadow:ro \
-v /home:/home \
ghcr.io/srl-labs/clab-api-server/clab-api-server:latestNote
Volume mounts enable Docker management, networking features, Linux PAM authentication, and user file storage. No containerlab binary is required - it's integrated as a Go library.
This Docker example uses the default managed lab storage: each authenticated user's ~/.clab directory from the mounted /home. To use a different root, add both CLAB_LABS_ROOT and a matching volume mount:
-e CLAB_LABS_ROOT=/var/lib/containerlab/labs \
-v /var/lib/containerlab/labs:/var/lib/containerlab/labs \Check for a newer API server release and upgrade the installed binary:
clab-api-server version check
sudo clab-api-server version upgradeThe installer can also upgrade to latest or replace the binary with a specific release tag. Installing an older tag is the supported downgrade path:
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo bash -s -- upgrade
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo bash -s -- upgrade --version clab-0.73.0-api-0.2.1Upgrade stops and restarts the service only if it was running before the upgrade.
Uninstall removes the service and binary while keeping configuration by default:
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo bash -s -- uninstallRemove the configuration intentionally with --purge:
curl -fsSL https://raw.githubusercontent.com/srl-labs/clab-api-server/main/install.sh | sudo bash -s -- uninstall --purgeAfter startup, verify the service:
sudo systemctl status clab-api-server| Variable | Default | Description |
|---|---|---|
API_PORT |
8090 |
Server listening port |
API_SERVER_HOST |
localhost |
Hostname/IP used in SSH access URLs |
TERMINAL_MAX_SESSIONS_PER_USER |
128 |
Maximum active browser terminal sessions per API user |
JWT_SECRET |
generated by installer | CRITICAL: Secret key for JWT token generation |
JWT_EXPIRATION |
24h |
JWT token lifetime (e.g., "24h", "7d") |
API_USER_GROUP |
clab_api |
Linux group for API access |
SUPERUSER_GROUP |
clab_admins |
Linux group for elevated privileges |
CLAB_RUNTIME |
docker |
Container runtime used by Containerlab |
CLAB_LABS_ROOT |
unset | Optional absolute root for managed lab workspaces. When set, users store labs under $CLAB_LABS_ROOT/<username>/; otherwise labs use <home>/.clab/. |
LOG_LEVEL |
info |
Log verbosity (debug, info, warn, error) |
CORS_ALLOWED_ORIGINS |
Comma-separated browser origin allowlist (for standalone UI) | |
GIN_MODE |
release |
Web framework mode (debug or release) |
SSH_BASE_PORT |
2223 |
Starting port for SSH proxy allocation |
SSH_MAX_PORT |
2322 |
Maximum port for SSH proxy allocation |
TLS_ENABLE |
true |
Enable TLS for HTTPS |
TLS_AUTO_CERT |
true |
Generate/reuse a local self-signed certificate when cert/key files are unset |
TLS_CERT_FILE |
Path to TLS certificate when overriding auto certificate generation | |
TLS_KEY_FILE |
Path to TLS private key when overriding auto certificate generation |
The Containerlab API Server uses Linux system users and passwords for authentication. Users must:
- Exist as valid Linux users on the system where the API server runs
- Belong to the configured
API_USER_GROUP(clab_apiby default) orSUPERUSER_GROUP(clab_adminsby default)
When authenticating via the API, provide the Linux username and password to receive a JWT token for subsequent requests.
- Server user – The process runs with permissions to access the container runtime.
- Authenticated users – Must be members of
API_USER_GROUPorSUPERUSER_GROUP. - Library integration – Containerlab is embedded as a Go library, not executed as a separate CLI process.
- Ownership – Lab ownership is tracked via container labels.
- SSH sessions – Allocated ports forward to container port 22 with automatic expiration.
- Security controls – PAM for credential validation, JWT for session management, input validation, and HTTPS by default.
Access interactive API documentation at:
https://<server_ip>:<API_PORT>/swagger/index.html # Swagger UI
https://<server_ip>:<API_PORT>/redoc # ReDoc UI
# Authenticate with your Linux username and password
TOKEN=$(curl -sk -X POST https://localhost:8090/login \
-H "Content-Type: application/json" \
-d '{"username":"your_linux_username","password":"your_linux_password"}' \
| jq -r '.token')
# Optional: request a custom token lifetime for this login
TOKEN_CUSTOM=$(curl -sk -X POST https://localhost:8090/login \
-H "Content-Type: application/json" \
-d '{"username":"your_linux_username","password":"your_linux_password","sessionDuration":"36h"}' \
| jq -r '.token')
# List labs
curl -k -H "Authorization: Bearer $TOKEN" https://localhost:8090/api/v1/labs
# Deploy a lab
curl -k -X POST https://localhost:8090/api/v1/labs \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"topologyContent":{"name":"srl01","topology":{"kinds":{"nokia_srlinux":{"type":"ixrd3","image":"ghcr.io/nokia/srlinux"}},"nodes":{"srl1":{"kind":"nokia_srlinux"},"srl2":{"kind":"nokia_srlinux"}},"links":[{"endpoints":["srl1:e1-1","srl2:e1-1"]}]}}}'The standalone containerlab-gui app uses these authenticated endpoints:
GET /api/v1/topologies- list editable topology files for the userGET|PUT /api/v1/topologies/{labName}/yaml- read/write canonical topology YAML (<lab>.clab.yml)GET|PUT /api/v1/topologies/{labName}/annotations- read/write canonical annotations JSON (<lab>.clab.yml.annotations.json)GET|PUT|DELETE|HEAD /api/v1/topologies/{labName}/file?path=<relativePath>- scoped file operations inside the lab directoryPOST /api/v1/topologies/{labName}/file/rename- scoped rename operationPOST /api/v1/topologies/{labName}/deploy- deploy an on-disk topology by lab name
Enable browser access by setting CORS_ALLOWED_ORIGINS (for example https://localhost:5173).
Flashpost is a free alternative to Postman that runs entirely in VS Code as an extension.
The examples folder contains a Flashpost collection that demonstrates how to use the Containerlab API. The collection provides ready-to-use requests for all API endpoints.
The collection assumes that the server is running on localhost:8090, but you can change the server URL via a variable.
To use the collection:
- Install the Flashpost VS Code extension
- Import the collection from the json file in the examples folder
The collection makes use of the following variables:
USER_NAME- Linux user name that client will use for authentication with the clab api serverUSER_PASSWORD- Linux user password that client will use for authentication with the clab api serverbaseUrl- for example:localhost:8090
For development setup:
git clone https://github.com/srl-labs/clab-api-server.git
cd clab-api-server
cp .env.example .env # edit JWT_SECRET
# build & run
task # tidy → swag docs → build binary
./clab-api-server