├── .gitignore ├── .github ├── CODEOWNERS ├── renovate.json ├── release.yml ├── dependabot.yml └── workflows │ ├── documentation.yml │ ├── release.yml │ └── tests.yml ├── .dockerignore ├── .editorconfig ├── LICENSE ├── deployments └── helm │ ├── Chart.yaml │ ├── templates │ ├── service.yaml │ ├── _helpers.tpl │ └── deployment.yaml │ ├── README.md │ ├── values.yaml │ └── values.schema.json ├── 3proxy.cfg.json ├── 3proxy.cfg.mustach ├── Dockerfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## IDEs 2 | /.vscode 3 | /.idea 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # @link 2 | 3 | * @tarampampam 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | ## Ignore everything 2 | * 3 | 4 | ## Except the following files (and directories) 5 | !/3proxy.cfg.json 6 | !/3proxy.cfg.mustach 7 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "github>tarampampam/.github//renovate/default", 5 | ":rebaseStalePrs" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig docs: 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [{*.yml,*.yaml}] 14 | ij_any_spaces_within_braces = false 15 | ij_any_spaces_within_brackets = false 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) tarampampam 2 | 3 | Everyone is permitted to copy and distribute verbatim or modified copies of this license 4 | document, and changing it is allowed as long as the name is changed. 5 | 6 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, 7 | DISTRIBUTION AND MODIFICATION 8 | 9 | 0. You just DO WHAT THE FUCK YOU WANT TO. 10 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-release-config.json 2 | # docs: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes 3 | 4 | changelog: 5 | categories: 6 | - title: 🛠 Fixes 7 | labels: [type:fix, type:bug] 8 | - title: 🚀 Features 9 | labels: [type:feature, type:feature_request] 10 | - title: 📦 Dependency updates 11 | labels: [dependencies] 12 | - title: Other Changes 13 | labels: ['*'] 14 | -------------------------------------------------------------------------------- /deployments/helm/Chart.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/chart.json 2 | 3 | apiVersion: v2 4 | name: proxy-3proxy 5 | description: Powerful and lightweight proxy server, written in pure C 6 | 7 | type: application 8 | version: 0.0.0 # will be replaced by the release workflow 9 | appVersion: 0.0.0 # will be replaced by the release workflow 10 | icon: https://github.com/user-attachments/assets/023186cf-b153-459c-8417-038fd87a2065 11 | home: https://github.com/3proxy/3proxy 12 | sources: [https://github.com/tarampampam/3proxy-docker] 13 | keywords: [proxy, 3proxy, http, socks] 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/dependabot-2.0.json 2 | # docs: https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/customizing-dependency-updates 3 | 4 | version: 2 5 | 6 | updates: 7 | - package-ecosystem: github-actions 8 | directory: / 9 | groups: {github-actions: {patterns: ['*']}} 10 | schedule: {interval: monthly} 11 | assignees: [tarampampam] 12 | 13 | - package-ecosystem: docker 14 | directory: / 15 | groups: {docker: {patterns: ['*']}} 16 | schedule: {interval: monthly} 17 | assignees: [tarampampam] 18 | -------------------------------------------------------------------------------- /3proxy.cfg.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "output": "${LOG_OUTPUT:-/dev/stdout}" 4 | }, 5 | "name_servers": [ 6 | "${PRIMARY_RESOLVER:-1.0.0.1}", 7 | "${SECONDARY_RESOLVER:-8.8.4.4}", 8 | "1.1.1.1", 9 | "9.9.9.9", 10 | "8.8.8.8" 11 | ], 12 | "name_servers_cache": 65536, 13 | "max_connections": "${MAX_CONNECTIONS:-1024}", 14 | "auth": { 15 | "login": "${PROXY_LOGIN:-}", 16 | "password": "${PROXY_PASSWORD:-}", 17 | "extra_accounts": ${EXTRA_ACCOUNTS:-{}} 18 | }, 19 | "ports": { 20 | "proxy": "${PROXY_PORT:-3128}", 21 | "socks": "${SOCKS_PORT:-1080}" 22 | }, 23 | "extra_config": "${EXTRA_CONFIG}" 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json 2 | # docs: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | 4 | name: 📚 Documentation 5 | 6 | on: 7 | push: 8 | branches: [master, main] 9 | paths: ['README.md'] 10 | 11 | jobs: 12 | docker-hub-description: 13 | name: Docker Hub Description 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v6 17 | 18 | - uses: peter-evans/dockerhub-description@v5 19 | with: 20 | username: ${{ secrets.DOCKER_LOGIN }} 21 | password: ${{ secrets.DOCKER_USER_PASSWORD }} 22 | repository: tarampampam/3proxy 23 | -------------------------------------------------------------------------------- /deployments/helm/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.service.enabled }} 2 | apiVersion: v1 3 | kind: Service 4 | 5 | metadata: 6 | name: {{ include "proxy-3proxy.fullname" . }} 7 | namespace: {{ template "proxy-3proxy.namespace" . }} 8 | labels: 9 | {{- include "proxy-3proxy.commonLabels" . | nindent 4 }} 10 | 11 | spec: 12 | {{- with .Values.service }} 13 | type: {{ .type }} 14 | {{- with .externalName }} 15 | externalName: {{ . }} 16 | {{- end }} 17 | ports: 18 | - name: http 19 | port: {{ .ports.http }} 20 | targetPort: http 21 | protocol: TCP 22 | - name: socks 23 | port: {{ .ports.socks }} 24 | targetPort: socks 25 | protocol: TCP 26 | selector: 27 | {{- include "proxy-3proxy.selectorLabels" $ | nindent 4 }} 28 | {{- end }} 29 | {{- end }} 30 | -------------------------------------------------------------------------------- /deployments/helm/README.md: -------------------------------------------------------------------------------- 1 | # 3proxy 2 | 3 | Important note: Since the chart is released together with the app under the same version (i.e., the chart version 4 | matches the app version), its versioning is not compatible with semantic versioning (SemVer). I will do my best to 5 | avoid non-backward-compatible changes in the chart, but due to Murphy's Law, I cannot guarantee that they will 6 | never occur. 7 | 8 | Also, this chart does not include Ingress configuration. If you need it, please, create it manually. 9 | 10 | ## Usage 11 | 12 | ```shell 13 | helm repo add proxy-3proxy https://tarampampam.github.io/3proxy-docker/helm-charts 14 | helm repo update 15 | 16 | helm install my-3proxy proxy-3proxy/proxy-3proxy --version 17 | ``` 18 | 19 | Alternatively, add the following lines to your `Chart.yaml`: 20 | 21 | ```yaml 22 | dependencies: 23 | - name: proxy-3proxy 24 | version: 25 | repository: https://tarampampam.github.io/3proxy-docker/helm-charts 26 | ``` 27 | 28 | And override the default values in your `values.yaml`: 29 | 30 | ```yaml 31 | proxy-3proxy: 32 | # ... 33 | service: {ports: {http: 3128}} 34 | # ... 35 | ``` 36 | -------------------------------------------------------------------------------- /3proxy.cfg.mustach: -------------------------------------------------------------------------------- 1 | #!/bin/3proxy 2 | config /etc/3proxy/3proxy.cfg 3 | 4 | # you may use system to execute some external command if proxy starts 5 | system "echo `which 3proxy`': Starting 3proxy'" 6 | 7 | # We can configure nservers to avoid unsafe gethostbyname() usage (max 5 servers) 8 | {{#name_servers}} 9 | nserver {{ . }} 10 | {{/name_servers}} 11 | 12 | # nscache is good to save speed, traffic and bandwidth 13 | nscache {{ name_servers_cache }} 14 | 15 | # Here we can change timeout values 16 | timeouts 1 5 30 60 180 1800 15 60 17 | 18 | # Logging docs: 19 | log {{ log.output }} 20 | logformat "-\""+_G{""time_unix"":%t, ""proxy"":{""type:"":""%N"", ""port"":%p}, ""error"":{""code"":""%E""}, ""auth"":{""user"":""%U""}, ""client"":{""ip"":""%C"", ""port"":%c}, ""server"":{""ip"":""%R"", ""port"":%r}, ""bytes"":{""sent"":%O, ""received"":%I}, ""request"":{""hostname"":""%n""}, ""message"":""%T""}" 21 | 22 | maxconn {{ max_connections }} 23 | 24 | {{^auth.login=}}{{^auth.password=}} 25 | users {{ auth.login }}:CL:{{ auth.password }}{{#auth.extra_accounts.*}} {{ * }}:CL:{{ . }}{{/auth.extra_accounts.*}} 26 | auth strong 27 | allow {{ auth.login }}{{#auth.extra_accounts.*}},{{ * }}{{/auth.extra_accounts.*}} 28 | {{/auth.password=}}{{/auth.login=}} 29 | 30 | {{^extra_config=}} 31 | 32 | # Additional configuration 33 | {{extra_config}} 34 | {{/extra_config=}} 35 | 36 | proxy -a -p{{ ports.proxy }} 37 | socks -a -p{{ ports.socks }} 38 | 39 | flush 40 | -------------------------------------------------------------------------------- /deployments/helm/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* Define namespace of chart, useful for multi-namespace deployments */}} 2 | {{- define "proxy-3proxy.namespace" -}} 3 | {{- if .Values.namespaceOverride }} 4 | {{- .Values.namespaceOverride }} 5 | {{- else }} 6 | {{- .Release.Namespace }} 7 | {{- end }} 8 | {{- end }} 9 | 10 | {{/* Expand the name of the chart */}} 11 | {{- define "proxy-3proxy.name" -}} 12 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 13 | {{- end }} 14 | 15 | {{/* 16 | Create a default fully qualified app name. 17 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 18 | If release name contains chart name it will be used as a full name. 19 | */}} 20 | {{- define "proxy-3proxy.fullname" -}} 21 | {{- if .Values.fullnameOverride }} 22 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 23 | {{- else }} 24 | {{- $name := default .Chart.Name .Values.nameOverride }} 25 | {{- if contains $name .Release.Name }} 26 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 27 | {{- else }} 28 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 29 | {{- end }} 30 | {{- end }} 31 | {{- end }} 32 | 33 | {{/* Create chart name and version as used by the chart label */}} 34 | {{- define "proxy-3proxy.chart" -}} 35 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 36 | {{- end }} 37 | 38 | {{/* Common labels */}} 39 | {{- define "proxy-3proxy.commonLabels" -}} 40 | helm.sh/chart: {{ include "proxy-3proxy.chart" . }} 41 | {{ include "proxy-3proxy.selectorLabels" . }} 42 | {{- if .Chart.AppVersion }} 43 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 44 | {{- end }} 45 | app.kubernetes.io/managed-by: {{ .Release.Service }} 46 | {{- end }} 47 | 48 | {{/* Selector labels */}} 49 | {{- define "proxy-3proxy.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "proxy-3proxy.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json 2 | # docs: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | 4 | name: 🚀 Release 5 | 6 | on: 7 | release: {types: [published]} 8 | workflow_dispatch: {} 9 | 10 | jobs: 11 | build-docker-image: 12 | name: Build the docker image 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v6 16 | - uses: docker/login-action@v3 17 | with: 18 | username: ${{ secrets.DOCKER_LOGIN }} 19 | password: ${{ secrets.DOCKER_PASSWORD }} 20 | - uses: docker/login-action@v3 21 | with: 22 | registry: ghcr.io 23 | username: ${{ github.actor }} 24 | password: ${{ secrets.GITHUB_TOKEN }} 25 | - {uses: gacts/github-slug@v1, id: slug} 26 | - uses: docker/setup-qemu-action@v3 27 | - uses: docker/setup-buildx-action@v3 28 | - uses: docker/build-push-action@v6 29 | with: 30 | context: . 31 | push: true 32 | platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x 33 | tags: | 34 | ghcr.io/${{ github.actor }}/3proxy:latest 35 | ghcr.io/${{ github.actor }}/3proxy:${{ steps.slug.outputs.version }} 36 | ghcr.io/${{ github.actor }}/3proxy:${{ steps.slug.outputs.version-major }}.${{ steps.slug.outputs.version-minor }} 37 | ghcr.io/${{ github.actor }}/3proxy:${{ steps.slug.outputs.version-major }} 38 | docker.io/tarampampam/3proxy:latest 39 | docker.io/tarampampam/3proxy:${{ steps.slug.outputs.version }} 40 | docker.io/tarampampam/3proxy:${{ steps.slug.outputs.version-major }}.${{ steps.slug.outputs.version-minor }} 41 | docker.io/tarampampam/3proxy:${{ steps.slug.outputs.version-major }} 42 | 43 | helm-pack: 44 | name: Pack the Helm chart 45 | runs-on: ubuntu-latest 46 | needs: [build-docker-image] 47 | defaults: {run: {working-directory: ./deployments/helm}} 48 | steps: 49 | - uses: actions/checkout@v6 50 | - uses: azure/setup-helm@v4 51 | - {uses: gacts/github-slug@v1, id: slug} 52 | - run: | 53 | helm package \ 54 | --app-version "${{ steps.slug.outputs.version }}" \ 55 | --version "${{ steps.slug.outputs.version }}" . 56 | - uses: actions/upload-artifact@v5 57 | with: 58 | name: helm-chart 59 | path: ./deployments/helm/*.tgz 60 | if-no-files-found: error 61 | retention-days: 1 62 | 63 | helm-publish: 64 | name: Put the Helm chart to the GitHub pages branch 65 | runs-on: ubuntu-latest 66 | needs: [helm-pack] 67 | steps: 68 | - {uses: actions/checkout@v4, with: {ref: gh-pages}} 69 | - uses: azure/setup-helm@v4 70 | - uses: actions/download-artifact@v6 71 | with: {name: helm-chart, path: ./helm-charts} 72 | - name: Update the index.yaml 73 | run: | 74 | helm repo index \ 75 | --url https://${{ github.actor }}.github.io/${{ github.event.repository.name }}/helm-charts/ \ 76 | --merge \ 77 | ./helm-charts/index.yaml \ 78 | ./helm-charts 79 | - {uses: gacts/directory-listing@v1, with: {overwrite: true}} 80 | - name: Commit and push the changes 81 | run: | 82 | git config user.name "${{ github.actor }}" 83 | git config user.email "${{ github.actor }}@users.noreply.github.com" 84 | git add . 85 | git commit -m "Helm chart release" 86 | git push origin gh-pages 87 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM docker.io/library/gcc:15.2.0 AS builder 4 | 5 | # renovate: source=github-tags name=3proxy/3proxy 6 | ARG Z3PROXY_VERSION=0.9.5 7 | 8 | # Fetch 3proxy sources 9 | RUN set -x \ 10 | && git -c advice.detachedHead=false clone --depth 1 --branch "${Z3PROXY_VERSION}" https://github.com/3proxy/3proxy.git /tmp/3proxy 11 | 12 | WORKDIR /tmp/3proxy 13 | 14 | # Patch sources 15 | RUN set -x \ 16 | && echo '#define ANONYMOUS 1' >> ./src/3proxy.h \ 17 | # proxy.c source: 18 | && sed -i 's~\(<\/head>\)~\1~' ./src/proxy.c \ 24 | && cat ./src/proxy.c | grep '' 25 | 26 | # And compile 27 | RUN set -x \ 28 | && echo "" >> ./Makefile.Linux \ 29 | && echo "PLUGINS = StringsPlugin TrafficPlugin PCREPlugin TransparentPlugin SSLPlugin" >> ./Makefile.Linux \ 30 | && echo "LIBS = -l:libcrypto.a -l:libssl.a -ldl" >> ./Makefile.Linux \ 31 | && make -f Makefile.Linux \ 32 | && strip ./bin/3proxy \ 33 | && strip ./bin/StringsPlugin.ld.so \ 34 | && strip ./bin/TrafficPlugin.ld.so \ 35 | && strip ./bin/PCREPlugin.ld.so \ 36 | && strip ./bin/TransparentPlugin.ld.so \ 37 | && strip ./bin/SSLPlugin.ld.so \ 38 | && cp /lib/$(gcc -dumpmachine)/libdl.so.* /tmp/3proxy/ 39 | 40 | # Prepare filesystem for 3proxy running 41 | FROM docker.io/library/alpine:latest AS buffer 42 | 43 | # create a directory for the future root filesystem 44 | WORKDIR /tmp/rootfs 45 | 46 | # prepare the root filesystem 47 | RUN set -x \ 48 | && mkdir -p ./etc ./bin ./usr/local/3proxy/libexec ./etc/3proxy \ 49 | && echo '3proxy:x:10001:10001::/nonexistent:/sbin/nologin' > ./etc/passwd \ 50 | && echo '3proxy:x:10001:' > ./etc/group \ 51 | && apk add --no-cache --virtual .build-deps curl ca-certificates \ 52 | && update-ca-certificates \ 53 | && curl -SsL -o ./bin/dumb-init "https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_$(arch)" \ 54 | && chmod +x ./bin/dumb-init \ 55 | && apk del .build-deps 56 | 57 | COPY --from=builder /tmp/3proxy/libdl.so.* ./lib/ 58 | COPY --from=builder /tmp/3proxy/bin/3proxy ./bin/3proxy 59 | COPY --from=builder /tmp/3proxy/bin/*.ld.so ./usr/local/3proxy/libexec/ 60 | COPY --from=ghcr.io/tarampampam/mustpl:0.1.1 /bin/mustpl ./bin/mustpl 61 | COPY 3proxy.cfg.json ./etc/3proxy/3proxy.cfg.json 62 | COPY 3proxy.cfg.mustach ./etc/3proxy/3proxy.cfg.mustach 63 | 64 | RUN chown -R 10001:10001 ./etc/3proxy 65 | 66 | # Merge into a single layer 67 | FROM docker.io/library/busybox:stable-glibc 68 | 69 | LABEL \ 70 | org.opencontainers.image.title="3proxy" \ 71 | org.opencontainers.image.description="Tiny free proxy server" \ 72 | org.opencontainers.image.url="https://github.com/tarampampam/3proxy-docker" \ 73 | org.opencontainers.image.source="https://github.com/tarampampam/3proxy-docker" \ 74 | org.opencontainers.image.vendor="Tarampampam" \ 75 | org.opencontainers.image.licenses="WTFPL" 76 | 77 | # Import from builder 78 | COPY --from=buffer /tmp/rootfs / 79 | 80 | # Use an unprivileged user 81 | USER 3proxy:3proxy 82 | 83 | ENTRYPOINT [ \ 84 | "/bin/mustpl", \ 85 | "-f", "/etc/3proxy/3proxy.cfg.json", \ 86 | "-o", "/etc/3proxy/3proxy.cfg", \ 87 | "/etc/3proxy/3proxy.cfg.mustach", \ 88 | "--", "/bin/dumb-init" \ 89 | ] 90 | 91 | CMD ["/bin/3proxy", "/etc/3proxy/3proxy.cfg"] 92 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json 2 | # docs: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | 4 | name: 🧪 Tests 5 | 6 | on: 7 | workflow_dispatch: {} 8 | push: 9 | branches: [master, main] 10 | paths-ignore: ['**.md'] 11 | tags-ignore: ['**'] 12 | pull_request: 13 | paths-ignore: ['**.md'] 14 | 15 | concurrency: 16 | group: ${{ github.ref }} 17 | cancel-in-progress: true 18 | 19 | jobs: 20 | gitleaks: 21 | name: Check for GitLeaks 22 | runs-on: ubuntu-latest 23 | steps: 24 | - {uses: actions/checkout@v4, with: {fetch-depth: 0}} 25 | - uses: gacts/gitleaks@v1 26 | 27 | lint-charts: 28 | name: Lint the chart 29 | runs-on: ubuntu-latest 30 | defaults: {run: {working-directory: ./deployments/helm}} 31 | steps: 32 | - uses: actions/checkout@v6 33 | - uses: azure/setup-helm@v4 34 | - run: helm dependency update . 35 | - run: helm template . > /dev/null 36 | - run: helm lint --strict . 37 | 38 | build-image: 39 | name: Build the docker image (${{ matrix.platform }}) 40 | runs-on: ubuntu-latest 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | platform: 45 | - linux/amd64 46 | - linux/arm/v6 47 | - linux/arm/v7 48 | - linux/arm64 49 | - linux/ppc64le 50 | - linux/s390x 51 | steps: 52 | - uses: actions/checkout@v6 53 | - uses: docker/setup-qemu-action@v3 54 | - uses: docker/setup-buildx-action@v3 55 | - uses: docker/build-push-action@v6 56 | with: 57 | context: . 58 | file: Dockerfile 59 | push: false 60 | load: true 61 | platforms: ${{ matrix.platform }} 62 | tags: 3proxy:local 63 | - if: matrix.platform == 'linux/amd64' 64 | run: docker save 3proxy:local -o ./docker-image.tar 65 | - if: matrix.platform == 'linux/amd64' 66 | uses: actions/upload-artifact@v5 67 | with: 68 | name: docker-image 69 | path: ./docker-image.tar 70 | retention-days: 1 71 | 72 | try-to-use: 73 | name: Try to use the docker image (auth ${{ matrix.auth }}) 74 | runs-on: ubuntu-latest 75 | strategy: 76 | fail-fast: false 77 | matrix: 78 | auth: [yes, no] 79 | needs: [build-image] 80 | steps: 81 | - uses: actions/download-artifact@v6 82 | with: 83 | name: docker-image 84 | path: .artifact 85 | - working-directory: .artifact 86 | run: docker load < docker-image.tar 87 | - if: matrix.auth != 'yes' 88 | run: docker run --rm -d -p "3128:3128/tcp" -p "1080:1080/tcp" 3proxy:local 89 | - if: matrix.auth == 'yes' 90 | run: docker run --rm -d -p "3128:3128/tcp" -p "1080:1080/tcp" -e "PROXY_LOGIN=evil" -e "PROXY_PASSWORD=live" -e 'EXTRA_ACCOUNTS={"foo":"bar"}' 3proxy:local 91 | - run: sleep 3 92 | - name: Try to use HTTP proxy 93 | if: matrix.auth != 'yes' 94 | run: | 95 | curl -v --fail \ 96 | --proxy http://127.0.0.1:3128 \ 97 | --connect-timeout 3 \ 98 | --max-time 3 \ 99 | https://www.cloudflare.com/robots.txt 100 | - name: Try to use SOCKS proxy 101 | if: matrix.auth != 'yes' 102 | run: | 103 | curl -v --fail \ 104 | --proxy socks5://127.0.0.1:1080 \ 105 | --connect-timeout 3 \ 106 | --max-time 3 \ 107 | https://www.cloudflare.com/robots.txt 108 | - name: Try to use HTTP proxy (with auth) 109 | if: matrix.auth == 'yes' 110 | run: | 111 | curl -v --fail \ 112 | --proxy http://127.0.0.1:3128 \ 113 | --proxy-user evil:live \ 114 | --connect-timeout 3 \ 115 | --max-time 3 \ 116 | https://www.cloudflare.com/robots.txt 117 | - name: Try to use HTTP proxy (with auth, extra user) 118 | if: matrix.auth == 'yes' 119 | run: | 120 | curl -v --fail \ 121 | --proxy http://127.0.0.1:3128 \ 122 | --proxy-user foo:bar \ 123 | --connect-timeout 3 \ 124 | --max-time 3 \ 125 | https://www.cloudflare.com/robots.txt 126 | - name: Try to use SOCKS proxy (with auth) 127 | if: matrix.auth == 'yes' 128 | run: | 129 | curl -v --fail \ 130 | --proxy socks5://127.0.0.1:1080 \ 131 | --proxy-user evil:live \ 132 | --connect-timeout 3 \ 133 | --max-time 3 \ 134 | https://www.cloudflare.com/robots.txt 135 | - run: docker stop $(docker ps -a --filter ancestor=3proxy:local -q) 136 | -------------------------------------------------------------------------------- /deployments/helm/values.yaml: -------------------------------------------------------------------------------- 1 | # -- The name of the Helm release 2 | fullnameOverride: null 3 | # -- This is to override the chart name 4 | nameOverride: null 5 | # -- Override the default Release Namespace for Helm 6 | namespaceOverride: null 7 | 8 | image: 9 | # -- The image repository to pull from 10 | repository: ghcr.io/tarampampam/3proxy 11 | # -- Defines the image pull policy 12 | pullPolicy: IfNotPresent 13 | # -- Overrides the image tag whose default is the chart appVersion 14 | tag: null 15 | 16 | deployment: 17 | # -- Enable deployment 18 | enabled: true 19 | # -- The deployment kind 20 | kind: Deployment 21 | # -- How many replicas to run 22 | replicas: 1 23 | # -- Additional pod annotations (e.g. for mesh injection or prometheus scraping) 24 | # It supports templating. One can set it with values like some/name: '{{ template "some.name" . }}' 25 | # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ 26 | podAnnotations: {} # supports templating 27 | # -- Additional deployment labels (e.g. for filtering deployment by custom labels) 28 | labels: {} # supports templating 29 | # -- This is for the secretes for pulling an image from a private repository more information can be found 30 | # here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ 31 | imagePullSecrets: [] # supports templating 32 | # -- Security context for the pod, more information can be found here: 33 | # https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1 34 | securityContext: 35 | runAsNonRoot: true 36 | runAsUser: 10001 # as defined in the Dockerfile 37 | runAsGroup: 10001 # as defined in the Dockerfile 38 | probe: 39 | # -- The port to probe (containerPort, "http" or "socks") 40 | port: http 41 | # -- How often (in seconds) to perform the probe 42 | interval: 10 43 | # -- Number of seconds after the container has started before liveness probes are initiated 44 | initialDelay: 2 45 | # -- Resource limits and requests, more information can be found here: 46 | # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ 47 | resources: 48 | requests: {memory: 16Mi} 49 | limits: {memory: 128Mi} 50 | # -- Additional volumes to add to the pod, more information can be found here: 51 | # https://kubernetes.io/docs/concepts/storage/volumes/ 52 | volumes: [] # supports templating 53 | # -- Additional volumeMounts to add to the container (for instance when using fs storage driver) 54 | volumeMounts: [] # supports templating 55 | # -- Node selector for pod assignment, more information can be found here: 56 | # https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ 57 | nodeSelector: {} # supports templating 58 | # -- Affinity for pod assignment, more information can be found here: 59 | # https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ 60 | affinity: {} # supports templating 61 | # -- Tolerations for pod assignment, more information can be found here: 62 | # https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ 63 | tolerations: [] # supports templating 64 | # -- The list of additional environment variables to set in the container 65 | env: [] # supports templating 66 | # -- The list of additional arguments to pass to the container 67 | args: [] # supports templating 68 | 69 | service: 70 | # -- Enable service 71 | enabled: true 72 | # -- Sets the service type more information can be found here: 73 | # https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types 74 | type: ClusterIP 75 | # -- External name for the service (for type=ExternalName) 76 | externalName: null 77 | # -- Sets the port, more information can be found here: 78 | # https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports 79 | ports: 80 | # -- The port number for the proxy to listen on 81 | http: 3128 82 | # -- The same, but for socks proxy 83 | socks: 1080 84 | 85 | config: 86 | log: 87 | # -- Enable logging (set to false to disable) 88 | enabled: true 89 | # -- The output log file 90 | # @default /dev/stdout 91 | output: null 92 | 93 | auth: 94 | login: 95 | # -- Username (login) for proxy authentication, provided as a plain value 96 | plain: null 97 | fromSecret: 98 | # -- Enable getting the username from a secret 99 | enabled: false 100 | secretName: null # supports templating 101 | secretKey: null # supports templating 102 | fromConfigMap: 103 | # -- Enable getting the username from a config map 104 | enabled: false 105 | configMapName: null # supports templating 106 | configMapKey: null # supports templating 107 | password: 108 | # -- Password for proxy authentication, provided as a plain value 109 | plain: null 110 | fromSecret: 111 | # -- Enable getting the password from a secret 112 | enabled: false 113 | secretName: null # supports templating 114 | secretKey: null # supports templating 115 | fromConfigMap: 116 | # -- Enable getting the password from a config map 117 | enabled: false 118 | configMapName: null # supports templating 119 | configMapKey: null # supports templating 120 | extraAccounts: 121 | # -- The list of additional accounts to add to the configuration (a hashmap of username:password) 122 | plain: {} 123 | fromSecret: 124 | # -- Enable getting the extra accounts from a secret (the value should be a JSON object) 125 | enabled: false 126 | secretName: null # supports templating 127 | secretKey: null # supports templating 128 | fromConfigMap: 129 | # -- Enable getting the extra accounts from a config map (the value should be a JSON object) 130 | enabled: false 131 | configMapName: null # supports templating 132 | configMapKey: null # supports templating 133 | 134 | dns: 135 | # -- Primary DNS server 136 | # @default 1.0.0.1 (Cloudflare) 137 | primaryResolver: null 138 | # -- Secondary DNS server 139 | # @default 8.8.4.4 (Google) 140 | secondaryResolver: null 141 | 142 | limits: 143 | # -- The maximum number of connections 144 | # @default 1024 145 | maxConnections: null 146 | 147 | # -- Additional 3proxy configuration (appended to the end of the config file, but before `proxy` and `flush`), 148 | # new lines should be separated by `\n`, i.e.: "# line 1\n# line 2" 149 | extraConfig: null 150 | -------------------------------------------------------------------------------- /deployments/helm/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.deployment.enabled }} 2 | apiVersion: apps/v1 3 | kind: {{ .Values.deployment.kind | default "Deployment" }} 4 | 5 | metadata: 6 | name: {{ include "proxy-3proxy.fullname" . }} 7 | namespace: {{ template "proxy-3proxy.namespace" . }} 8 | labels: 9 | {{- include "proxy-3proxy.commonLabels" . | nindent 4 }} 10 | 11 | spec: 12 | {{- with .Values.deployment }} 13 | replicas: {{ .replicas | default 1 }} 14 | selector: 15 | matchLabels: 16 | {{- include "proxy-3proxy.selectorLabels" $ | nindent 6 }} 17 | template: 18 | metadata: 19 | {{- with .podAnnotations }} 20 | annotations: 21 | {{- tpl (toYaml .) $ | nindent 8 }} 22 | {{- end }} 23 | labels: 24 | {{- include "proxy-3proxy.commonLabels" $ | nindent 8 }} 25 | {{- with .labels }} 26 | {{- tpl (toYaml .) $ | nindent 8 }} 27 | {{- end }} 28 | spec: 29 | automountServiceAccountToken: false 30 | {{- with .imagePullSecrets }} 31 | imagePullSecrets: 32 | {{- tpl (toYaml .) $ | nindent 8 }} 33 | {{- end }} 34 | containers: 35 | - name: {{ include "proxy-3proxy.fullname" $ }} 36 | 37 | {{- with .securityContext }} 38 | securityContext: 39 | {{- toYaml . | nindent 12 }} 40 | readOnlyRootFilesystem: false 41 | {{- end }} 42 | 43 | {{- with $.Values.image }} 44 | image: "{{ .repository }}:{{ .tag | default $.Chart.AppVersion }}" 45 | imagePullPolicy: {{ .pullPolicy | default "IfNotPresent" }} 46 | {{- end }} 47 | ports: 48 | - name: http 49 | containerPort: 3128 50 | protocol: TCP 51 | - name: socks 52 | containerPort: 1080 53 | protocol: TCP 54 | env: 55 | - {name: PROXY_PORT, value: "3128"} 56 | - {name: SOCKS_PORT, value: "1080"} 57 | {{- with $.Values.config }} 58 | {{- with .log }} 59 | {{- $logOutputEnvName := "LOG_OUTPUT" }} 60 | {{- if eq .enabled false }} 61 | - {name: {{ $logOutputEnvName }}, value: "/dev/null"} 62 | {{- else if .output }} 63 | - {name: {{ $logOutputEnvName }}, value: "{{ .output }}"} 64 | {{- end }} 65 | {{- end }} 66 | 67 | {{- with .auth.login }} 68 | {{- $authLoginEnvName := "PROXY_LOGIN" }} 69 | {{- if .plain }} 70 | - {name: {{ $authLoginEnvName }}, value: "{{ .plain }}"} 71 | {{- else if .fromSecret.enabled }} 72 | - name: {{ $authLoginEnvName }} 73 | valueFrom: 74 | secretKeyRef: 75 | name: {{ tpl .fromSecret.secretName $ | quote }} 76 | key: {{ tpl .fromSecret.secretKey $ | quote }} 77 | {{- else if .fromConfigMap.enabled }} 78 | - name: {{ $authLoginEnvName }} 79 | valueFrom: 80 | configMapKeyRef: 81 | name: {{ tpl .fromConfigMap.configMapName $ | quote }} 82 | key: {{ tpl .fromConfigMap.configMapKey $ | quote }} 83 | {{- end }} 84 | {{- end }} 85 | 86 | {{- with .auth.password }} 87 | {{- $authPasswordEnvName := "PROXY_PASSWORD" }} 88 | {{- if .plain }} 89 | - {name: {{ $authPasswordEnvName }}, value: "{{ .plain }}"} 90 | {{- else if .fromSecret.enabled }} 91 | - name: {{ $authPasswordEnvName }} 92 | valueFrom: 93 | secretKeyRef: 94 | name: {{ tpl .fromSecret.secretName $ | quote }} 95 | key: {{ tpl .fromSecret.secretKey $ | quote }} 96 | {{- else if .fromConfigMap.enabled }} 97 | - name: {{ $authPasswordEnvName }} 98 | valueFrom: 99 | configMapKeyRef: 100 | name: {{ tpl .fromConfigMap.configMapName $ | quote }} 101 | key: {{ tpl .fromConfigMap.configMapKey $ | quote }} 102 | {{- end }} 103 | {{- end }} 104 | 105 | {{- with .auth.extraAccounts }} 106 | {{- $extraAuthAccountsEnvName := "EXTRA_ACCOUNTS" }} 107 | {{- if .plain }} 108 | - name: {{ $extraAuthAccountsEnvName }} 109 | value: >- 110 | {{ .plain | toJson }} 111 | {{- else if .fromSecret.enabled }} 112 | - name: {{ $extraAuthAccountsEnvName }} 113 | valueFrom: 114 | secretKeyRef: 115 | name: {{ tpl .fromSecret.secretName $ | quote }} 116 | key: {{ tpl .fromSecret.secretKey $ | quote }} 117 | {{- else if .fromConfigMap.enabled }} 118 | - name: {{ $extraAuthAccountsEnvName }} 119 | valueFrom: 120 | configMapKeyRef: 121 | name: {{ tpl .fromConfigMap.configMapName $ | quote }} 122 | key: {{ tpl .fromConfigMap.configMapKey $ | quote }} 123 | {{- end }} 124 | {{- end }} 125 | 126 | {{- if .dns.primaryResolver }} 127 | - {name: PRIMARY_RESOLVER, value: "{{ .dns.primaryResolver }}"} 128 | {{- end }} 129 | 130 | {{- if .dns.secondaryResolver }} 131 | - {name: SECONDARY_RESOLVER, value: "{{ .dns.secondaryResolver }}"} 132 | {{- end }} 133 | 134 | {{- if ne .limits.maxConnections nil }} 135 | - {name: MAX_CONNECTIONS, value: "{{ .limits.maxConnections }}"} 136 | {{- end }} 137 | 138 | {{- if .extraConfig }} 139 | - name: EXTRA_CONFIG 140 | value: >- 141 | {{ .extraConfig }} 142 | {{- end }} 143 | {{- with $.Values.deployment.env }} 144 | {{- tpl (toYaml .) $ | nindent 12 }} 145 | {{- end }} 146 | {{- end }} 147 | 148 | {{- with .args }} 149 | args: 150 | {{- tpl (toYaml .) $ | nindent 12 }} 151 | {{- end }} 152 | 153 | {{- with .probe }} 154 | livenessProbe: 155 | tcpSocket: {port: "{{ .port }}"} 156 | periodSeconds: {{ .interval }} 157 | initialDelaySeconds: {{ .initialDelay }} 158 | readinessProbe: 159 | tcpSocket: {port: "{{ .port }}"} 160 | periodSeconds: {{ .interval }} 161 | initialDelaySeconds: {{ .initialDelay }} 162 | {{- end }} 163 | 164 | {{- with .resources }} 165 | resources: 166 | {{- toYaml . | nindent 12 }} 167 | {{- end }} 168 | 169 | {{- with .volumeMounts }} 170 | volumeMounts: 171 | {{- tpl (toYaml .) $ | nindent 12 }} 172 | {{- end }} 173 | 174 | {{- with .volumes }} 175 | volumes: 176 | {{- tpl (toYaml .) $ | nindent 8 }} 177 | {{- end }} 178 | 179 | {{- with .nodeSelector }} 180 | nodeSelector: 181 | {{- tpl (toYaml .) $ | nindent 8 }} 182 | {{- end }} 183 | 184 | {{- with .affinity }} 185 | affinity: 186 | {{- tpl (toYaml .) $ | nindent 8 }} 187 | {{- end }} 188 | 189 | {{- with .tolerations }} 190 | tolerations: 191 | {{- tpl (toYaml .) $ | nindent 8 }} 192 | {{- end }} 193 | {{- end }} 194 | {{- end }} 195 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | 6 | 7 | 8 |

