# Apply: kubectl apply -f manifests/media/jdownloader.yaml # Delete: kubectl delete -f manifests/media/jdownloader.yaml # Description: JDownloader deployment with Ingress at jdownloader.home.arpa. apiVersion: apps/v1 kind: Deployment metadata: name: jdownloader namespace: downloads spec: replicas: 1 selector: matchLabels: app: jdownloader template: metadata: labels: app: jdownloader spec: nodeSelector: node-role: storage containers: - name: gluetun image: qmcgaw/gluetun:latest securityContext: capabilities: add: - NET_ADMIN env: - name: VPN_SERVICE_PROVIDER value: private internet access - name: VPN_TYPE value: openvpn - name: SERVER_REGIONS value: US Seattle,US Oregon,US Silicon Valley - name: OPENVPN_USER valueFrom: secretKeyRef: name: pia-credentials key: OPENVPN_USER - name: OPENVPN_PASSWORD valueFrom: secretKeyRef: name: pia-credentials key: OPENVPN_PASSWORD - name: FIREWALL_OUTBOUND_SUBNETS value: "10.42.0.0/16,10.43.0.0/16,192.168.7.0/24" - name: BLOCK_IPV6 value: "on" startupProbe: exec: command: - /gluetun-entrypoint - healthcheck periodSeconds: 10 failureThreshold: 18 livenessProbe: exec: command: - /gluetun-entrypoint - healthcheck periodSeconds: 30 failureThreshold: 3 readinessProbe: exec: command: - /gluetun-entrypoint - healthcheck periodSeconds: 10 failureThreshold: 3 volumeMounts: - name: tun mountPath: /dev/net/tun - name: jdownloader image: jlesage/jdownloader-2:latest ports: - containerPort: 5800 env: - name: USER_ID value: "1000" - name: GROUP_ID value: "1000" - name: TZ value: "Asia/Tokyo" volumeMounts: - name: config mountPath: /config - name: dl mountPath: /output - name: cnl-bridge image: python:3.12-alpine ports: - containerPort: 9666 volumeMounts: - name: config mountPath: /config command: - python3 - -c - | import http.server, urllib.parse, os, time WATCH_DIR = '/config/folderwatch' os.makedirs(WATCH_DIR, exist_ok=True) class Handler(http.server.BaseHTTPRequestHandler): def do_POST(self): if self.path != '/add': self.send_response(404); self.end_headers(); return length = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(length).decode() params = urllib.parse.parse_qs(body) urls = params.get('urls', []) if not urls: self.send_response(400); self.end_headers(); return fname = f'{WATCH_DIR}/{int(time.time()*1000)}.crawljob' with open(fname, 'w') as f: f.write(f'url={urls[0]}\nautoStart=TRUE\npackageName=subyshare\n') self.send_response(200); self.end_headers() self.wfile.write(b'Ok.') def log_message(self, *a): pass http.server.HTTPServer(('0.0.0.0', 9666), Handler).serve_forever() volumes: - name: tun hostPath: path: /dev/net/tun type: CharDevice - name: config hostPath: path: /data/jdownloader type: DirectoryOrCreate - name: dl hostPath: path: /mnt/storage/dl type: Directory --- apiVersion: v1 kind: Service metadata: name: jdownloader namespace: downloads spec: selector: app: jdownloader ports: - name: web port: 80 targetPort: 5800 - name: cnl-bridge port: 9666 targetPort: 9666 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: jdownloader namespace: downloads annotations: traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.tls: "true" cert-manager.io/cluster-issuer: internal-ca-issuer spec: ingressClassName: traefik tls: - secretName: jdownloader-tls hosts: - jdownloader.home.arpa rules: - host: jdownloader.home.arpa http: paths: - path: / pathType: Prefix backend: service: name: jdownloader port: number: 80 --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: jdownloader-cnl-tls namespace: downloads spec: secretName: jdownloader-cnl-tls issuerRef: name: internal-ca-issuer kind: ClusterIssuer dnsNames: - jdownloader.home.arpa --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: jdownloader-cnl namespace: downloads spec: entryPoints: - websecure routes: - match: Host(`jdownloader.home.arpa`) && PathPrefix(`/add`) kind: Rule services: - name: jdownloader port: 9666 tls: secretName: jdownloader-cnl-tls