apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "yourls-nginx.fullname" . }} labels: {{- include "yourls-nginx.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "yourls-nginx.selectorLabels" . | nindent 6 }} template: metadata: labels: {{- include "yourls-nginx.selectorLabels" . | nindent 8 }} spec: automountServiceAccountToken: false securityContext: fsGroup: 82 fsGroupChangePolicy: "OnRootMismatch" initContainers: - name: yourls-init image: "{{ .Values.image.yourls.registry }}/{{ .Values.image.yourls.repository }}:{{ .Values.image.yourls.tag }}" imagePullPolicy: {{ .Values.image.yourls.pullPolicy }} command: ["/bin/sh", "-c"] args: - | set -e echo "=== YOURLS initialization started ===" echo "Copying YOURLS core files..." # user/ ディレクトリ(プラグイン・ページ・言語・設定)は別ボリュームで扱うため、 # コアファイルのコピー対象から除外する。 for item in /usr/src/yourls/*; do name=$(basename "$item") if [ "$name" = "user" ]; then continue fi cp -r "$item" /var/www/html/ done echo "Core files copied" mkdir -p /var/www/html/user # user/plugins, user/pages, user/languages はPVC(またはemptyDir)。 # 初回(空)の場合のみYOURLS同梱のデフォルト内容(サンプルプラグイン等)を投入し、 # 以降は管理画面経由で追加/削除された内容をPod再起動のたびに上書きしない。 for sub in plugins pages languages; do target="/var/www/html/user/$sub" mkdir -p "$target" if [ -z "$(ls -A "$target" 2>/dev/null)" ]; then echo "Seeding default user/$sub (first run)" cp -rp "/usr/src/yourls/user/$sub/"* "$target/" 2>/dev/null || true else echo "user/$sub already has content, preserving" fi done # user/config.phpは環境変数(getenv)を読むだけのテンプレートで、YOURLS自体が # 書き込むことはないため、永続化せず毎回生成し直す(values.yaml変更を確実に反映)。 echo "Generating user/config.php from environment variables..." cp /usr/src/yourls/user/config-container.php /var/www/html/user/config.php echo "=== YOURLS initialization completed ===" securityContext: runAsUser: 82 runAsGroup: 82 runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] volumeMounts: - name: yourls-data mountPath: /var/www/html - name: yourls-persistent mountPath: /var/www/html/user/plugins subPath: plugins - name: yourls-persistent mountPath: /var/www/html/user/pages subPath: pages - name: yourls-persistent mountPath: /var/www/html/user/languages subPath: languages containers: - name: nginx image: "{{ .Values.image.nginx.registry }}/{{ .Values.image.nginx.repository }}:{{ .Values.image.nginx.tag }}" imagePullPolicy: {{ .Values.image.nginx.pullPolicy }} ports: - name: http containerPort: 80 protocol: TCP volumeMounts: - name: yourls-data mountPath: /var/www/html readOnly: true - name: yourls-persistent mountPath: /var/www/html/user/plugins subPath: plugins readOnly: true - name: yourls-persistent mountPath: /var/www/html/user/pages subPath: pages readOnly: true - name: yourls-persistent mountPath: /var/www/html/user/languages subPath: languages readOnly: true - name: nginx-config mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf {{- if .Values.healthCheck.enabled }} livenessProbe: {{- toYaml .Values.healthCheck.livenessProbe | nindent 12 }} readinessProbe: {{- toYaml .Values.healthCheck.readinessProbe | nindent 12 }} {{- end }} resources: {{- toYaml .Values.resources.nginx | nindent 12 }} - name: yourls image: "{{ .Values.image.yourls.registry }}/{{ .Values.image.yourls.repository }}:{{ .Values.image.yourls.tag }}" imagePullPolicy: {{ .Values.image.yourls.pullPolicy }} command: ["php-fpm"] securityContext: runAsUser: 82 runAsGroup: 82 runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] env: - name: YOURLS_SITE value: {{ .Values.yourls.site | quote }} - name: YOURLS_USER value: {{ .Values.yourls.admin.username | quote }} - name: YOURLS_PASS valueFrom: secretKeyRef: {{- if .Values.yourls.admin.existingSecret }} name: {{ .Values.yourls.admin.existingSecret }} key: {{ .Values.yourls.admin.existingSecretKey }} {{- else }} name: {{ include "yourls-nginx.secretName" . }} key: admin-password {{- end }} - name: YOURLS_COOKIEKEY valueFrom: secretKeyRef: name: {{ include "yourls-nginx.secretName" . }} key: cookiekey - name: YOURLS_DB_HOST value: {{ printf "%s:%v" .Values.database.host .Values.database.port | quote }} - name: YOURLS_DB_USER value: {{ .Values.database.user | quote }} - name: YOURLS_DB_PASS valueFrom: secretKeyRef: {{- if .Values.database.existingSecret }} name: {{ .Values.database.existingSecret }} key: {{ .Values.database.existingSecretKey }} {{- else }} name: {{ include "yourls-nginx.secretName" . }} key: db-password {{- end }} - name: YOURLS_DB_NAME value: {{ .Values.database.name | quote }} - name: YOURLS_DB_PREFIX value: {{ .Values.database.tablePrefix | quote }} - name: YOURLS_HOURS_OFFSET value: {{ .Values.yourls.hoursOffset | quote }} - name: YOURLS_LANG value: {{ .Values.yourls.lang | quote }} - name: YOURLS_PRIVATE value: {{ .Values.yourls.privateMode | quote }} {{- with .Values.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} {{- with .Values.extraEnvFrom }} envFrom: {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: # YOURLS本体はinitContainerが書き込んだ後は変更不要なため読み取り専用でマウントする # (実行時に侵害された場合でも配信コードの改ざん・永続化を防ぐ多層防御)。 - name: yourls-data mountPath: /var/www/html readOnly: true - name: yourls-persistent mountPath: /var/www/html/user/plugins subPath: plugins - name: yourls-persistent mountPath: /var/www/html/user/pages subPath: pages - name: yourls-persistent mountPath: /var/www/html/user/languages subPath: languages resources: {{- toYaml .Values.resources.yourls | nindent 12 }} volumes: - name: yourls-data emptyDir: {} - name: yourls-persistent {{- if .Values.persistence.enabled }} persistentVolumeClaim: claimName: {{ include "yourls-nginx.fullname" . }}-pvc {{- else }} emptyDir: {} {{- end }} - name: nginx-config configMap: name: {{ include "yourls-nginx.fullname" . }}-nginx-config {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }}