There are some Docker containers running services that I want to make sure use a privacy VPN. For example, SearXNG.
One of the main reasons to use a self-hosted meta search engine like SearXNG is to protect your privacy. SearXNG protects privacy in several ways:
- Doesn't send cookies to the external search engines it uses
- Generates a random browser profile for every search
- Doesn't serve ads, so no third-party tracking
- Hides the referring page and search query from the page you visit
However, when SearXNG pings all of the external search engines you choose, it's still using the IP address of the instance.
I use Tailscale with Mullvad exit nodes for my privacy VPN needs. I have SearXNG installed in a Docker container. Here's how to tell that container (or any container you want) to use a Mullvad exit node with docker-compose.
Basically, you're going to be adding a Tailscale sidecar to whatever container your service is in. Then you're going to tell that Tailscale sidecar to use an exit node using TS_EXTRA_ARGS=-exit-node=IP_OF_EXIT_NODE.
services:
redis:
container_name: redis
image: docker.io/valkey/valkey:8-alpine
command: valkey-server --save 30 1 --loglevel warning
restart: unless-stopped
network_mode: service:ts-searxng
depends_on:
- ts-searxng
volumes:
- valkey-data2:/data
logging:
driver: "json-file"
options:
max-size: "1m"
max-file: "1"
# Here's the Tailscale sidecar
ts-searxng:
container_name: ts-searxng
image: tailscale/tailscale:latest
hostname: searxng
restart: unless-stopped
volumes:
- "/volume1/docker/ts-searxng/state:/var/lib/tailscale"
devices:
- /dev/net/tun:/dev/net/tun
cap_add:
- net_admin
- sys_module
environment:
- TS_AUTH_KEY=AUTH_KEY
- TS_STATE_DIR=/var/lib/tailscale
- TS_USERSPACE=false
- TS_EXTRA_ARGS=--exit-node=IP_OF_EXIT_NODE --exit-node-allow-lan-access=true --reset
- TS_TAILSCALED_EXTRA_ARGS=--no-logs-no-support
searxng:
container_name: searxng
image: docker.io/searxng/searxng:latest
restart: unless-stopped
network_mode: service:ts-searxng
depends_on:
- ts-searxng
# ports:
# - "127.0.0.1:8080:8080"
volumes:
- ./searxng:/etc/searxng:rw
- searxng-data:/var/cache/searxng:rw
environment:
- SEARXNG_BASE_URL=https://searxng.mydomain.com
logging:
driver: "json-file"
options:
max-size: "1m"
max-file: "1"
volumes:
valkey-data2:
searxng-data:
ts-searxng:
driver: local
Just a few more things to note.
One, you obviously need to pay for and have Mullvad exit nodes enabled in Tailscale.
Two, after you add the Tailscale sidecar, your container will be a new "machine" on your Tailnet, and you'll have to add that machine to your list of devices that have Mullvad access in your Tailscale settings.
And three, here's how you can find the IP addresses of all your Mullvad exit nodes in Tailscale. Assuming you have a shell open in your Tailscale container, just run tailscale exit-node list. That's what you'll put in TS_EXTRA_ARGS=--exit-node=IP_OF_EXIT_NODE.
Confirming the exit node is actually being used
You can confirm your container is using the exit node in a couple ways. For containers that can run curl, you can use sudo docker exec CONTAINER_NAME apk add curl && curl https://ifconfig.co/json.
SearXNG doesn't let you install or use curl, so I typically use wget -qO- https://ifconfig.me/ip | cat to get the IP the container is using.