A friend of mine wanted to make one of their docker containers go through Wireguard to connect to Internet. I came up with a solution using a docker container to manage the wireguard VPN itself. This allows us to fully isolate the VPN, and use AllowedIPs=0.0.0.0/0 without affecting the rest of the system.

This solution is both simple technically (we just share the network stack (namespaces)) and in usage (just add another container, without even changing the original).

services:
  # The application that will use Wireguard for its connections
  myapp:
    container_name: myapp
    image: nginx:latest

  # Wireguard container that shares the same network stack, to inject the Wireguard routing rules into your app
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE #optional
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - ./wg0.conf:/config/wg_confs/g0.conf:ro
      - /lib/modules:/lib/modules #optional
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped
    network_mode: container:myapp # This is the magic trick to make the containers share the network stack

You need to add a wg0.conf file in the same directory as your docker-compose.yml file, with AllowedIPs=0.0.0.0/0

You can verify that this works by running wg, ip a, curl ip.me in the wireguard container.