krz/skunky-art

Alternative privacy frontend for DeviantArt.

clone: git clone https://gitbay.org/krz/skunky-art.git

v1.3.5: compose.vpn_example.yml · raw

 1# SkunkyArt + optional VPN egress, in a single stack.
 2#
 3# Why: DeviantArt's API (AWS CloudFront + WAF) blocks some egress IPs on the
 4# /_puppy path, which makes every DA-backed page fail with
 5# `invalid character '<' looking for beginning of value` (Go trying to
 6# json.Unmarshal a CloudFront HTML 403 page). Routing SkunkyArt's outbound
 7# through a non-blocked VPN exit fixes it without any code change: devianter's
 8# HTTP client honors HTTPS_PROXY/HTTP_PROXY.
 9#
10# The VPN sidecar (gluetun) is OPTIONAL — it only starts under the "vpn" profile.
11# With the profile off, SkunkyArt runs exactly as the stock compose.yaml (direct).
12#
13# The VPN provider is YOUR choice: gluetun supports AirVPN, Mullvad, ProtonVPN,
14# PIA, and many others. Set VPN_SERVICE_PROVIDER and supply that provider's
15# required settings. Provider list + required variables:
16#   https://github.com/qdm12/gluetun-wiki
17#
18# ---------------------------------------------------------------------------
19# Setup:
20#   1. Copy this file to compose.yaml (or run with `-f compose.vpn_example.yml`).
21#   2. Create a .env next to it (and `echo ".env" >> .gitignore`):
22#
23#        # toggle VPN: uncomment both to route SkunkyArt through the VPN
24#        #COMPOSE_PROFILES=vpn
25#        #SKUNKY_PROXY=http://gluetun:8888
26#
27#        # pick your provider (see the gluetun wiki for the exact name/vars)
28#        VPN_SERVICE_PROVIDER=airvpn
29#        VPN_TYPE=wireguard
30#
31#        # WireGuard credentials (from your provider's config generator)
32#        VPN_PRIVATE_KEY=<[Interface] PrivateKey>
33#        VPN_PRESHARED_KEY=<[Peer] PresharedKey>   # optional; some providers omit it
34#        VPN_ADDRESSES=<[Interface] Address, e.g. 10.128.x.x/32>
35#        VPN_COUNTRIES=Netherlands
36#        TZ=America/Chicago
37#
38#   3. VPN on:  uncomment the two toggle lines, then `docker compose up -d`.
39#      VPN off: leave them commented, then `docker compose up -d`.
40#
41# Verify an exit is not blocked BEFORE trusting it:
42#   curl -x http://127.0.0.1:8888 -s -o /dev/null -w "%{http_code}\n" \
43#     "https://www.deviantart.com/_puppy/dabrowse/networkbar/rfy/deviations?page=0"
44#   400 (JSON "csrf: missing") = clean exit.  403 (text/html) = blocked, rotate servers.
45# ---------------------------------------------------------------------------
46
47services:
48  skunkyart:
49    container_name: skunkyart
50    restart: unless-stopped
51    # Published multi-arch image; pin a release tag (e.g. :1.3.3) for
52    # reproducible upgrades. To build from this checkout instead, comment out
53    # `image:` and uncomment `build:`, then `docker compose up -d --build`.
54    image: ghcr.io/zerolabsco/skunky-art:latest
55    #build: .
56    ports:
57      - "127.0.0.1:3003:3003"
58    security_opt:
59      - no-new-privileges:true
60    volumes:
61      - ./config.json:/config.json:ro
62      - ./cache:/cache            # ensure this dir is owned 10000:10000
63    environment:
64      # Empty by default = direct. Set SKUNKY_PROXY in .env to route via the VPN.
65      - HTTPS_PROXY=${SKUNKY_PROXY:-}
66      - HTTP_PROXY=${SKUNKY_PROXY:-}
67      - NO_PROXY=localhost,127.0.0.1
68    depends_on:
69      gluetun:
70        condition: service_healthy
71        required: false           # optional dep: skunky still starts if gluetun is off
72                                  # (needs Docker Compose v2.20+; drop this block on older)
73
74  # --- optional VPN egress: only starts with the "vpn" profile ---
75  gluetun:
76    image: qmcgaw/gluetun:latest
77    container_name: gluetun-skunky
78    profiles: ["vpn"]
79    cap_add:
80      - NET_ADMIN
81    devices:
82      - /dev/net/tun:/dev/net/tun
83    ports:
84      - "127.0.0.1:8888:8888"     # host-side, only for testing the proxy
85    environment:
86      # Provider + tunnel type — your choice (see gluetun wiki).
87      - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER:-}
88      - VPN_TYPE=${VPN_TYPE:-wireguard}
89      # WireGuard credentials (leave PRESHARED empty if your provider omits it).
90      - WIREGUARD_PRIVATE_KEY=${VPN_PRIVATE_KEY:-}
91      - WIREGUARD_PRESHARED_KEY=${VPN_PRESHARED_KEY:-}
92      - WIREGUARD_ADDRESSES=${VPN_ADDRESSES:-}
93      - SERVER_COUNTRIES=${VPN_COUNTRIES:-}
94      - HTTPPROXY=on              # built-in HTTP proxy on :8888
95      - TZ=${TZ:-Etc/UTC}
96      # If skunky can't reach the proxy while gluetun is healthy, uncomment to let
97      # gluetun's firewall accept the docker network:
98      # - FIREWALL_OUTBOUND_SUBNETS=172.16.0.0/12
99    restart: unless-stopped