How make openvpn work with docker

You can also get docker-compose working if you define the subnet CIDR in your docker compose file:

networks:
  your-network:
   ipam:
      config:
      - subnet: 172.16.238.0/24
        gateway: 172.16.238.1

Another option: create first the network with the subnet CIDR and then specify in the docker compose file that you want to use this network:

docker network create your-network --subnet 172.24.24.0/24

In your docker compose file:

networks:
  your-network:
    external: true

Based on answer from Anas El Barkani, here's a complete step-by-step example using PostgreSQL.

While VPN is not connected, create a permanent docker network:

docker network create my-network --subnet 172.24.24.0/24

In docker-compose file, specify network as external:

version: "2"
services: postgres: container_name: postgres image: postgres volumes: - ./volumes/postgres/data:/var/lib/postgresql/data environment: - POSTGRES_DB=dummy - POSTGRES_USER=user - POSTGRES_PASSWORD=123456 - POSTGRES_HOST=localhost networks: - default ports: - "127.0.0.1:5432:5432"
networks: default: external: name: my-network

That's all. Now you can enable your VPN, and start/stop container as usual:

docker-compose up -d
docker-compose down

No need to turn VPN on/off every time, or to add weird scripts as root.


Solution (TL;DR;)

Create /etc/openvpn/fix-routes.sh script with following contents:

#!/bin/sh

echo "Adding default route to $route_vpn_gateway with /0 mask..."
ip route add default via $route_vpn_gateway

echo "Removing /1 routes..."
ip route del 0.0.0.0/1 via $route_vpn_gateway
ip route del 128.0.0.0/1 via $route_vpn_gateway

Add executable bit to the file: chmod o+x /etc/openvpn/fix-routes.sh. Change owner of this file to root: chown root:root /etc/openvpn/fix-routes.sh.

Add to your config following two lines:

 script-security 2
 route-up  /etc/openvpn/fix-routes.sh

Explanation

Openvpn adds routes that for following networks: 0.0.0.0/1 and 128.0.0.0/1 (these routes cover entire IP range), and docker can't find range of IP addresses to create it's own private network.

You need to add a default route (to route everything through openvpn) and disable these two specific routes. fix-routes script does that.

This script is called after openvpn adds its own routes. To execute scripts you'll need to set script-security to 2 which allows execution of bash scripts from openvpn context.

Thanks

I'd like to thank author of this comment on github, also thanks to ovpn support.