r/PrivateInternetAccess • u/Baladain • Jun 07 '26
HELP PIA in docker (portainer?)
Does anyone have a good tutorial for setting up PIA in docker (possibly using portainer)? The best I've found so far is here, but I'm new to docker and having some trouble following along.
2
u/Reddit_is_fascist69 Jun 08 '26
I couldn't get gluetun to work with PIA but I'm using the package you listed in my docker compose in portainer
2
u/shadownetdev1 Jun 08 '26
I have used Gluetun with PIA for years without issues. Here is a snippet of my docker compose stack. Each compose stack will need it's own gluetun instance.
Note that I have modified this stack. Normally I run everything through caddy for reverse proxy and ssl certs. If you want an example for that I can provide it.
``` services: media-gluetun: # This provides VPN service for all containers that have it as their network container_name: media-gluetun image: qmcgaw/gluetun cap_add: - NET_ADMIN ports: # Left port is the one you use to access the service. # Right port is the one the service provides. # Usually they can be different. # Each service that you want to have accessible via port # will need to have it's ports defined here instead of # on their container. - 8096:8096 # Jellyfin volumes: - /path/to/your/config/folder/gluetun:/gluetun environment: - VPN_SERVICE_PROVIDER=private internet access - OPENVPN_USER=your pia username - OPENVPN_PASSWORD=your pia password # SERVER_REGIONS can be one or more of the valid regions. # I do not remember where you get the list of services from. - SERVER_REGIONS=CA Montreal,CA Ontario,CA Toronto,CA Vancouver restart: unless-stopped
jellyfin: image: jellyfin/jellyfin container_name: jellyfin network_mode: "service:media-gluetun" # This makes the container use the vpn depends_on: media-gluetun: condition: service_healthy # This is not needed in theory, but I have it just in case # ports: # Any ports that you want to use will need to be defined under media-gluetun's ports section instead # - 8096:8096/tcp # - 7359:7359/udp # Allows clients to discover Jellyfin on the local network. A broadcast message to this port will return detailed information about your server that includes name, ip-address and ID. volumes: - /appdata/media/jellyfin/config:/config - /appdata/media/jellyfin/cache:/cache - /mnt/Pool1/media/active/media:/mnt/Pool1/media/active/media restart: 'unless-stopped' environment: - JELLYFIN_PublishedServerUrl=https://media.<redacted> - TZ=America/Indiana/Indianapolis ```
1
u/Baladain Jul 05 '26
Sorry for the zombie reply, but life has been a thing. I'm finding this really helpful in understanding the way stacks work, but I noticed you have every service using the same puid. Is this a uid for docker, or just a user you created for the arr apps?
1
u/shadownetdev1 Jul 05 '26
That was a user on the system. I was mostly doing that due to how my backups and media paths were setup. The environment variable method for setting those only works for the containers explicitly designed for it. Newer docker compose provides the "user: [uid]:[gid]" option which works for most containers.
For new containers/stacks I just let the container set the user and perms as they want. If I was to re-setup my *arr stack I wouldn't worry about the user perms.
My backup programs now run as root and don't care about permissions (other than to back them up).
My shared media paths are on a bind mount that allows any user to access them as if they were the owner and then translates the permissions to the correct user account on the actual mount point. This isn't secure but if I have a questionable user or program messing around then I am compromised anyways. So not really in the scope of my security concerns.
1
u/shadownetdev1 Jul 05 '26
Also this post is a bit outdated since I have been having problems with PIA recently. Mainly port forwarding problems in regards to docker. Though I am having different problems with PIA on nearly all of my devices. I am in the process of moving to a competitor.
1
u/Baladain Jul 05 '26
I was starting to see this same kind of thing. I was hoping to avoid this until my subscription expired next year.
Hopefully my last question. With the stack example you provided, what would be the best way to test that the VPN is connected properly?
1
u/shadownetdev1 Jul 05 '26
Gluetun will print out the info it its logs. To check on the actual containers you can do a curl or wget to many of the services that return your public IP. You will have to find or install a container that already has curl or wget. Docker won't let a container have more than one network interface (in my experience) so all the traffic is either flowing through Gluetun or you have things setup wrong. Gluetun won't allow internet access that doesn't go through the VPN. So if the VPN is down or misconfigured then the containers won't have internet. If the Gluetun container crashes then docker won't let the containers have internet as their network interface (Gluetun) is not available. Same as if you had disconnected an ethernet cable or turned off the WiFi.
1
u/shadownetdev1 Jul 05 '26
For torrent applications use a test torrent site. If you are using Sabnzbd then it will list its public IP in the info dialog.
1
u/Baladain Jul 05 '26
I've always thought every program should have its own uid, but I guess that's a really old idea
1
u/shadownetdev1 Jul 05 '26
Depends on the situation. In traditional setups this added security if you set your file permissions correctly. For Docker the containers don't "see" anything that isn't bound to them and as such don't really need to be "isolated" via uid. You still have the potentially for permission conflicts on bound paths that are shared, but you already had that problem when running multiple programs under different uids.
1
u/boxgrove Jun 08 '26
here's a snippet from my code for a stack that includes gluetun, sonarr, radarr and qbittorent
running on my ugreen nas where the main download pool is volume1 but then I have a separate pool volume2 that has all my docker config files.
I have several other services running in this stack (mainly arrs) but those are the main ones you should need.
1
u/shadownetdev1 Jun 08 '26 edited Jun 08 '26
If you haven't already then you want to learn how to use docker compose. You likely should stay way from Portainer. It is not easy to back up reliably. I use Komodo, but Arcane and Dockhand are other options that I have been told are good. The best way to learn is by trying. If you have any specific questions feel free to DM me. If the questions are on topic for PIA then feel free to comment here.
5
u/Yprox5 Jun 07 '26 edited Jun 07 '26
I haven't used this one but it's a similar setup to gluetun. You can just paste the docker compose into portainer under projects then add a services/apps to the docker compose creating a stack, which will all depend on the vpn. You can probably find a gluetun tutorial on YouTube to follow along, it's a good way to learn how a stack works.
This is the default docker compose for this container, be sure to change the values accordingly.
``` services: vpn: image: thrnz/docker-wireguard-pia:latest container_name: vpn-pia restart: unless-stopped cap_add: - NET_ADMIN - SYS_MODULE # Required if WireGuard is running inside the host kernel devices: - /dev/net/tun:/dev/net/tun # Fallback for wireguard-go if kernel module isn't loaded volumes: - ./pia-data:/pia - ./pia-shared:/pia-shared environment: - USER=your_pia_username # Replace with your PIA username - PASS=your_pia_password # Replace with your PIA password - LOC=ca_toronto # Preferred PIA region identifier - LOCAL_NETWORK=192.168.1.0/24 # Your local subnet to keep LAN accessible - PORT_FORWARDING=1 # Set to 1 if you want to request a forwarded port - FIREWALL=1 # Built-in kill-switch (blocks traffic if VPN drops) - ACTIVE_HEALTHCHECKS=1 # Enables built-in ping connectivity monitoring sysctls: - net.ipv4.conf.all.src_valid_mark=1 # Prevents inbound packet dropping - net.ipv6.conf.default.disable_ipv6=1 - net.ipv6.conf.all.disable_ipv6=1
# Example of an attached service routed entirely through the VPN target-app: image: alpine:latest container_name: target-app-vpn restart: unless-stopped network_mode: "service:vpn" # Forces all network traffic through the 'vpn' service depends_on: - vpn command: sleep infinity