apiVersion: apps/v1
kind: Deployment
metadata:
  name: ib-gateway
  namespace: foxhunt
  labels:
    app: ib-gateway
    app.kubernetes.io/part-of: foxhunt
spec:
  # LIVE — the sole IBKR paper execution gateway (fxhnt-ibkr-rebalancer -> :4004). Keep replicas: 1.
  # (Was replicas: 0 "dev-mode paused" while the live cluster ran 1 — a manifest/cluster drift that would
  # have scaled IBKR execution to ZERO on any re-apply. Corrected 2026-07-14.)
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: ib-gateway
  template:
    metadata:
      labels:
        app: ib-gateway
        app.kubernetes.io/part-of: foxhunt
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
        # gnzsnz image runs as the non-root `ibgateway` user (UID/GID 1000); fsGroup makes the mounted
        # tws_settings PVC group-writable so IBC can write jts.ini (a fresh PVC is root-owned otherwise ->
        # "Permission denied" crashloop).
        fsGroup: 1000
      # image is public (ghcr.io/gnzsnz/ib-gateway) — no pull secret needed on bizworx
      # (the legacy gitlab-registry secret does not exist there).
      nodeSelector:
        k8s.scaleway.com/pool-name: large
      containers:
        - name: ib-gateway
          image: ghcr.io/gnzsnz/ib-gateway:stable
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          ports:
            - name: tws-api
              containerPort: 4002
              protocol: TCP
            - name: tws-api-socat
              containerPort: 4004
              protocol: TCP
            - name: vnc
              containerPort: 5900
              protocol: TCP
          env:
            - name: TWS_USERID
              valueFrom:
                secretKeyRef:
                  name: ibkr-credentials
                  key: username
            - name: TWS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ibkr-credentials
                  key: password
            - name: TRADING_MODE
              value: "paper"
            - name: TWS_ACCEPT_INCOMING
              value: "accept"
            - name: READ_ONLY_API
              value: "no"
            - name: TWOFA_TIMEOUT_ACTION
              value: "restart"
            - name: EXISTING_SESSION_DETECTED_ACTION
              value: "primaryoverride"
            # Daily IN-PLACE restart via IBC — "does not require daily 2FA validation" (gnzsnz docs), so the
            # container no longer EXITS on IBKR's forced daily reset (the cause of the ~daily container churn +
            # full re-login each time). 08:00 UTC is clear of the 14:35 rebalancer + 23:30 nightly windows.
            - name: TIME_ZONE
              value: "Etc/UTC"
            # MUST be zero-padded hh:mm (IBC's parser rejects "8:00 AM" with "Auto restart time setting must be
            # hh:mm AM or hh:mm PM" — the rejection left the daily auto-restart UNCONFIGURED, so the gateway
            # churned ~16 restarts/day instead of one clean daily cycle. Verified in the pod log 2026-07-20.)
            - name: AUTO_RESTART_TIME
              value: "08:00 AM"
            # Persist jts.ini + IBC config across pod restarts (a fresh empty volume just does a clean first-run
            # login) so settings survive a deploy/reschedule instead of being rebuilt each time.
            - name: TWS_SETTINGS_PATH
              value: "/home/ibgateway/tws_settings"
            - name: VNC_SERVER_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ibkr-credentials
                  key: vnc-password
                  optional: true
          resources:
            requests:
              memory: "1Gi"
              cpu: "500m"
            limits:
              memory: "2Gi"
              cpu: "1000m"
          readinessProbe:
            tcpSocket:
              port: 4002
            initialDelaySeconds: 90
            periodSeconds: 10
          livenessProbe:
            tcpSocket:
              port: 4002
            initialDelaySeconds: 120
            periodSeconds: 30
            # 6×30s = 180s tolerance: the daily auto-restart + IBKR reauth window drops port 4002 for up to a
            # couple of minutes; too tight a threshold would k8s-kill the pod mid-reauth and compound the churn.
            failureThreshold: 6
          volumeMounts:
            - name: tws-settings
              mountPath: /home/ibgateway/tws_settings
      volumes:
        - name: tws-settings
          persistentVolumeClaim:
            claimName: ib-gateway-settings
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ib-gateway-settings
  namespace: foxhunt
  labels:
    app: ib-gateway
    app.kubernetes.io/part-of: foxhunt
spec:
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: ib-gateway
  namespace: foxhunt
  labels:
    app: ib-gateway
spec:
  selector:
    app: ib-gateway
  ports:
    - name: tws-api
      port: 4002
      targetPort: 4002
    - name: tws-api-socat
      port: 4004
      targetPort: 4004
    - name: vnc
      port: 5900
      targetPort: 5900
  type: ClusterIP