9 | 10 |

11 | 12 | 13 | 14 | 15 | 16 |

17 | 18 | # Docker image with [3proxy][link_3proxy] 19 | 20 | 3proxy is a powerful and lightweight proxy server. This image includes the stable version and can be easily 21 | configured using environment variables. By default, it operates with anonymous proxy settings to hide client 22 | information and logs activity in JSON format. 23 | 24 | > Page on `hub.docker.com` can be [found here][link_docker_hub]. 25 | 26 | TCP ports: 27 | 28 | | Port number | Description | 29 | |-------------|---------------------------------------------------------| 30 | | `3128` | [HTTP proxy](https://3proxy.org/doc/man8/proxy.8.html) | 31 | | `1080` | [SOCKS proxy](https://3proxy.org/doc/man8/socks.8.html) | 32 | 33 | ## Supported tags 34 | 35 | | Registry | Image | 36 | |----------------------------------------|------------------------------| 37 | | [GitHub Container Registry][link_ghcr] | `ghcr.io/tarampampam/3proxy` | 38 | | [Docker Hub][link_docker_hub] (mirror) | `tarampampam/3proxy` | 39 | 40 | > [!NOTE] 41 | > It’s recommended to avoid using the `latest` tag, as **major** upgrades may include breaking changes. 42 | > Instead, use specific tags in `X.Y.Z` format for version consistency. 43 | 44 | All supported image tags can be [found here][link_docker_tags]. 45 | 46 | > Starting with version 1.8.2, the `arm64` architecture is supported (in addition to `amd64`): 47 | 48 |
49 | docker run --rm mplatform/mquery ghcr.io/tarampampam/3proxy:1.8.2 50 | 51 | ```shell 52 | Image: ghcr.io/tarampampam/3proxy:1.8.2 53 | * Manifest List: Yes (Image type: application/vnd.docker.distribution.manifest.list.v2+json) 54 | * Supported platforms: 55 | - linux/amd64 56 | - linux/arm64 57 | ``` 58 | 59 |
60 | 61 | > Starting with version 1.12.1, the following architectures are supported: `arm/v6`, `arm/v7`, `ppc64le`, `s390x` 62 | > (in addition to `amd64`, `arm64`): 63 | 64 |
65 | docker run --rm mplatform/mquery ghcr.io/tarampampam/3proxy:1.12.1 66 | 67 | ```shell 68 | Image: ghcr.io/tarampampam/3proxy:1.12.1 69 | * Manifest List: Yes (Image type: application/vnd.oci.image.index.v1+json) 70 | * Supported platforms: 71 | - linux/amd64 72 | - linux/arm/v6 73 | - linux/arm/v7 74 | - linux/arm64 75 | - linux/ppc64le 76 | - linux/s390x 77 | ``` 78 | 79 |
80 | 81 | ## Supported Environment Variables 82 | 83 | | Variable Name | Description | Example | 84 | |----------------------|-----------------------------------------------------------------------------------------------------------------------|-----------------------------------| 85 | | `PROXY_LOGIN` | Authorization login (empty by default) | `username` | 86 | | `PROXY_PASSWORD` | Authorization password (empty by default) | `password` | 87 | | `EXTRA_ACCOUNTS` | Additional proxy users (JSON object format) | `{"evil":"live", "guest":"pass"}` | 88 | | `PRIMARY_RESOLVER` | Primary DNS resolver (`1.0.0.1` by default) | `8.8.8.8:5353/tcp` | 89 | | `SECONDARY_RESOLVER` | Secondary DNS resolver (`8.8.4.4` by default) | `2001:4860:4860::8844` | 90 | | `MAX_CONNECTIONS` | Maximum number of connections (`1024` by default) | `2056` | 91 | | `PROXY_PORT` | HTTP proxy port (`3128` by default) | `8080` | 92 | | `SOCKS_PORT` | SOCKS proxy port (`1080` by default) | `8888` | 93 | | `EXTRA_CONFIG` | Additional 3proxy configuration (appended to the **end** of the config file, but before `proxy` and `flush`) | `# line 1\n# line 2` | 94 | | `LOG_OUTPUT` | Path for log output (`/dev/stdout` by default; set to `/dev/null` to disable logging) | `/tmp/3proxy.log` | 95 | 96 | ## Helm Chart 97 | 98 | To install it on Kubernetes (K8s), please use the Helm chart from [ArtifactHUB][artifact-hub]. 99 | 100 | [artifact-hub]:https://artifacthub.io/packages/helm/proxy-3proxy/proxy-3proxy 101 | 102 | ## How to Use This Image 103 | 104 | Example usage: 105 | 106 | ```bash 107 | docker run --rm -d \ 108 | -p "3128:3128/tcp" \ 109 | -p "1080:1080/tcp" \ 110 | ghcr.io/tarampampam/3proxy:1 111 | ``` 112 | 113 | With authentication and custom resolver settings: 114 | 115 | ```bash 116 | docker run --rm -d \ 117 | -p "3128:3128/tcp" \ 118 | -p "1080:1080/tcp" \ 119 | -e "PROXY_LOGIN=evil" \ 120 | -e "PROXY_PASSWORD=live" \ 121 | -e "PRIMARY_RESOLVER=2001:4860:4860::8888" \ 122 | ghcr.io/tarampampam/3proxy:1 123 | ``` 124 | 125 | Docker compose example: 126 | 127 | ```yaml 128 | services: 129 | 3proxy: 130 | image: ghcr.io/tarampampam/3proxy:1 131 | environment: 132 | PROXY_LOGIN: evil 133 | PROXY_PASSWORD: live 134 | MAX_CONNECTIONS: 10000 135 | PROXY_PORT: 8000 136 | SOCKS_PORT: 8001 137 | PRIMARY_RESOLVER: 77.88.8.8 138 | SECONDARY_RESOLVER: 8.8.8.8 139 | ports: 140 | - '8000:8000/tcp' 141 | - '8001:8001/tcp' 142 | ``` 143 | 144 | ## Releasing 145 | 146 | Publishing a new version is straightforward: 147 | 148 | 1. Make the necessary changes in this repository. 149 | 2. "Publish" a new release on the repository's releases page. 150 | 151 | Docker images will be automatically built and published. 152 | 153 | > Note: The `latest` tag will be overwritten in both registries when a new release is published. 154 | 155 | ## Support 156 | 157 | [![Issues][badge_issues]][link_issues] 158 | [![Issues][badge_pulls]][link_pulls] 159 | 160 | If you encounter any issues, please [open an issue][link_create_issue] in this repository. 161 | 162 | ## License 163 | 164 | This project is licensed under the WTFPL. Use it freely and enjoy! 165 | 166 | [badge_issues]:https://img.shields.io/github/issues/tarampampam/3proxy-docker.svg?style=flat-square&maxAge=180 167 | [badge_pulls]:https://img.shields.io/github/issues-pr/tarampampam/3proxy-docker.svg?style=flat-square&maxAge=180 168 | [link_issues]:https://github.com/tarampampam/3proxy-docker/issues 169 | [link_pulls]:https://github.com/tarampampam/3proxy-docker/pulls 170 | [link_create_issue]:https://github.com/tarampampam/3proxy-docker/issues/new 171 | [link_docker_tags]:https://hub.docker.com/r/tarampampam/3proxy/tags 172 | [link_docker_hub]:https://hub.docker.com/r/tarampampam/3proxy/ 173 | [link_ghcr]:https://github.com/tarampampam/3proxy-docker/pkgs/container/3proxy 174 | [link_3proxy]:https://github.com/3proxy/3proxy 175 | -------------------------------------------------------------------------------- /deployments/helm/values.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "nameOverride": { 6 | "oneOf": [ 7 | {"type": "string", "minLength": 1}, 8 | {"type": "null"} 9 | ] 10 | }, 11 | "fullnameOverride": { 12 | "oneOf": [ 13 | {"type": "string", "minLength": 1}, 14 | {"type": "null"} 15 | ] 16 | }, 17 | "namespaceOverride": { 18 | "oneOf": [ 19 | {"type": "string", "minLength": 1}, 20 | {"type": "null"} 21 | ] 22 | }, 23 | "image": { 24 | "type": "object", 25 | "properties": { 26 | "repository": {"type": "string", "minLength": 1}, 27 | "tag": { 28 | "oneOf": [ 29 | {"type": "string", "minLength": 1}, 30 | {"type": "null"} 31 | ] 32 | }, 33 | "pullPolicy": { 34 | "oneOf": [ 35 | {"type": "string", "enum": ["Always", "IfNotPresent", "Never"]}, 36 | {"type": "null"} 37 | ] 38 | } 39 | } 40 | }, 41 | "deployment": { 42 | "type": "object", 43 | "properties": { 44 | "enabled": {"type": "boolean"}, 45 | "kind": {"type": "string"}, 46 | "replicas": {"type": "integer"}, 47 | "podAnnotations": { 48 | "type": "object", 49 | "additionalProperties": {"type": "string", "minLength": 1} 50 | }, 51 | "labels": { 52 | "type": "object", 53 | "additionalProperties": {"type": "string", "minLength": 1} 54 | }, 55 | "imagePullSecrets": { 56 | "type": "array", 57 | "items": { 58 | "type": "object", 59 | "properties": { 60 | "name": {"type": "string"} 61 | }, 62 | "minProperties": 1 63 | } 64 | }, 65 | "securityContext": { 66 | "type": "object", 67 | "properties": { 68 | "runAsNonRoot": {"type": "boolean"}, 69 | "runAsUser": {"type": "integer"}, 70 | "runAsGroup": {"type": "integer"} 71 | } 72 | }, 73 | "probe": { 74 | "type": "object", 75 | "properties": { 76 | "port": {"type": "string", "enum": ["http", "socks"]}, 77 | "interval": {"type": "integer"}, 78 | "initialDelay": {"type": "integer"} 79 | } 80 | }, 81 | "resources": { 82 | "type": "object", 83 | "properties": { 84 | "requests": { 85 | "type": "object", 86 | "properties": { 87 | "cpu": {"type": "string"}, 88 | "memory": {"type": "string"} 89 | } 90 | }, 91 | "limits": { 92 | "type": "object", 93 | "properties": { 94 | "cpu": {"type": "string"}, 95 | "memory": {"type": "string"} 96 | } 97 | } 98 | } 99 | }, 100 | "volumes": { 101 | "type": "array", 102 | "items": { 103 | "type": "object", 104 | "properties": { 105 | "name": {"type": "string"}, 106 | "configMap": { 107 | "type": "object", 108 | "properties": { 109 | "name": {"type": "string"} 110 | } 111 | }, 112 | "secret": { 113 | "type": "object", 114 | "properties": { 115 | "secretName": {"type": "string"} 116 | } 117 | }, 118 | "persistentVolumeClaim": { 119 | "type": "object", 120 | "properties": { 121 | "claimName": {"type": "string"} 122 | } 123 | } 124 | } 125 | } 126 | }, 127 | "volumeMounts": { 128 | "type": "array", 129 | "items": { 130 | "type": "object", 131 | "properties": { 132 | "name": {"type": "string"}, 133 | "mountPath": {"type": "string"}, 134 | "subPath": {"type": "string"}, 135 | "readOnly": {"type": "boolean"} 136 | } 137 | } 138 | }, 139 | "nodeSelector": { 140 | "type": "object", 141 | "additionalProperties": {"type": "string", "minLength": 1} 142 | }, 143 | "affinity": { 144 | "type": "object", 145 | "properties": { 146 | "nodeAffinity": {"type": "object"}, 147 | "podAffinity": {"type": "object"}, 148 | "podAntiAffinity": {"type": "object"} 149 | } 150 | }, 151 | "tolerations": { 152 | "type": "array", 153 | "items": { 154 | "type": "object", 155 | "properties": { 156 | "key": {"type": "string"}, 157 | "operator": {"type": "string"}, 158 | "value": {"type": "string"}, 159 | "effect": {"type": "string"} 160 | } 161 | } 162 | }, 163 | "env": { 164 | "type": "array", 165 | "items": { 166 | "type": "object", 167 | "properties": { 168 | "name": {"type": "string"}, 169 | "value": {"type": "string"}, 170 | "valueFrom": {"type": "object"} 171 | } 172 | } 173 | }, 174 | "args": { 175 | "type": "array", 176 | "items": { 177 | "type": "string", 178 | "minLength": 1 179 | } 180 | } 181 | } 182 | }, 183 | "service": { 184 | "type": "object", 185 | "properties": { 186 | "enabled": {"type": "boolean"}, 187 | "type": { 188 | "type": "string", 189 | "enum": ["ClusterIP", "NodePort", "LoadBalancer", "ExternalName"] 190 | }, 191 | "externalName": { 192 | "oneOf": [ 193 | {"type": "string", "minLength": 1}, 194 | {"type": "null"} 195 | ] 196 | }, 197 | "ports": { 198 | "type": "object", 199 | "properties": { 200 | "http": {"type": "integer", "minimum": 1, "maximum": 65535}, 201 | "socks": {"type": "integer", "minimum": 1, "maximum": 65535} 202 | } 203 | } 204 | } 205 | }, 206 | "ingress": { 207 | "type": "object", 208 | "properties": { 209 | "enabled": {"type": "boolean"}, 210 | "className": { 211 | "oneOf": [ 212 | {"type": "string", "minLength": 1}, 213 | {"type": "null"} 214 | ] 215 | }, 216 | "annotations": { 217 | "type": "object", 218 | "additionalProperties": {"type": "string", "minLength": 1} 219 | }, 220 | "hosts": { 221 | "type": "array", 222 | "items": { 223 | "type": "object", 224 | "properties": { 225 | "host": {"type": "string", "minLength": 1}, 226 | "paths": { 227 | "type": "array", 228 | "items": { 229 | "type": "object", 230 | "properties": { 231 | "path": {"type": "string", "minLength": 1}, 232 | "pathType": {"type": "string", "minLength": 1} 233 | } 234 | } 235 | } 236 | } 237 | } 238 | }, 239 | "tls": { 240 | "type": "array", 241 | "items": { 242 | "type": "object", 243 | "properties": { 244 | "hosts": {"type": "array"}, 245 | "secretName": {"type": "string"} 246 | } 247 | } 248 | } 249 | } 250 | }, 251 | "config": { 252 | "type": "object", 253 | "properties": { 254 | "log": { 255 | "type": "object", 256 | "properties": { 257 | "enabled": {"type": "boolean"}, 258 | "output": { 259 | "oneOf": [ 260 | {"type": "string", "minLength": 2, "examples": ["/dev/stdout"]}, 261 | {"type": "null"} 262 | ] 263 | } 264 | } 265 | }, 266 | "auth": { 267 | "type": "object", 268 | "properties": { 269 | "login": { 270 | "type": "object", 271 | "properties": { 272 | "plain": { 273 | "oneOf": [ 274 | {"type": "string", "minLength": 1}, 275 | {"type": "null"} 276 | ] 277 | }, 278 | "fromSecret": { 279 | "type": "object", 280 | "properties": { 281 | "enabled": {"type": "boolean"}, 282 | "secretName": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 283 | "secretKey": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 284 | } 285 | }, 286 | "fromConfigMap": { 287 | "type": "object", 288 | "properties": { 289 | "enabled": {"type": "boolean"}, 290 | "configMapName": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 291 | "configMapKey": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 292 | } 293 | } 294 | } 295 | }, 296 | "password": { 297 | "type": "object", 298 | "properties": { 299 | "plain": { 300 | "oneOf": [ 301 | {"type": "string", "minLength": 1}, 302 | {"type": "null"} 303 | ] 304 | }, 305 | "fromSecret": { 306 | "type": "object", 307 | "properties": { 308 | "enabled": {"type": "boolean"}, 309 | "secretName": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 310 | "secretKey": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 311 | } 312 | }, 313 | "fromConfigMap": { 314 | "type": "object", 315 | "properties": { 316 | "enabled": {"type": "boolean"}, 317 | "configMapName": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 318 | "configMapKey": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 319 | } 320 | } 321 | } 322 | }, 323 | "extraAccounts": { 324 | "type": "object", 325 | "properties": { 326 | "plain": { 327 | "type": "object", 328 | "additionalProperties": {"type": "string", "minLength": 1} 329 | }, 330 | "fromSecret": { 331 | "type": "object", 332 | "properties": { 333 | "enabled": {"type": "boolean"}, 334 | "secretName": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 335 | "secretKey": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 336 | } 337 | }, 338 | "fromConfigMap": { 339 | "type": "object", 340 | "properties": { 341 | "enabled": {"type": "boolean"}, 342 | "configMapName": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 343 | "configMapKey": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 344 | } 345 | } 346 | } 347 | } 348 | } 349 | }, 350 | "dns": { 351 | "type": "object", 352 | "properties": { 353 | "primaryResolver": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]}, 354 | "secondaryResolver": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 355 | } 356 | }, 357 | "limits": { 358 | "type": "object", 359 | "properties": { 360 | "maxConnections": {"oneOf": [{"type": "integer", "minimum": 1}, {"type": "null"}]} 361 | } 362 | }, 363 | "extraConfig": {"oneOf": [{"type": "string", "minLength": 1}, {"type": "null"}]} 364 | } 365 | } 366 | } 367 | } 368 | --------------------------------------------------------------------------------