# docker-ipsec-vpn-server: Self-Hosted IPsec VPN in a Single Docker Container

> hwdsl2/docker-ipsec-vpn-server is a Docker image that sets up a complete IPsec VPN server supporting IKEv2, Cisco IPsec, and IPsec/L2TP, auto-generating credentials and client profiles on first start from a 19 MB Alpine-based image.

**hwdsl2/docker-ipsec-vpn-server** — Docker image to run an IPsec VPN server, with IPsec/L2TP, Cisco IPsec and IKEv2. Auto-generates server config and supports VPN client setup on Linux, Windows, macOS, iOS and Android.

- Repository: https://github.com/hwdsl2/docker-ipsec-vpn-server
- Website: https://hub.docker.com/r/hwdsl2/ipsec-vpn-server
- Stars: 7,143 · Forks: 1,464
- Language: Shell
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/hwdsl2-docker-ipsec-vpn-server

## What This Image Solves and Who Uses It

IPsec VPN servers are complex to configure from scratch. Libreswan, xl2tpd, IKEv2 certificates, and firewall rules each require separate setup, and a misconfiguration in any layer leaves the VPN non-functional. docker-ipsec-vpn-server wraps all of that into a single container that generates credentials and server configuration automatically on first start.

The README states the core use case: "An IPsec VPN encrypts your network traffic, so that nobody between you and the VPN server can eavesdrop on your data as it travels via the Internet. This is especially useful when using unsecured networks, e.g. at coffee shops, airports or hotel rooms."

The image targets engineers who run Linux servers with a public IP and want a portable, self-hosted VPN without maintaining a bare-metal configuration. It supports VPN clients on Windows, macOS, iOS, Android, Chrome OS, and Linux.

## How It Works: Libreswan, xl2tpd, and Three Protocol Modes

The Alpine-based image builds Libreswan 5.4 from source during the Docker build. Libreswan handles the IPsec layer. xl2tpd handles the L2TP daemon for the IPsec/L2TP mode. The image supports three distinct VPN protocols: IPsec/L2TP (for older clients), Cisco IPsec (for macOS and iOS native VPN clients), and IKEv2 (the recommended mode with strong ciphers like AES-GCM).

On first container start, the image auto-generates VPN credentials (PSK, username, password) if none are provided via environment variables. For IKEv2, it also generates the server certificate and a client configuration profile. These generated files are stored in the ikev2-vpn-data Docker volume mounted at /etc/ipsec.d, so they persist across container restarts.

The image is available in two variants. The default Alpine-based image compresses to approximately 19 MB. A Debian-based alternative tagged as hwdsl2/ipsec-vpn-server:debian compresses to approximately 62 MB. Both run Libreswan 5.4 and support the same protocol modes. Neither is compatible with Synology NAS systems.

Multi-architecture builds cover linux/amd64, linux/arm64, and linux/arm/v7.

## Quick Start and First Connection

A single docker run command starts a VPN server with randomly generated credentials:

