├── .gitignore ├── service ├── tor │ ├── run │ └── torrc.base └── privoxy │ ├── run │ └── config ├── .github ├── dependabot.yml └── workflows │ └── build.yml ├── docker-compose.yml ├── Dockerfile.debian ├── Dockerfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/settings.json 2 | -------------------------------------------------------------------------------- /service/tor/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tor -f ./torrc 4 | -------------------------------------------------------------------------------- /service/privoxy/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | privoxy --no-daemon 3 | -------------------------------------------------------------------------------- /service/privoxy/config: -------------------------------------------------------------------------------- 1 | listen-address 0.0.0.0:8118 2 | forward-socks5t / localhost:9050 . 3 | -------------------------------------------------------------------------------- /service/tor/torrc.base: -------------------------------------------------------------------------------- 1 | SOCKSPort 0.0.0.0:9050 2 | ExitPolicy reject *:* 3 | BridgeRelay 0 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | name: torprivoxy 2 | 3 | services: 4 | torprivoxy: 5 | container_name: torprivoxy 6 | environment: 7 | TZ: Europe/Berlin # customize to your own 8 | BRIDGE: |- 9 | obfs4 : cert= iat-mode=0 10 | obfs4 : cert= iat-mode=0 11 | ports: 12 | - 8118:8118 13 | - 9050:9050 14 | image: ghcr.io/avpnusr/torprivoxy:latest 15 | # or image: ghcr.io/avpnusr/torprivoxy:latest-debian 16 | -------------------------------------------------------------------------------- /Dockerfile.debian: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:labs 2 | FROM debian:stable-slim 3 | LABEL maintainer="avpnusr" 4 | ARG TARGETARCH TARGETVARIANT DEBIAN_FRONTEND=noninteractive 5 | 6 | ADD --link service /etc/service/ 7 | 8 | EXPOSE 8118 9050 9 | 10 | RUN CPUARCH=${TARGETARCH}${TARGETVARIANT} \ 11 | && if [ $CPUARCH == "armv6" ]; then export QEMU_CPU="arm1176"; fi \ 12 | && apt update -y && apt upgrade -y && apt -y install privoxy obfs4proxy tor torsocks runit tini curl --no-install-recommends \ 13 | && addgroup --system tordocker \ 14 | && adduser --system tordocker --ingroup tordocker \ 15 | && chown tordocker:tordocker /etc/service \ 16 | && chown -R tordocker:tordocker /etc/service/* \ 17 | && apt autoremove -y && apt-get clean \ 18 | && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* 19 | 20 | 21 | COPY <> /etc/service/tor/torrc 27 | echo "ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy" >> /etc/service/tor/torrc 28 | for TORBRIDGE in \$BRIDGE; do echo "Bridge \${TORBRIDGE}" >> /etc/service/tor/torrc; done 29 | fi 30 | exec "\$@" 31 | EOT 32 | 33 | RUN chmod +x /docker-entrypoint.sh 34 | 35 | HEALTHCHECK --interval=120s --timeout=15s --start-period=120s --retries=2 \ 36 | CMD curl --fail -x http://127.0.0.1:8118 -s 'https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion' -k > /dev/null && echo "HealthCheck succeeded..." || exit 1 37 | 38 | USER tordocker 39 | 40 | ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"] 41 | CMD ["runsvdir", "/etc/service"] 42 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:labs 2 | ARG GO_VERSION="1.25" 3 | FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS obfs4proxy 4 | ARG TARGETPLATFORM TARGETOS TARGETARCH TARGETVARIANT 5 | RUN CPUARCH=${TARGETARCH}${TARGETVARIANT} \ 6 | && if [ $CPUARCH == "armv6" ]; then export QEMU_CPU="arm1176"; fi 7 | ENV GOOS=${TARGETOS} 8 | ENV GOARCH=${TARGETARCH} 9 | ADD https://github.com/Yawning/obfs4.git /app 10 | WORKDIR /app 11 | RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go mod download 12 | RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 go build -ldflags "-s -w" -trimpath -o /app/obfs4proxy ./obfs4proxy 13 | 14 | FROM alpine:3.22 15 | LABEL maintainer="avpnusr" 16 | 17 | ADD --link service /etc/service/ 18 | 19 | EXPOSE 8118 9050 20 | 21 | RUN CPUARCH=${TARGETARCH}${TARGETVARIANT} \ 22 | && if [ $CPUARCH == "armv6" ]; then export QEMU_CPU="arm1176"; fi \ 23 | && apk update --no-cache && apk upgrade -a --no-cache && apk --update --no-cache add privoxy runit tor torsocks tini curl \ 24 | && addgroup -S tordocker \ 25 | && adduser -S tordocker -G tordocker \ 26 | && chown tordocker:tordocker /etc/service \ 27 | && chown -R tordocker:tordocker /etc/service/* 28 | 29 | COPY --link --from=obfs4proxy /app/obfs4proxy/obfs4proxy /usr/bin/obfs4proxy 30 | 31 | COPY <> /etc/service/tor/torrc 37 | echo "ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy" >> /etc/service/tor/torrc 38 | for TORBRIDGE in \$BRIDGE; do echo "Bridge \${TORBRIDGE}" >> /etc/service/tor/torrc; done 39 | fi 40 | exec "\$@" 41 | EOT 42 | 43 | RUN chmod +x /docker-entrypoint.sh 44 | HEALTHCHECK --interval=120s --timeout=15s --start-period=120s --retries=2 \ 45 | CMD curl --fail -x http://127.0.0.1:8118 -s 'https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion' -k > /dev/null && echo "HealthCheck succeeded..." || exit 1 46 | 47 | USER tordocker 48 | 49 | ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"] 50 | CMD ["runsvdir", "/etc/service"] 51 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: TorPrivoxy Docker Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths-ignore: 8 | - '.github/workflows/build.yml' 9 | - 'README.md' 10 | - 'docker-compose.yml' 11 | schedule: 12 | - cron: '12 2 * * 6' 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: define bdate 19 | run: echo "BDATE=$(date +%d-%m-%Y)" >> $GITHUB_ENV 20 | - name: checkout code 21 | uses: actions/checkout@v5 22 | - name: setup qemu 23 | id: qemu 24 | uses: docker/setup-qemu-action@v3 25 | - name: install buildx 26 | id: buildx 27 | uses: docker/setup-buildx-action@v3 28 | with: 29 | version: latest 30 | - name: Log in to the Container registry 31 | uses: docker/login-action@v3 32 | with: 33 | username: ${{ secrets.DOCKER_USERNAME }} 34 | password: ${{ secrets.DOCKER_PASSWORD }} 35 | - 36 | name: Login to GitHub Container Registry 37 | uses: docker/login-action@v3 38 | with: 39 | registry: ghcr.io 40 | username: ${{ github.actor }} 41 | password: ${{ secrets.GITHUB_TOKEN }} 42 | - name: Build and push 43 | uses: docker/build-push-action@v6 44 | with: 45 | context: . 46 | push: true 47 | platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 48 | tags: | 49 | avpnusr/torprivoxy:latest 50 | avpnusr/torprivoxy:${{ env.BDATE }} 51 | ghcr.io/avpnusr/torprivoxy:latest 52 | ghcr.io/avpnusr/torprivoxy:${{ env.BDATE }} 53 | file: Dockerfile 54 | cache-from: type=gha 55 | cache-to: type=gha,mode=max 56 | - name: Build and push debian 57 | uses: docker/build-push-action@v6 58 | with: 59 | context: . 60 | push: true 61 | platforms: linux/amd64,linux/arm/v7,linux/arm/v6,linux/arm64 62 | tags: | 63 | avpnusr/torprivoxy:latest-debian 64 | avpnusr/torprivoxy:debian-${{ env.BDATE }} 65 | ghcr.io/avpnusr/torprivoxy:latest-debian 66 | ghcr.io/avpnusr/torprivoxy:debian-${{ env.BDATE }} 67 | file: Dockerfile.debian 68 | cache-from: type=gha 69 | cache-to: type=gha,mode=max 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![TOR Privoxy Logo](https://i.imgur.com/rGdIzv9.png) 2 | 3 | **TOR and Privoxy in docker container** 4 | === 5 | 6 | This repository has multi architecture support and is regularly updated. 7 | Container is built for amd64, arm64, armv7 and armv6. 8 | 9 | The container is available with alpine base image **ghcr.io/avpnusr/torprivoxy:latest** 10 | The container is also available with debian base image **ghcr.io/avpnusr/torprivoxy:latest-debian** 11 | 12 | **Important:** Got rid of the old alpine version 3.12 - this could require action, if you use armhf architecture (Raspberry Pi i.e.) with older versions of docker. Please find information about this in the [alpine wiki](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0#time64_requirements) 13 | 14 | Kudos to [rdsubhas](https://hub.docker.com/r/rdsubhas/tor-privoxy-alpine). 15 | I used the tini and run based startup-scripts for services from his container. 16 | 17 | Status from last build 18 | ----- 19 | ![TorPrivoxy Docker Build](https://github.com/avpnusr/torprivoxy/workflows/TorPrivoxy%20Docker%20Build/badge.svg) 20 | 21 | Versions in the latest image 22 | ----- 23 | - [TOR](https://www.torproject.org/ "TOR Project Homepage") Version: 0.4.8.17 24 | - [Privoxy](https://www.privoxy.org/ "Privoxy Homepage") Version: 4.0.0 25 | 26 | Healthcheck & Configs 27 | ----- 28 | The docker container has a working health-check built in. 29 | 30 | To determine the correct function, it verifies access to the *.onion address from [DuckDuckGo](https://duckduckgo.com/ "DuckDuckGo Homepage"). 31 | 32 | **torrc-configuration:** 33 | 34 | I know the TOR-Project is in need for bridge relays, but considering, not every user from the container is familiar with the impacts, I decided to disable the bridge relay in the container by default. 35 | ``` 36 | SOCKSPort 0.0.0.0:9050 37 | ExitPolicy reject *:* 38 | BridgeRelay 0 39 | ``` 40 | 41 | **privoxy-configuration:** 42 | ``` 43 | listen-address 0.0.0.0:8118 44 | forward-socks5t / localhost:9050 . 45 | ``` 46 | 47 | Start your container 48 | ----- 49 | On port **[8118]**, the container offers a privoxy HTTP-Proxy forwarded to localhost:9050 SOCKS5 50 | 51 | On port **[9050]**, the container offers the TOR SOCKS5 proxy 52 | 53 | **docker compose** 54 | ----- 55 | You can add multiple lines under "BRIDGE" environment variable, all bridges will be added to torrc file. 56 | 57 | ``` 58 | services: 59 | torprivoxy: 60 | container_name: torprivoxy 61 | environment: 62 | TZ: Europe/Berlin # customize to your own 63 | BRIDGE: |- 64 | obfs4 : cert= iat-mode=0 65 | obfs4 : cert= iat-mode=0 66 | ports: 67 | - 8118:8118 68 | - 9050:9050 69 | image: ghcr.io/avpnusr/torprivoxy:latest 70 | ``` 71 | 72 | **alpine version** 73 | ----- 74 | ``` 75 | docker run -d \ 76 | -p 8118:8118 \ 77 | -p 9050:9050 \ 78 | --user=[UID:GID] \ 79 | --name torprivoxy \ 80 | --restart=unless-stopped ghcr.io/avpnusr/torprivoxy 81 | ``` 82 | 83 | **debian version** 84 | ------ 85 | ``` 86 | docker run -d \ 87 | -p 8118:8118 \ 88 | -p 9050:9050 \ 89 | --user=[UID:GID] \ 90 | --name torprivoxy \ 91 | --restart=unless-stopped ghcr.io/avpnusr/torprivoxy:latest-debian 92 | ``` --------------------------------------------------------------------------------