apiVersion: v1 kind: PersistentVolumeClaim metadata: name: data namespace: {{ www_namespace }} spec: accessModes: [ReadWriteMany] resources: requests: storage: {{ www_archive_storage_size }} --- apiVersion: v1 kind: ConfigMap metadata: name: httpd namespace: {{ www_namespace }} data: httpd.conf: {{ lookup('ansible.builtin.file', role_path ~ '/files/httpd.conf') | to_json }} membership.conf: {{ _www_proxy_config | to_json }} --- apiVersion: apps/v1 kind: Deployment metadata: name: httpd namespace: {{ www_namespace }} spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: httpd template: metadata: labels: app: httpd annotations: www/config-revision: {{ (lookup('ansible.builtin.file', role_path ~ '/files/httpd.conf') ~ _www_proxy_config ~ www_rollout_revision ~ www_repo_url ~ www_repo_version) | hash('sha256') | to_json }} spec: automountServiceAccountToken: false {% if www_image_pull_secrets | length %} imagePullSecrets: {{ www_image_pull_secrets | to_nice_yaml | indent(8, true) }} {% endif %} initContainers: - name: init image: {{ www_source_image | to_json }} command: - /bin/bash - -ec - | apt-get update apt-get install --no-install-recommends -y git ca-certificates git clone --depth 1 -- "$WWW_REPO_URL" /tmp/www git -C /tmp/www fetch --depth 1 origin "$WWW_REPO_VERSION" git -C /tmp/www checkout --detach FETCH_HEAD # Never delete /data: it contains persistent archives, not just # this repository's static site. Copy hidden site assets too. cp -a /tmp/www/htdocs/. /data/ env: - name: WWW_REPO_URL value: {{ www_repo_url | to_json }} - name: WWW_REPO_VERSION value: {{ www_repo_version | to_json }} volumeMounts: - name: data mountPath: /data containers: - name: httpd image: {{ www_httpd_image | to_json }} imagePullPolicy: Always ports: - name: http containerPort: 80 - name: metrics containerPort: 9117 readinessProbe: tcpSocket: {port: http} volumeMounts: - name: data mountPath: /usr/local/apache2/htdocs - name: httpd mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf readOnly: true - name: httpd mountPath: /usr/local/apache2/conf/extra/membership.conf subPath: membership.conf readOnly: true volumes: - name: data persistentVolumeClaim: claimName: data - name: httpd configMap: name: httpd --- apiVersion: v1 kind: Service metadata: name: prometheus namespace: {{ www_namespace }} spec: type: ClusterIP selector: app: httpd ports: - name: http port: 9117 targetPort: metrics --- apiVersion: v1 kind: Service metadata: name: httpd namespace: {{ www_namespace }} spec: type: ClusterIP selector: app: httpd ports: - name: http port: 80 targetPort: http {% if www_onion_enabled %} --- apiVersion: tor.k8s.torproject.org/v1alpha2 kind: OnionService metadata: name: httpd namespace: {{ www_namespace }} spec: version: 3 rules: - port: number: 80 backend: service: name: httpd port: number: 80 {% endif %} --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: www namespace: {{ www_namespace }} annotations: cert-manager.io/cluster-issuer: {{ www_cluster_issuer | to_json }} nginx.ingress.kubernetes.io/ssl-redirect: "true" # Redact email verification tokens and OIDC codes at the edge, not only in # Apache/Gunicorn. Do not enable request-body/error tracing for /members/. nginx.ingress.kubernetes.io/enable-access-log: "false" # Apache retains 256 KiB for non-profile member routes. nginx.ingress.kubernetes.io/proxy-body-size: "2m" nginx.ingress.kubernetes.io/proxy-read-timeout: "120" spec: ingressClassName: {{ www_ingress_class }} rules: - host: {{ www_hostname }} http: paths: - pathType: Prefix path: / backend: service: name: httpd port: number: 80 tls: - hosts: [{{ www_hostname }}] secretName: www {% if www_redirect_hostnames | length > 0 %} --- # Send browsers on alias hostnames (e.g. the apex, whose /.well-known/matrix/* # paths are owned by another ingress) to the canonical origin. Exact/longer # paths on the same host in other ingresses still take precedence over "/". # A snippet is used because the controller's annotation validation rejects # "$request_uri" in permanent-redirect. apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: www-redirect namespace: {{ www_namespace }} annotations: cert-manager.io/cluster-issuer: {{ www_cluster_issuer | to_json }} nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/enable-access-log: "false" nginx.ingress.kubernetes.io/configuration-snippet: {{ ("return 301 https://" ~ www_hostname ~ "$request_uri;") | to_json }} spec: ingressClassName: {{ www_ingress_class }} rules: {% for host in www_redirect_hostnames %} - host: {{ host }} http: paths: - pathType: Prefix path: / backend: service: name: httpd port: number: 80 {% endfor %} tls: - hosts: {{ www_redirect_hostnames | to_json }} secretName: www-redirect {% endif %}