apiVersion: v1 kind: ConfigMap metadata: name: loops-env namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/part-of: loops data: {{- range $key, $value := .Values.config }} {{ $key }}: {{ $value | quote }} {{- end }} --- apiVersion: v1 kind: ConfigMap metadata: name: loops-filesystem-config namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/part-of: loops data: filesystems.php: |- 'local', 'disks' => [ 'app' => [ 'driver' => 'local', 'root' => storage_path('app'), 'serve' => false, 'throw' => false, ], 'local' => [ 'driver' => 'local', 'root' => storage_path('app/private'), 'serve' => false, 'throw' => false, ], 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'throw' => false, ], 's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'throw' => false, 'options' => [ 'request_checksum_calculation' => env('AWS_REQUEST_CHECKSUM_CALCULATION', 'WHEN_SUPPORTED'), 'response_checksum_validation' => env('AWS_RESPONSE_CHECKSUM_VALIDATION', 'WHEN_SUPPORTED'), 'StorageClass' => env('AWS_STORAGE_CLASS', 'STANDARD'), ], ], 'backupS3' => [ 'driver' => 's3', 'key' => env('BACKUP_AWS_ACCESS_KEY_ID'), 'secret' => env('BACKUP_AWS_SECRET_ACCESS_KEY'), 'region' => env('BACKUP_AWS_DEFAULT_REGION'), 'bucket' => env('BACKUP_AWS_BUCKET'), 'url' => env('BACKUP_AWS_URL'), 'endpoint' => env('BACKUP_AWS_ENDPOINT'), 'visibility' => 'private', 'use_path_style_endpoint' => false, 'throw' => false, 'options' => [ 'request_checksum_calculation' => env('BACKUP_AWS_REQUEST_CHECKSUM_CALCULATION', 'WHEN_SUPPORTED'), 'response_checksum_validation' => env('BACKUP_AWS_RESPONSE_CHECKSUM_VALIDATION', 'WHEN_SUPPORTED'), ], ], 'assetCDN' => [ 'driver' => 's3', 'key' => env('ASSETCDN_AWS_ACCESS_KEY_ID'), 'secret' => env('ASSETCDN_AWS_SECRET_KEY'), 'region' => env('ASSETCDN_AWS_DEFAULT_REGION'), 'bucket' => env('ASSETCDN_AWS_BUCKET'), 'endpoint' => env('ASSETCDN_AWS_ENDPOINT'), 'use_path_style_endpoint' => env('ASSETCDN_AWS_USE_PATH_STYLE_ENDPOINT', false), 'visibility' => 'public', 'throw' => false, ], 'backupLocal' => [ 'driver' => 'local', 'root' => storage_path('app/backups'), 'visibility' => 'private', 'throw' => false, ], 'exports' => [ 'driver' => 'local', 'root' => storage_path('app/exports'), 'url' => env('APP_URL').'/storage/exports', 'visibility' => 'private', ], ], 'links' => [ public_path('storage') => storage_path('app/public'), ], ]; --- apiVersion: apps/v1 kind: Deployment metadata: name: loops-web namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: loops-web app.kubernetes.io/part-of: loops spec: replicas: {{ .Values.replicas.web }} strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: loops-web app.kubernetes.io/part-of: loops template: metadata: labels: app.kubernetes.io/name: loops-web app.kubernetes.io/part-of: loops spec: securityContext: fsGroup: 33 fsGroupChangePolicy: OnRootMismatch initContainers: - name: initialize-app-data image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }} imagePullPolicy: IfNotPresent command: - sh - -ec - >- mkdir -p /data/storage /data/bootstrap-cache && cp -rn /var/www/html/storage/. /data/storage/ && cp -rn /var/www/html/bootstrap/cache/. /data/bootstrap-cache/ && chown -R 33:33 /data securityContext: runAsUser: 0 runAsGroup: 0 volumeMounts: - name: app-data mountPath: /data containers: - name: loops image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }} imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 envFrom: - configMapRef: name: loops-env - secretRef: name: {{ .Values.runtimeSecret }} env: - name: AUTORUN_ENABLED value: "false" startupProbe: httpGet: path: /ping port: http # Initial Loops migrations can take longer than ten minutes. failureThreshold: 360 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: httpGet: path: /ping port: http periodSeconds: 10 timeoutSeconds: 5 livenessProbe: httpGet: path: /ping port: http initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 resources: requests: cpu: 500m memory: 768Mi limits: cpu: "3" memory: 3Gi volumeMounts: - name: app-data mountPath: /var/www/html/storage subPath: storage - name: app-data mountPath: /var/www/html/public/storage subPath: storage/app/public - name: app-data mountPath: /var/www/html/bootstrap/cache subPath: bootstrap-cache - name: filesystem-config mountPath: /var/www/html/config/filesystems.php subPath: filesystems.php - name: frontend-hotfix mountPath: /var/www/html/public/build/assets/index-Cng6wq5r.js subPath: index-Cng6wq5r.js readOnly: true - name: backend-hotfix mountPath: /var/www/html/app/Services/ForYouFeedService.php subPath: ForYouFeedService.php readOnly: true - name: backend-hotfix mountPath: /var/www/html/app/Services/ImpressionBloomFilterService.php subPath: ImpressionBloomFilterService.php readOnly: true - name: following-feed-hook mountPath: /var/www/html/app/Services/RandomizedFollowingFeedService.php subPath: RandomizedFollowingFeedService.php readOnly: true - name: following-feed-hook mountPath: /var/www/html/app/Http/Controllers/Api/RandomizedFeedController.php subPath: RandomizedFeedController.php readOnly: true - name: following-feed-hook mountPath: /var/www/html/app/Providers/FollowingFeedServiceProvider.php subPath: FollowingFeedServiceProvider.php readOnly: true - name: following-feed-hook mountPath: /var/www/html/bootstrap/providers.php subPath: providers.php readOnly: true volumes: - name: app-data persistentVolumeClaim: claimName: app-data - name: filesystem-config configMap: name: loops-filesystem-config - name: frontend-hotfix configMap: name: loops-frontend-hotfix - name: backend-hotfix configMap: name: loops-backend-hotfix - name: following-feed-hook configMap: name: loops-following-feed-hook --- apiVersion: v1 kind: Service metadata: name: loops-web namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: loops-web app.kubernetes.io/part-of: loops spec: selector: app.kubernetes.io/name: loops-web app.kubernetes.io/part-of: loops ports: - name: http port: 80 targetPort: http --- apiVersion: apps/v1 kind: Deployment metadata: name: loops-horizon namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: loops-horizon app.kubernetes.io/part-of: loops spec: replicas: {{ .Values.replicas.horizon }} strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: loops-horizon app.kubernetes.io/part-of: loops template: metadata: labels: app.kubernetes.io/name: loops-horizon app.kubernetes.io/part-of: loops spec: securityContext: fsGroup: 33 fsGroupChangePolicy: OnRootMismatch containers: - name: horizon image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }} imagePullPolicy: IfNotPresent command: - php - artisan - queue:work - redis - --queue=default,activitypub-out,activitypub-in,actor-update,activitypub-delete-fanout,notify,push,klipy,email-verification - --sleep=3 - --tries=3 - --timeout=300 - --max-time=3600 - --memory=512 envFrom: - configMapRef: name: loops-env - secretRef: name: {{ .Values.runtimeSecret }} env: - name: AUTORUN_ENABLED value: "false" resources: requests: cpu: 200m memory: 512Mi limits: cpu: "1" memory: 1Gi volumeMounts: - name: app-data mountPath: /var/www/html/storage subPath: storage - name: app-data mountPath: /var/www/html/bootstrap/cache subPath: bootstrap-cache - name: filesystem-config mountPath: /var/www/html/config/filesystems.php subPath: filesystems.php volumes: - name: app-data persistentVolumeClaim: claimName: app-data - name: filesystem-config configMap: name: loops-filesystem-config --- apiVersion: apps/v1 kind: Deployment metadata: name: loops-transcoder namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: loops-transcoder app.kubernetes.io/component: transcoder app.kubernetes.io/part-of: loops spec: replicas: {{ .Values.replicas.transcoder }} strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: loops-transcoder app.kubernetes.io/part-of: loops template: metadata: labels: app.kubernetes.io/name: loops-transcoder app.kubernetes.io/component: transcoder app.kubernetes.io/part-of: loops spec: {{- with .Values.transcoder.nodeSelector }} nodeSelector: {{ toYaml . | indent 8 }} {{- end }} {{- with .Values.transcoder.tolerations }} tolerations: {{ toYaml . | indent 8 }} {{- end }} terminationGracePeriodSeconds: 900 securityContext: fsGroup: 33 fsGroupChangePolicy: OnRootMismatch containers: - name: remote-video image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }} imagePullPolicy: IfNotPresent command: - php - artisan - queue:work - redis - --queue=remote-video - --sleep=3 - --tries=3 - --timeout=900 - --max-time=3600 - --memory=4096 envFrom: - configMapRef: name: loops-env - secretRef: name: {{ .Values.runtimeSecret }} env: - name: AUTORUN_ENABLED value: "false" resources: requests: cpu: "4" memory: 2Gi limits: cpu: "10" memory: 8Gi volumeMounts: - name: app-data mountPath: /var/www/html/storage subPath: storage - name: app-data mountPath: /var/www/html/bootstrap/cache subPath: bootstrap-cache - name: filesystem-config mountPath: /var/www/html/config/filesystems.php subPath: filesystems.php - name: local-media image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }} imagePullPolicy: IfNotPresent command: - php - artisan - queue:work - redis - --queue=video-processing,audio-processing - --sleep=3 - --tries=3 - --timeout=900 - --max-time=3600 - --memory=4096 envFrom: - configMapRef: name: loops-env - secretRef: name: {{ .Values.runtimeSecret }} env: - name: AUTORUN_ENABLED value: "false" resources: requests: cpu: "2" memory: 2Gi limits: cpu: "10" memory: 8Gi volumeMounts: - name: app-data mountPath: /var/www/html/storage subPath: storage - name: app-data mountPath: /var/www/html/bootstrap/cache subPath: bootstrap-cache - name: filesystem-config mountPath: /var/www/html/config/filesystems.php subPath: filesystems.php volumes: - name: app-data persistentVolumeClaim: claimName: app-data - name: filesystem-config configMap: name: loops-filesystem-config --- apiVersion: apps/v1 kind: Deployment metadata: name: loops-scheduler namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: loops-scheduler app.kubernetes.io/part-of: loops spec: replicas: {{ .Values.replicas.scheduler }} strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: loops-scheduler app.kubernetes.io/part-of: loops template: metadata: labels: app.kubernetes.io/name: loops-scheduler app.kubernetes.io/part-of: loops spec: securityContext: fsGroup: 33 fsGroupChangePolicy: OnRootMismatch containers: - name: scheduler image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }} imagePullPolicy: IfNotPresent command: - php - artisan - schedule:work envFrom: - configMapRef: name: loops-env - secretRef: name: {{ .Values.runtimeSecret }} env: - name: AUTORUN_ENABLED value: "false" resources: requests: cpu: 100m memory: 256Mi limits: cpu: "1" memory: 1Gi volumeMounts: - name: app-data mountPath: /var/www/html/storage subPath: storage - name: app-data mountPath: /var/www/html/bootstrap/cache subPath: bootstrap-cache - name: filesystem-config mountPath: /var/www/html/config/filesystems.php subPath: filesystems.php volumes: - name: app-data persistentVolumeClaim: claimName: app-data - name: filesystem-config configMap: name: loops-filesystem-config {{- if .Values.ingress.enabled }} --- apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: loops-android-for-you namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/part-of: loops spec: replacePathRegex: regex: ^/api/v1/feed/for-you$ replacement: /api/v0/feed/recommended --- apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: loops-upload-buffer namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/part-of: loops spec: buffering: maxRequestBodyBytes: 524288000 memRequestBodyBytes: 2097152 --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: {{ .Values.ingress.name }} namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/part-of: loops spec: entryPoints: - {{ .Values.ingress.entryPoint }} routes: - kind: Rule match: Host(`{{ .Values.domain }}`) && Path(`/api/v1/feed/for-you`) priority: 100 middlewares: - name: loops-android-for-you - name: loops-upload-buffer services: - name: loops-web port: 80 - kind: Rule match: Host(`{{ .Values.domain }}`) middlewares: - name: loops-upload-buffer services: - name: loops-web port: 80 tls: {} {{- end }}