cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1416
Views
6
Helpful
5
Comments
Jens Albrecht
Spotlight
Spotlight

Create a Docker container for CML 2.9

The native support for Docker containers is the biggest feature added to CML in version 2.9 and it comes with 10 different pre-built ready-to-use containers.

However, as other users have already noticed as well, the Radius container is not working as expected due to missing entries in the radiusd.conf file.

Furthermore, I wanted to have a Radius container with debugging enabled to facilitate troubleshooting and hence decided to build my own Radius container to be used within CML.

Note: The CML-Team reacted really fast, and Ralph Schmieder just released a YouTube video with an updated radiusd.conf file that can be downloaded from his GitHub repository. My preparations for this article were already done so that I decided to stay with the Radius example, especially as I wanted to have the Debug option enabled. Of course, you can use this as a guideline to create other useful Docker containers like iperf3, Trex and many more.

The myradius.yaml file I prepared for the Node definition can be downloaded at the end of this article as a reference.

Prerequisites

First, you need CML v2.9 to begin with. It does not matter whether you use CML-Free or any paid version as the software is the same.

To build the containers, I use an Ubuntu 24.04 machine with the latest version 28.3.3 of Docker CE installed. Since I only use the CLI you can use Docker on Windows, macOS or any other Linux flavor as well.

I assume some basic knowledge of Linux, e.g. how to add a user to the Docker group but at the end of this article I include a Troubleshooting section regarding some issues you might run into and how to fix them. Take a look at that section when you run into problems.

This article is meant to be a living document, meaning I plan to update this as needed as well as based on your comments.
So, let’s get started!

Building the Radius docker container

Step 1: Prepare Your Environment

Create a new directory for your project (recommended to use a descriptive name), then navigate into it:

mkdir myradius
cd myradius

Step 2: Create the Dockerfile

Use your preferred text editor to create a file named Dockerfile.myrad in your project folder. Add the following content to define the properties of the FreeRADIUS container:

# Use latest official FreeRADIUS image v3.2.7 as base
FROM freeradius/freeradius-server:3.2.7

# Optional: COPY your custom config files into the container
# COPY raddb/ /etc/raddb/

# Set FreeRADIUS to run in foreground debug mode
ENTRYPOINT ["freeradius", "-f", "-X", "-lstdout"]

You can check the contents of the file:

15-08-2025_18-10-48.png

Step 3: Build the Docker Image

Use the following command to build the Docker image from your Dockerfile:

docker build -f Dockerfile.myrad -t myradius:3.2.7 .

15-08-2025_18-14-29.png

Note: If you get some error messages “permission denied…”, then your user is not a member of the docker group (see Troubleshooting section).

Checking the docker images lists the newly created one:

15-08-2025_18-37-32.png

Step 4: Save the Docker image

Save the Docker image as a TAR file to enable transfer to your CML server:

docker save -o myradius.tar myradius:3.2.7

Note: This may take some time depending on image size. Verify the creation of the myradius.tar file when done:

15-08-2025_21-40-58.png

Step 5: Get the SHA256 Checksum

Retrieve the SHA256 checksum of your Docker image:

docker image inspect -f '{{ index .Id }}' myradius:3.2.7

15-08-2025_18-23-43.png

Take note of the sha256 checksum as this value will be needed for creating the Image Definition on your CML server at Step 9:

de4a610246fd02a8fa4f50579df473c6d1fcfe4983413f825e6feffb02c9f9e1

Step 6: Transfer the TAR-File

If needed, copy the TAR file to a USB stick or network share to make it available for transfer to your CML server.

Configuration on the CML-Server

Step 7: Prepare the YAML Node Definition

Create the YAML-file for the MyRadius container:

Node Definitions are stored at the CML server as YAML files. We use the default Radius YAML file as a template and modify it to match our custom container image and requirements. Depending on the node type you want to create, you may use another node type to start with, of course.

  • Log into CML as admin and navigate to “Tools -> Node and Image Definitions”
  • Look for Radius, select the tile and click “Download” at the top right corner
  • Open the radius.yaml file with the editor of your choice

