Run OpenVPN in Docker in 2 seconds

  • Tutorial
Hello, Khabrovsk citizens! Have you ever encountered a situation where you would really like to virtually travel to another city, country or to another continent? I have such a need quite often, so the possibility of having my own VPN server that can be started anywhere in a couple of seconds was quite acute. In this article I want to talk about my project, which I planned when I was looking for a ready-made solution, in this case, docker an image that would allow you to quickly raise the OpenVPN server, with a minimum of settings and an acceptable level of security.


The ability to run the service on any machine: whether it be a physical server, or a virtual private server, or, at all, the container space inside another container management system - was critical. My gaze immediately fell on the Docker. Firstly, this service is gaining popularity, and therefore, more and more providers provide turnkey solutions with its pre-installation; secondly - there is a centralized repository of images, from where you can download and start the service with a single command in the terminal. The idea that such a project should already exist, visited me and I persistently searched. But, most of the projects that I found were either too cumbersome (it was necessary to create a container for permanent data storage and run the container several times with an application with different parameters), or without sane documentation, or completely abandoned. Not finding anything acceptable, I began work on my project. There were sleepless nights ahead of us studying the documentation, writing code and debugging, but in the end, my service saw the light and played in all the colors of the monochrome LED panel of the router. So please love and favor -Docker-openvpn. I even came up with a logo (above, in front of the cut), but do not judge it strictly, because I am not a designer (already). When I implemented this project, I focused on deployment speed, a minimum of settings and an acceptable level of security. By trial and error, I found the optimal balance of these criteria, although in some places I had to sacrifice the deployment speed for security, and I had to pay portability for a minimum of settings: in the current configuration, the container once created on one server cannot be transferred and run on another. For example, all client and server certificates are generated when the service starts and this takes about 2 seconds. However, the generation of the Defi Hellman file had to be taken out in the build time: it is created during the build of the docker image and can last up to 10 minutes.


To start the service we need a few things:
  1. Server: physical or virtual. Theoretically, you can run in docker-in-docker mode, but I have not conducted extensive testing of this option;
  2. Actually Docker. Many hosting providers provide turnkey solutions with Docker “on board”;
  3. The public IP address.
If all the details are in place, then it remains for us to run the following command in the console of your server:
docker run --cap-add=NET_ADMIN \
-it -p 1194:1194/udp -p 80:8080/tcp \
-e HOST_ADDR=$(curl -s \
An attentive reader could pay attention to the fact that the IP address of the server is determined automatically using . If for some reason this does not work, then you can specify the address manually. If all the previous steps were completed correctly, then we should see something similar in the console:
Sun Jun  9 08:56:11 2019 Initialization Sequence Completed
Sun Jun  9 08:56:12 2019 Client.ovpn file has been generated
Sun Jun  9 08:56:12 2019 Config server started, download your client.ovpn config at
Sun Jun  9 08:56:12 2019 NOTE: After you download you client config, http server will be shut down!
We are close to the goal: now we need to copy (in your case there will be the address of your server) and paste it into the address bar of the browser. After you press Enter, the client.ovpn file will be downloaded, and the http server itself will go into oblivion. If this solution is in doubt, then you can use the following trick: run the previous command and add the zp flags and password. Now, if you paste the generated link into the browser window, you will receive a zip archive with a password. When you have a file with client configuration, you can use any suitable client. I use Tunnelblick for Mac.

Video tutorial

This video tutorial contains detailed instructions for deploying the service on DigitalOcean.
PS If you find this project useful, then please give it an asterisk on the GitHub, fork and tell your friends. Contributors and security audits are also widely welcome. PPS If this article gets to Habr, then I plan to write the following about how I launched docker-in-docker and docker-in-docker-in-docker, for what I did it and what came of it.
  1. Corrected errors in the publication,
  2. Responding to comments, I decided to put this information here: the --privileged flag is needed to work with iptables

  1. Improved image launch command: now it does not require the --privileged flag
  2. Added a link to the Russian-language video guide:

Also popular now: