Enable automatic updates

recommended

hosted installer

recommended
bash
curl -fsSL https://rsb-dashboard.tarik02.me/install/proxynode/kubernetes \
  | bash -s -- '' '' --auto-update
  • Then check /proxies to confirm the connection shows up.

manual install

proxynode.k8s.yaml
apiVersion: v1
kind: Secret
metadata:
  name: proxynode-config
type: Opaque
stringData:
  proxynode.yaml: |
    log:
      level: info

    endpoint: "wss://proxyhub.tarik02.me/join"
    username: ""
    password: ""

    egressWhitelist:
      - '{www.,}instagram.com:{80,443}'
      - '{www.,}facebook.com:{80,443}'
      - '{www.,}edge-chat.facebook.com:{80,443}'
      - '{www.,}web-chat-e2ee.instagram.com:{80,443}'
      - '{www.,}edge-chat.instagram.com:{80,443}'
      - '{www.,}graph.instagram.com:{80,443}'
      - '{www.,}gateway.instagram.com:{80,443}'
      - '{www.,}2ip.ua:{80,443}'
      - '{www.,}i.instagram.com:{80,443}'
      - 'cdninstagram.com:{80,443}'
      - '**.cdninstagram.com:{80,443}'
      - 'fbcdn.net:{80,443}'
      - '**.fbcdn.net:{80,443}'
      - '{www.,}fbsbx.com:{80,443}'
      - '{www.,}google.com:{80,443}'
      - 'gstatic.com:{80,443}'
      - '**.gstatic.com:{80,443}'
      - '{www.,}{api.,}{x,twitter}.com:{80,443}'
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: proxynode
spec:
  replicas: 1
  selector:
    matchLabels:
      app: proxynode
  template:
    metadata:
      labels:
        app: proxynode
    spec:
      containers:
        - name: proxynode
          image: ghcr.io/tarik02/proxyhub/proxynode:stable
          imagePullPolicy: Always
          workingDir: /app
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            readOnlyRootFilesystem: true
            runAsGroup: 1000
            runAsNonRoot: true
            runAsUser: 1000
          resources:
            limits:
              memory: 128Mi
          volumeMounts:
            - mountPath: /app/proxynode.yaml
              name: proxynode-config
              readOnly: true
              subPath: proxynode.yaml
      volumes:
        - name: proxynode-config
          secret:
            secretName: proxynode-config
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: proxynode-auto-update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: proxynode-auto-update
rules:
  - apiGroups:
      - apps
    resources:
      - deployments
    resourceNames:
      - proxynode
    verbs:
      - get
      - patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: proxynode-auto-update
subjects:
  - kind: ServiceAccount
    name: proxynode-auto-update
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: proxynode-auto-update
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: proxynode-auto-update
data:
  check-and-rollout.sh: |
    #!/bin/sh
    set -eu

    registry_host='ghcr.io'
    repository='tarik02/proxyhub/proxynode'
    tag='stable'
    deployment='proxynode'
    service_account_dir=/var/run/secrets/kubernetes.io/serviceaccount
    namespace="$(cat "$service_account_dir/namespace")"
    api_server="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}"

    auth_header="$(curl -fsSI "https://${registry_host}/v2/${repository}/manifests/${tag}" | tr -d '\r' | awk -F': ' 'tolower($1)=="www-authenticate"{print $2}')"
    realm="$(printf %s "$auth_header" | sed -n 's/^Bearer realm="\([^"]*\)".*/\1/p')"
    service="$(printf %s "$auth_header" | sed -n 's/.*service="\([^"]*\)".*/\1/p')"
    scope="$(printf %s "$auth_header" | sed -n 's/.*scope="\([^"]*\)".*/\1/p')"
    registry_token="$(curl -fsSL "${realm}?service=${service}&scope=${scope}" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')"
    latest_digest="$(curl -fsSI \
      -H "Authorization: Bearer ${registry_token}" \
      -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.index.v1+json, application/vnd.oci.image.manifest.v1+json' \
      "https://${registry_host}/v2/${repository}/manifests/${tag}" | tr -d '\r' | awk -F': ' 'tolower($1)=="docker-content-digest"{print $2}' | tail -n 1)"

    [ -n "$latest_digest" ] || {
        echo "failed to resolve the latest proxynode image digest" >&2
        exit 1
    }

    cluster_token="$(cat "$service_account_dir/token")"
    deployment_json="$(curl -fsSL --cacert "$service_account_dir/ca.crt" -H "Authorization: Bearer ${cluster_token}" "${api_server}/apis/apps/v1/namespaces/${namespace}/deployments/${deployment}")"
    current_digest="$(printf %s "$deployment_json" | sed -n 's|.*"proxyhub.io/last-image-digest":"\([^"]*\)".*|\1|p')"

    if [ "$current_digest" = "$latest_digest" ]; then
        echo "proxynode is already up to date ($latest_digest)"
        exit 0
    fi

    timestamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
    patch="$(cat <<EOF
    {"metadata":{"annotations":{"proxyhub.io/last-image-digest":"$latest_digest"}},"spec":{"template":{"metadata":{"annotations":{"proxyhub.io/last-image-digest":"$latest_digest","proxyhub.io/restarted-at":"$timestamp"}}}}}
    EOF
    )"

    curl -fsSL --cacert "$service_account_dir/ca.crt" \
      -X PATCH \
      -H "Authorization: Bearer ${cluster_token}" \
      -H "Content-Type: application/strategic-merge-patch+json" \
      --data "$patch" \
      "${api_server}/apis/apps/v1/namespaces/${namespace}/deployments/${deployment}" >/dev/null

    echo "rolled proxynode to $latest_digest"
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: proxynode-auto-update
spec:
  schedule: "*/5 * * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: proxynode-auto-update
          restartPolicy: Never
          containers:
            - name: updater
              image: curlimages/curl:8.12.1
              imagePullPolicy: IfNotPresent
              command:
                - sh
                - /scripts/check-and-rollout.sh
              volumeMounts:
                - name: scripts
                  mountPath: /scripts
                  readOnly: true
          volumes:
            - name: scripts
              configMap:
                name: proxynode-auto-update
                defaultMode: 493

apply

bash
kubectl apply -f proxynode.k8s.yaml

check logs

bash
kubectl logs deployment/proxynode -f
  • Then check /proxies to confirm the connection shows up.