There are several occurrences of ‘radius’ and ‘Radius’ in this file that need to be checked. Some refer to labels or descriptions but the key items are the following:

  • The first line contains the id that needs to be changed to myradius.
    Note: The id must be unique on your CML-Server.
  • Line 14 contains the image which must match the tag of our container.
    So, we need to replace “image”: “radius:3.2.1” with “image”: “myradius:3.2.7”.
    Warning: If the image name does not match the container you get an error message when you try to start your node (see Troubleshooting section).
  • At the end of the file you find label that defines the name for the node definition in CML.
    We change this to label: MyRadius.
  • Next line has the label_prefix that is used for the display name of the node in your topologies.
    We change this to label_prefix: myradius-
  • I also changed the descriptions to contain the correct version and added that debug is enabled
  • Finally, I modified the radiusd.conf section to make Radius work as expected
  • If you like, you can also modify the users, clients.conf and boot.sh section to reflect your preferences regarding user accounts, client networks and IP addresses.
  • You can also change the resources for the container like RAM or CPUs if needed
  • Save the file as myradius.yaml.

Note: My version of the file myradius.yaml contains some additional changes e.g. to the users section to reflect common AAA use cases.

Step 8: Create the Node Definition

Upload your customized YAML node definition into CML via the Node and Image Definitions interface, ensuring all fields are set as described above:

  • Import the YAML file into CML via “Tools -> Node and Image Definitions -> Import”.
  • Click the Paper Clip icon, select your YAML file and then click “Open”.
  • Selecting “Go To Node Definition” will open the Node Definition Editor.
  • Confirm that the fields ID, Description, Description (Markdown), Prefix and Label display the modified entries correctly.

At this point, the editor shows “Available Image Definitions (0)” since you have not yet uploaded your Docker container. This will be handled in the next step.

Note: See the Verification section for a screenshot of the final Node Definition.

Step 9: Create the Image Definition

Open the Image Definitions section in CML, upload your TAR file, and then create a new Image Definition that references your Docker image and corresponding node definition:

  • Select “Create New Image Definition” and then “Manage Image Uploads”. This opens the “Image File Upload” window.
  • Click the Paper Clip Icon, select the TAR file of your container and click “Open”.
  • Select “Upload Image” and wait until the upload is completed. The TAR file is now displayed under “Uploaded Images”.
  • Select “Create New Image Definition” to open the Image Definition Editor.
  • Enter the ID, Label and Description to match the fields of your Node definition.
  • Click “Node Definition” and select the one you created, in this case MyRadius.
  • Click “Disk Image” and select the TAR file you uploaded, in this case myradius.tar.
  • Select “Disk Hash” and enter the sha256 checksum you calculated in Step 5.
    Warning: If the hash does not match your container, the node will hang when you attempt to start it, without an error message (see Troubleshooting section).
  • Finally, click “Create Image Definition” and you get a quick confirmation pop-up.

Note: See the Verification section for a screenshot of the final Image Definition.

Step 10: Deploy and Test the New Node

Add your custom node to a CML workspace topology, configure it as needed, and start the lab to verify proper operation of the new Docker container:

Use the Dashboard to open an existing topology or to add a new one. Select “Add Nodes” and drag the new MyRadius node to your Workbench and connect it to a switch. Select the MyRadius node, click "Config" and edit the files as required. Set IP address and gateway, user accounts and clients so that they fit your lab setup.

When you are done, start the MyRadius node. The first start takes significantly longer as CML needs to load the container so be patient. Subsequent starts will happen almost instantly.

If the node does not start, appears to hang, or you receive an error message, refer to the Troubleshooting section for guidance.

Verification

You have successfully created your own Radius Docker container and you can review the Node and Images definitions.

The Node Definitions contain a new entry:

16-08-2025_18-43-39.png

Verify the contents of the MyRadius node definition:

