Blog

How we solved host VPN conflicts by running OpenVPN inside Docker containers

Diario del capitán, fecha estelar d642.y41/AB

Juan Salvador
Engineering Manager
astronaut code

When your development workflow depends on OpenVPN but your host machine is forced to run a corporate VPN, things can get complicated fast. Host-level VPN software often takes over routing rules, intercepts private networks, and breaks access to remote development services, even when your OpenVPN configuration is correct.

Our team faced this exact issue. Instead of fighting with the host VPN client, we chose a better alternative: we moved the OpenVPN connection inside our Docker development containers.

This article explains the problem, the reasoning, and the complete solution, step by step.

Why host-level VPNs break Docker-based development

Modern corporate VPN clients often enforce strict security policies. They often:

  • Override routing tables globally.
  • Capture private CIDR ranges (especially 10.0.0.0/8).
  • Redirect internal traffic through themselves.
  • Block route additions from other VPN clients.
  • Interfere with Docker bridged networking.

Our development environment relied on OpenVPN to reach remote services. The OpenVPN client could still “connect”, but the host VPN silently hijacked traffic and routed it through its own tunnel instead. OpenVPN showed as connected, but the dev environment was unreachable.

The solution: run OpenVPN inside Docker, not on the host

Here’s the key insight: Docker containers run in their own network namespaces. That means host VPN routing rules don’t affect container routing.

By moving OpenVPN into the container:

  • Host VPN policies cannot override it.
  • Each service gets an isolated VPN tunnel.
  • No host OS hacks or route overrides are needed.
  • Developers can still keep the required corporate VPN active on the host.
  • The VPN configuration becomes reproducible and version-controlled.

This technique cleanly separates host networking (corporate VPN) from development networking (OpenVPN inside Docker), creating a stable and conflict-free environment.

How we built container-level OpenVPN support

1. Install OpenVPN inside the development image

First, ensure the package is available in your Dockerfile:

	RUN apt-get install -yqq ... openvpn
	RUN mkdir -p /opt/openvpn && chown -R user:user /opt/openvpn
	

2. Give the container NET_ADMIN capabilities

OpenVPN needs privileges to create tun devices. In your docker-compose.yml:

	privileged: true
	cap_add:
		- NET_ADMIN
		

3. Mount .ovpn config files into the container

Developers store VPN files under .dockerdev/ovpn/:

	volumes:
		- ./ovpn:/opt/openvpn

Make sure these files are ignored by Git.

	*.ovpn
	

4. Add an entrypoint script that auto-starts OpenVPN

	OPEN_VPN_CONFIG=/opt/openvpn/$CUSTOMER_NETWORK.ovpn

	if [ -f "$OPEN_VPN_CONFIG" ]; then
		echo "Connecting with VPN"
		sudo openvpn --daemon --log-append /var/log/openvpn/openvpn.log --config $OPEN_VPN_CONFIG
	fi

	exec "$@"
	

The container checks the selected network and launches OpenVPN automatically.

5. Select the VPN profile using an environment variable

	CUSTOMER_NETWORK: dev-eu-west-3

The value must match an existing .ovpn file:

	dev-eu-west-3.ovpn

Developer setup: step-by-step

Once the infrastructure is in place, the developer workflow is simple:

Rebuild the containers:

	bin/dockerdev setup

Add your .ovpn files:

	Place them in .dockerdev/ovpn/dev-eu-west-3.ovpn

Copy the override template:

	cd .dockerdev
	cp compose.override.yml.sample compose.override.yml

Edit as needed setting the CUSTOMER_NETWORK environment variable to the right VPN name.

Start development services: bin/dockerdev start server

	bin/dockerdev start server

If an OpenVPN profile exists, the VPN starts inside the container automatically.

Why this approach works so well

Running OpenVPN inside Docker gives you:

✅ No more routing conflicts.

✅ Clean separation between host and development networks.

✅ Predictable and isolated development routing.

✅ Zero host OS changes.

✅ Faster onboarding for developers.

✅ A fully reproducible environment.

✅ Reliable access to cloud services behind OpenVPN.

This architecture dramatically improved our development workflow, and it’s a pattern any remote-friendly or cloud-based team can benefit from.

Compartir este post

Artículos relacionados

How I use Docker for Rails development: running services

How I use Docker for Rails development: running services

Project setup can be a very cumbersome process for developers. In this blog post, our developer Dani explains how he uses Docker to develop in Rails

Leer el artículo
Rust for NodeJS developers (III) - Docker development environment

Rust for NodeJS developers (III) - Docker development environment

Learn how to use Docker for local Rust API development. Containerisation ensures a consistent, isolated environment across all team members' machines.

Leer el artículo