diff --git a/README.md b/README.md index 1ffe93c..1616249 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ Async Telegram bot for selling and extending Marzban VPN subscriptions. ## Features + - Plans: - 1 month = ⭐️100 - 3 months = ⭐️270 @@ -26,6 +27,7 @@ Async Telegram bot for selling and extending Marzban VPN subscriptions. - traffic usage/total quota ## Admin user management + - `/select_user ` — select user for further updates and show current values. - `/selected_user` — show the currently selected user and current values. - `/set_expire ` — set selected user expiration (UTC). @@ -33,6 +35,7 @@ Async Telegram bot for selling and extending Marzban VPN subscriptions. - `/set_multiplier ` — set selected user price multiplier. ## Setup + ```bash python -m venv .venv source .venv/bin/activate @@ -41,6 +44,7 @@ cp .env.example .env ``` Fill `.env` and run: + ```bash set -a source .env @@ -90,57 +94,7 @@ git tag v0.1.0 git push origin main v0.1.0 ``` -### K3s deployment - -Create the namespace first: - -```bash -kubectl apply -f k8s/namespace.yaml -``` - -Create or update the application Secret from the local `.env` file. The Secret -is never stored in Git: - -```bash -kubectl -n tt-simple create secret generic tt-simple-env \ - --from-env-file=.env \ - --dry-run=client -o yaml | kubectl apply -f - -``` - -For a private GHCR package, create a classic GitHub token with `read:packages` -and create the registry pull secret: - -```bash -read -rsp "GHCR token: " GHCR_TOKEN -echo -kubectl -n tt-simple create secret docker-registry ghcr-creds \ - --docker-server=ghcr.io \ - --docker-username=kr0sh512 \ - --docker-password="$GHCR_TOKEN" \ - --dry-run=client -o yaml | kubectl apply -f - -unset GHCR_TOKEN -``` - -If the package is public, remove `imagePullSecrets` from -`k8s/tt-simple.yaml`. Deploy the PVC and bot after publishing the `v0.1.0` -image: - -```bash -kubectl apply -f k8s/tt-simple.yaml -kubectl -n tt-simple rollout status deployment/tt-simple -kubectl -n tt-simple logs -f deployment/tt-simple -``` - -The manifest injects the Secret, mounts persistent storage at `/data`, and sets -`DB_PATH=/data/stats.db`. To use the shared non-Russian proxy, add this to the -local `.env` before updating `tt-simple-env`: - -```dotenv -HTTP_PROXY=http://shared-http-proxy.proxy.svc.cluster.local:3128 -``` - -The included namespace and pod labels satisfy the proxy `NetworkPolicy`. - ## Notes + - Telegram Stars invoices use `currency="XTR"` and empty `provider_token`. - Local SQLite database stores only payment statistics. User state is read from Marzban API. diff --git a/k8s/namespace.yaml b/k8s/namespace.yaml deleted file mode 100644 index 934c622..0000000 --- a/k8s/namespace.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: tt-simple - labels: - # Required by the shared proxy NetworkPolicy when HTTP_PROXY is enabled. - proxy-access: "true" diff --git a/k8s/tt-simple.yaml b/k8s/tt-simple.yaml deleted file mode 100644 index e9eebcd..0000000 --- a/k8s/tt-simple.yaml +++ /dev/null @@ -1,87 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: tt-simple-data - namespace: tt-simple -spec: - accessModes: - - ReadWriteOnce - storageClassName: local-path - resources: - requests: - storage: 256Mi ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: tt-simple - namespace: tt-simple - labels: - app.kubernetes.io/name: tt-simple -spec: - replicas: 1 - strategy: - type: Recreate - revisionHistoryLimit: 2 - selector: - matchLabels: - app.kubernetes.io/name: tt-simple - template: - metadata: - labels: - app.kubernetes.io/name: tt-simple - # Required by the shared proxy NetworkPolicy when HTTP_PROXY is enabled. - proxy-client: "true" - spec: - automountServiceAccountToken: false - terminationGracePeriodSeconds: 30 - imagePullSecrets: - - name: ghcr-creds - securityContext: - runAsNonRoot: true - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 - fsGroupChangePolicy: OnRootMismatch - seccompProfile: - type: RuntimeDefault - containers: - - name: bot - # Replace this with an immutable release tag or image digest. - image: ghcr.io/kr0sh512/tt-simple:v0.1.0 - imagePullPolicy: IfNotPresent - envFrom: - - secretRef: - name: tt-simple-env - env: - - name: DB_PATH - value: /data/stats.db - - name: PYTHONUNBUFFERED - value: "1" - - name: PYTHONDONTWRITEBYTECODE - value: "1" - resources: - requests: - cpu: 25m - memory: 64Mi - limits: - cpu: 250m - memory: 256Mi - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - volumeMounts: - - name: data - mountPath: /data - - name: tmp - mountPath: /tmp - volumes: - - name: data - persistentVolumeClaim: - claimName: tt-simple-data - - name: tmp - emptyDir: - sizeLimit: 32Mi