16-08-2025_18-45-12.png

The Image Definitions contain a matching entry as well:

16-08-2025_18-48-07.png

It is obvious that the tiles for the node and image definitions look exactly the same because we used the same entries for the Label and Description fields. You may want to include e.g. the version for the image in case of containers that get updated more frequently. There are no dependencies so that you can modify these entries as needed.

Verify the contents of the MyRadius image definition:

16-08-2025_18-48-53.png

Troubleshooting

There is always the chance for a typo or to miss something. So let us take a look at some common problems that might occur and how to solve them.

Docker commands resulting in error messages

If you install Docker and try to run commands, you might see error messages like the following:

16-08-2025_22-57-36.png

This happens because the user devadmin is not a member of the docker group as you can see from the 'groups' command output.

You can either use 'sudo' for each command or change the group membership for your user with the following commands:

  • 'sudo usermod -aG docker $USER' to add the current user to the docker group
  • 'newgrp docker' to update the group membership of your user
    You could also log out and log back in for this change to take effect
  • Now you have the right to use docker commands

16-08-2025_23-01-04.png

CML: Node does not start but hangs

The very first start of your new node takes quite a bit longer but if it just hangs and does not start at all without any error messages, you need to dig deeper.

10-08-2025_13-32-01.png

Hence, you need to log into the System Administration Cockpit with the system administrator account.

Under "System" select "Protocols" on the left side of the screen and then change the "Priority" to "Debug and higher" to get the maximum detail level.

You might see some generic messages that indicate problems loading the TAR file:

13:12
[33mWARNING:[0m docker_shim:250:Docker image /var/lib/libvirt/images/virl-base-images/myradius/myradius.tar load required
virl2-lowlevel-driver.sh

I experienced these error messages when the sha256 checksum was not correctly copied into the “Disk Hash” field of the image definition in Step 9.

CML: Error message ‘No such image’

When you try to start your new node you might get the following error message:

11-08-2025_18-20-53.png

This indicates that the image name that you entered in Step 7 while creating the YAML-file (Line 14 in this example) does not match the repository name and tag of your docker image.

In this case it is obvious as we named our docker image myradius:3.2.7. So, you need to check the correct name and tag with the docker images command and verify the entry in your YAML-file.

Conclusion and final words

CML version 2.9 with the build-in support for Docker containers and pre-built sample nodes is a huge step forward and opens entirely new options.

This KB article shows how-to build your own Docker container to further expand the opportunity to create complex network topologies by adding new services or modifying existing ones. Whether you want to add traffic generators like iperf3 or monitoring tools like Grafana, the choice is yours. Any functionality available via Docker containers can now seemingly be integrated into CML.

If you have any comments, tips/hints or further ideas, please leave a comment. This article will be updated as needed so your feedback is highly appreciated. Thanks!

Comments
Martin L
VIP
VIP

Awesome, Thank You for sharing!!!

Thank alot

Next year I will get my own server and try install CML and sure your post will help alot 

MHM

M02@rt37
VIP
VIP

Thanks Jens !

nicolay1974
Level 1
Level 1

Hi @Jens Albrecht,
Thank you very much — your work is truly excellent.
I've integrated your node definition file and the Docker image I created into my CML setup, however, I'm still encountering the same error as before. I'm currently stuck, as your radiusd.conf file appears to be identical to Ralph's configuration.
Additionally, I've noticed that even though the RADIUS daemon is running in debug mode, the console output lacks detailed information.

nicolay1974_1-1755787745179.png

 



nicolay1974_0-1755787712953.png

 

Jens Albrecht
Spotlight
Spotlight

Hi @nicolay1974,

I indeed changed the 'radiusd.conf' section at last minute to Ralph's version as it appeared to work in his video. The original testing was done with the version provided by FreeRADIUS which is 900+ lines long due to lots of comments. So I switched to his stripped down version to reduce overhead. Hence I need to test this and will then update the file accordingly.

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community:

Quick Links