docker.automation.openvpn is a portable lab environment that can be deployed on cloud or on-premise servers. It provisions containerized services, including a browser-based IDE and a container management dashboard, all secured via OpenVPN.
- Deployable on both cloud and on-premise servers
- OpenVPN-secured access to all lab services, powered by
kylemanna/docker-openvpn - Provisions a browser-based IDE (
lscr.io/linuxserver/code-server) - Includes a container management dashboard (
portainer/portainer) - Automated setup via
init.sh— pulls images, builds the OpenVPN network stack, and attaches all containers to it newclient.shgenerates.ovpnfiles for new VPN usersremoveserver.shremoves all containers, networks, and volumes created by the provisioner- Portable — recreate an identical lab environment quickly when needed
All lab services run inside Docker and share a private, OpenVPN-managed network. No service is publicly exposed to the internet — access is restricted to VPN-connected clients only.
[VPN Client]
│ (OpenVPN connection)
▼
[OpenVPN Container] <---> [code-server IDE]
│ [Portainer Dashboard]
│ [Additional Lab Tools...]
(Custom Docker Network)
Flow:
- A user connects to the server via the
.ovpnprofile generated bynewclient.sh. - OpenVPN routes the client’s traffic into the private Docker network.
- The client can securely access the IDE, Portainer, and any other lab services — without any public-facing ports.
The code-server container has access to the host Docker daemon through:
/var/run/docker.sock:/var/run/docker.sock
This allows the IDE to manage containers directly on the host machine, giving you full control over your lab environment from within the browser.
- Server OS: Tested on Ubuntu 24.04 LTS
- Docker: Latest ARM-compatible version (tested following Docker’s ARM on Linux guide) — works on x86_64 as well
- docker-compose: Installed and in
$PATH - Root access (or user in the
dockergroup) - OpenVPN client on your local machine to connect after provisioning
- Required packages:
git,docker,ipcalc(the `` script will check for these and warn if missing)
Note:
- Cloud VM must allow inbound traffic on the chosen VPN port (default:
1194/udp). - Recommended to use a fresh server to avoid conflicts with existing Docker containers or networks.
- Clone this repository to your server:
git clone https://github.com/nrobbyjay/docker.automation.openvpn.git
cd docker.automation.openvpn- Initialize the environment (build network, pull images, start containers):
./init.sh- Pulls required Docker images
- Prompts for OpenVPN server setup (CA key, hostname, confirmation prompts — see kylemanna/docker-openvpn guide)
- Creates OpenVPN network stack (
ovpn_net) - Attaches
code-server,Portainer, and other services to the VPN network - Creates persistent Docker volumes
Tip: Keep port 22 open initially so you can SCP the generated .ovpn files to your local machine. You may close it later if you only want VPN access.
- Generate a VPN client profile:
./newclient.sh- Enter a client name when prompted
- The
.ovpnfile will be saved in the server’s home directory - Securely copy it to your local machine using
scpor another secure method
- Find service IPs on the VPN network:
docker network inspect ovpn_net
docker inspect <container_name> | grep "IPAddress"-
Use these IPs to access services after connecting via VPN
-
Example:
- Code Server IDE:
https://<container-ip>:8443 - Portainer Dashboard:
https://<container-ip>:9443
- Code Server IDE:
- Remove the environment (if needed):
./removeserver.sh- Deletes all containers, networks, and volumes created by this project
External Access:
- VPN Port:
1194/udp(default, can be changed during setup) - SSH Port:
22/tcp(optional — only needed temporarily for initial SCP transfer)
Internal Access (via VPN):
- Code Server IDE:
8443/tcp - Portainer Dashboard:
9443/tcp - Additional tools use dynamically assigned ports on
ovpn_net
Key Points:
- No services are exposed to the public internet — VPN access is mandatory
- Container IPs are dynamic: inspect network and containers using Docker commands
- All containers are attached to
ovpn_net
-
VPN-Only Access: All services are accessible only through OpenVPN. No containers expose public ports by default
-
Dynamic IPs: Containers use a private, dynamically assigned IP on
ovpn_net -
Credentials:
code-serverandPortainerdo not have preconfigured passwords- Keep
.ovpnclient files secure
-
SSH Port: Only required temporarily; close after setup for full VPN isolation
-
Portable & Reproducible: Can remove everything with
removeserver.shand redeploy quickly
- Only
code-serverandPortainerare provisioned; other tools can be added later - OpenVPN setup prompts are manual; could be automated in the future
- Container IPs are dynamic; future improvements could include fixed subnets or hostnames
- No preconfigured IDE or dashboard settings; users must set credentials manually
- Only single-host deployment; multi-host/swarms are not yet supported