```bash
docker run \
    --name ipsec-vpn-server \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

The container requires privileged mode because it manages iptables rules and network interfaces inside the container. The /lib/modules volume is mounted read-only so the container can load the required kernel modules on the host.

Or pull the image first:

```bash
docker pull hwdsl2/ipsec-vpn-server
```

Credentials are generated randomly on first start. After the container starts, the VPN login details can be retrieved from the container logs.

For teams using docker-compose, the repository ships a docker-compose.yml. Create a vpn.env file with your chosen credentials:

```
VPN_IPSEC_PSK=your_ipsec_pre_shared_key
VPN_USER=your_vpn_username
VPN_PASSWORD=your_vpn_password
```

The docker-compose.yml mounts this file as env_file, binds UDP 500 and 4500, mounts the ikev2-vpn-data volume at /etc/ipsec.d, and sets the container name to ipsec-vpn-server with restart=always.

## IKEv2 Client Profiles and the Helper Script

IKEv2 is the strongest and fastest of the three supported protocol modes. The image auto-generates an IKEv2 client configuration on first start, and the README states that this configuration can auto-configure iOS, macOS, and Android devices by importing the generated profile.

A helper script is included in the image to manage IKEv2 users and certificates. This script handles adding, removing, and listing IKEv2 client certificates without requiring manual interaction with the Libreswan configuration files.

For IPsec/L2TP mode, the README notes that macOS users may need to restart the container once with `docker restart ipsec-vpn-server` before using that mode. Docker for macOS is supported for advanced users only, and Docker for Windows is explicitly not supported by this image.

## Environment Variables and Credential Management

All configuration variables are optional. Without any environment file, the container generates random credentials. To specify credentials, create a vpn.env file based on the example in the repository:

```
VPN_IPSEC_PSK=your_ipsec_pre_shared_key
VPN_USER=your_vpn_username
VPN_PASSWORD=your_vpn_password
```

Multiple VPN users are supported by declaring additional users in the env file. The README states that usernames and passwords must be separated by spaces and usernames cannot contain duplicates. All VPN users share the same IPsec PSK.

Credentials and IKEv2 certificate data are persisted in the ikev2-vpn-data volume at /etc/ipsec.d. This means deleting the container does not lose the VPN credentials or certificates as long as the named volume is not removed.

## Limitations and Cases Where This Image Is the Wrong Tool

This image requires a Linux server with a public IP address and open UDP ports 500 and 4500. It does not work on Docker for Windows. On macOS Docker Desktop, IPsec/L2TP mode requires a container restart workaround and general support is limited to advanced users only.

IPsec/L2TP is an older protocol combination. L2TP traffic has higher overhead than IKEv2. For clients that support IKEv2, the README recommends that mode over IPsec/L2TP.

The container requires --privileged to manage iptables and network interfaces. This is a significant security consideration in environments where container privilege escalation is a threat model concern. The README provides no option to run without privileged mode.

The Synology NAS platform is explicitly listed as incompatible with both the Alpine and Debian variants.

For teams that want WireGuard instead of IPsec, the same repository author maintains a separate docker-wireguard image, listed in the README under "Also available."

## Maintenance, License, and Alternatives

The repository is not archived. The last push was on 2026-09-21. The Dockerfile shows the Alpine base as version 3.23 and Libreswan version 5.4. GitHub Actions workflows build and publish the images automatically.

The license is listed as NOASSERTION in the repository metadata. The Dockerfile header states the work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License, with attribution required. This is an unusual license choice for infrastructure tooling and differs from the typical MIT or Apache-2.0 licenses common in this space. Teams with strict license requirements should review the full LICENSE.md in the repository before deploying in a production environment.

For a VPN that does not use Docker, the same author provides setup-ipsec-vpn, a set of scripts for bare-metal installation. For WireGuard, the docker-wireguard and docker-headscale repositories from the same author are listed as alternatives.

## Conclusion

docker-ipsec-vpn-server is the right choice for engineers who need a self-hosted VPN on a Linux server with a public IP and want it running in under five minutes. It is not suitable for macOS Docker Desktop (the README explicitly excludes Docker for Windows and notes macOS limitations), for Synology NAS systems (incompatible per the image comparison table), or for teams that need WireGuard instead of IPsec. Before deploying, confirm that UDP ports 500 and 4500 are open in the host firewall and that the server has a public IP address or DNS name, as the README lists both as hard requirements.

## FAQ

### How do I create an IPsec VPN server with this Docker image?

Run `docker run --name ipsec-vpn-server --restart=always -v ikev2-vpn-data:/etc/ipsec.d -v /lib/modules:/lib/modules:ro -p 500:500/udp -p 4500:4500/udp -d --privileged hwdsl2/ipsec-vpn-server`. The image auto-generates credentials on first start; the VPN login details are retrievable from the container logs.

### Does Docker work with VPN when using this image?

Yes, the image is designed to run an IPsec VPN server inside Docker on Linux hosts. It requires UDP ports 500 and 4500 open in the firewall, a public IP address on the server, and the container to run in privileged mode. Docker for Windows is not supported.

### What is the difference between IKEv2 and IPsec/L2TP in this image?

The image supports three modes: IKEv2, Cisco IPsec, and IPsec/L2TP. IKEv2 uses strong ciphers such as AES-GCM and is recommended for clients that support it. IPsec/L2TP is an older combination with higher overhead, included for compatibility with clients that do not support IKEv2.

## Sources

- [hwdsl2/docker-ipsec-vpn-server on GitHub](https://github.com/hwdsl2/docker-ipsec-vpn-server)
- [Issues](https://github.com/hwdsl2/docker-ipsec-vpn-server/issues)
- [Project website](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server)
- [README](https://github.com/hwdsl2/docker-ipsec-vpn-server/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/hwdsl2-docker-ipsec-vpn-server
