Fast setup for an Ubuntu server with Docker, including SSH access, persistent data, OpenVPN configuration, and optional GUI mode.
Copy-paste these 3 lines to bring up the lab instantly:
git clone https://github.com/william1nguyen/uvm.git
cd uvm
make start --guiNow open http://localhost:6080/vnc.html and youβre in π
- Features
- Prerequisites
- Docker Compose Workflow
- Make Help
- SSH Access
- GUI Mode (--gui)
- OpenVPN Management
- Apply VPN Config to a Container
- Verifying VPN Connection
- Apply Push Routes on OpenVPN Server
- Notes
- TODO
- Quick setup of Ubuntu server containers
- Persistent data storage
- Integrated OpenVPN server with client management
- Private and external network configuration for lab isolation
- Optional GUI desktop with Chrome browser via VNC/noVNC
Ensure your Docker environment is ready:
- Docker and Docker Compose installed
- Basic understanding of container networking
β οΈ Note: Orbstack does not support isolated networks, which is not suitable for this lab setup. It is recommended to use standard Docker: Orbstack issue #1944
The Makefile provides the following targets:
# Normal mode
make start
# VPN mode (vpn)
make start mode=vpn
# GUI mode (--gui)
make start --guiThis will start all containers defined in:
- Normal:
deployments/ubuntu/server/docker-compose.yml - VPN:
deployments/vpn/docker-compose.yml - GUI:
deployments/ubuntu/gui/docker-compose.yml
You can list all available commands with:
make helpLazy Ubuntu - Available commands
apply-push-routes Apply push routes to OpenVPN server
apply-vpn-config Apply VPN config to a container (SERVER=<name>)
listconfigs List OpenVPN profiles on server
reset Reset lab (remove containers, networks, volumes, images)
start Start lab (normal / vpn / gui)
stop Stop current lab
verify-vpn-config Verify VPN interface & routes inside container (SERVER=<name>)make resetThis cleans up:
- Networks
- Containers
- Volumes
- Images
make listconfigsEquivalent to:
docker exec openvpn ./listconfigs.shAfter starting the lab, you can connect to any ssh-ubuntu container via SSH:
ssh root@localhost -p 2222- Username:
root - Password:
rootpassword
π Ports may vary if you run multiple containers. Check the
docker-composemapping or logs.
To start an Ubuntu server with a lightweight desktop (XFCE) and Google Chrome:
make start --guiThis will:
- Run an Ubuntu server with SSH + GUI (XFCE4)
- Start VNC server on
:1(default port5901) - Expose noVNC at http://localhost:6080/vnc.html
- SSH:
ssh root@localhost -p 2222 - VNC Client: Connect to
localhost:5901 - Web Browser (noVNC): http://localhost:6080/vnc.html
Inside the VNC session:
- Double-click Google Chrome (Optimized) icon on desktop, OR
- Run:
/root/start-chrome.shmake apply-vpn-config SERVER=<container_name>Steps performed:
- Fetch
PROFILE_IDfrom OpenVPN server:
docker exec openvpn ./listconfigs.sh- Copy client configuration to host and target container:
docker cp openvpn:/opt/Dockovpn_data/clients/${PROFILE_ID}/client.ovpn ./data/client.ovpn
docker cp ./data/client.ovpn <container_name>:/client.ovpn- Install OpenVPN and run client in container:
docker exec -d <container_name> bash -c "apt-get update && apt-get install -y openvpn && openvpn --config /client.ovpn --daemon"Note: Ensure
./datadirectory exists on host.
make apply-push-routesThis will:
- Copy
push-routes.conffrom host into OpenVPN server:
docker cp ./config/push-routes.conf openvpn:/opt/Dockovpn/config/push-routes.conf- Append routes to server configuration:
docker exec -d openvpn bash -c "cat /opt/Dockovpn/config/push-routes.conf >> /opt/Dockovpn/config/server.conf"make verify-vpn-config SERVER=<container_name>This checks:
- VPN interface creation:
ip addr show tun0- Routing table:
ip route showOutput is formatted for readability.
DATA_DIRis./dataand used for storing client configuration files.CONFIG_DIRis./configand containspush-routes.conf.VPN_SERVERis defaultopenvpn; adjust if container name differs.- Ensure proper network isolation when testing VPN routes.
- Always verify network interfaces and firewall rules after configuration.
- Assign a dedicated private IP for each
ssh-ubuntuserver instead of port mapping. - Add option to load a GUI interface for Ubuntu servers (e.g., lightweight desktop environment).
- Isolate resources (CPU, memory, disk) for each Ubuntu server container to prevent interference.
- Consider automating VPN configuration application after container creation.
- Implement monitoring/logging for each Ubuntu server container.




