summaryrefslogtreecommitdiff
path: root/compose.vpn_example.yml
blob: 27cd488115b30e0c2d636fb286e52b5fef5278ec (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# SkunkyArt + optional VPN egress, in a single stack.
#
# Why: DeviantArt's API (AWS CloudFront + WAF) blocks some egress IPs on the
# /_puppy path, which makes every DA-backed page fail with
# `invalid character '<' looking for beginning of value` (Go trying to
# json.Unmarshal a CloudFront HTML 403 page). Routing SkunkyArt's outbound
# through a non-blocked VPN exit fixes it without any code change: devianter's
# HTTP client honors HTTPS_PROXY/HTTP_PROXY.
#
# The VPN sidecar (gluetun) is OPTIONAL — it only starts under the "vpn" profile.
# With the profile off, SkunkyArt runs exactly as the stock compose.yaml (direct).
#
# The VPN provider is YOUR choice: gluetun supports AirVPN, Mullvad, ProtonVPN,
# PIA, and many others. Set VPN_SERVICE_PROVIDER and supply that provider's
# required settings. Provider list + required variables:
#   https://github.com/qdm12/gluetun-wiki
#
# ---------------------------------------------------------------------------
# Setup:
#   1. Copy this file to compose.yaml (or run with `-f compose.vpn_example.yml`).
#   2. Create a .env next to it (and `echo ".env" >> .gitignore`):
#
#        # toggle VPN: uncomment both to route SkunkyArt through the VPN
#        #COMPOSE_PROFILES=vpn
#        #SKUNKY_PROXY=http://gluetun:8888
#
#        # pick your provider (see the gluetun wiki for the exact name/vars)
#        VPN_SERVICE_PROVIDER=airvpn
#        VPN_TYPE=wireguard
#
#        # WireGuard credentials (from your provider's config generator)
#        VPN_PRIVATE_KEY=<[Interface] PrivateKey>
#        VPN_PRESHARED_KEY=<[Peer] PresharedKey>   # optional; some providers omit it
#        VPN_ADDRESSES=<[Interface] Address, e.g. 10.128.x.x/32>
#        VPN_COUNTRIES=Netherlands
#        TZ=America/Chicago
#
#   3. VPN on:  uncomment the two toggle lines, then `docker compose up -d`.
#      VPN off: leave them commented, then `docker compose up -d`.
#
# Verify an exit is not blocked BEFORE trusting it:
#   curl -x http://127.0.0.1:8888 -s -o /dev/null -w "%{http_code}\n" \
#     "https://www.deviantart.com/_puppy/dabrowse/networkbar/rfy/deviations?page=0"
#   400 (JSON "csrf: missing") = clean exit.  403 (text/html) = blocked, rotate servers.
# ---------------------------------------------------------------------------

services:
  skunkyart:
    container_name: skunkyart
    restart: unless-stopped
    # Published multi-arch image; pin a release tag (e.g. :1.3.3) for
    # reproducible upgrades. To build from this checkout instead, comment out
    # `image:` and uncomment `build:`, then `docker compose up -d --build`.
    image: ghcr.io/zerolabsco/skunky-art:latest
    #build: .
    ports:
      - "127.0.0.1:3003:3003"
    security_opt:
      - no-new-privileges:true
    volumes:
      - ./config.json:/config.json:ro
      - ./cache:/cache            # ensure this dir is owned 10000:10000
    environment:
      # Empty by default = direct. Set SKUNKY_PROXY in .env to route via the VPN.
      - HTTPS_PROXY=${SKUNKY_PROXY:-}
      - HTTP_PROXY=${SKUNKY_PROXY:-}
      - NO_PROXY=localhost,127.0.0.1
    depends_on:
      gluetun:
        condition: service_healthy
        required: false           # optional dep: skunky still starts if gluetun is off
                                  # (needs Docker Compose v2.20+; drop this block on older)

  # --- optional VPN egress: only starts with the "vpn" profile ---
  gluetun:
    image: qmcgaw/gluetun:latest
    container_name: gluetun-skunky
    profiles: ["vpn"]
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - "127.0.0.1:8888:8888"     # host-side, only for testing the proxy
    environment:
      # Provider + tunnel type — your choice (see gluetun wiki).
      - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER:-}
      - VPN_TYPE=${VPN_TYPE:-wireguard}
      # WireGuard credentials (leave PRESHARED empty if your provider omits it).
      - WIREGUARD_PRIVATE_KEY=${VPN_PRIVATE_KEY:-}
      - WIREGUARD_PRESHARED_KEY=${VPN_PRESHARED_KEY:-}
      - WIREGUARD_ADDRESSES=${VPN_ADDRESSES:-}
      - SERVER_COUNTRIES=${VPN_COUNTRIES:-}
      - HTTPPROXY=on              # built-in HTTP proxy on :8888
      - TZ=${TZ:-Etc/UTC}
      # If skunky can't reach the proxy while gluetun is healthy, uncomment to let
      # gluetun's firewall accept the docker network:
      # - FIREWALL_OUTBOUND_SUBNETS=172.16.0.0/12
    restart: unless-stopped