diff --git a/polis/app.yaml b/polis/app.yaml new file mode 100644 index 0000000..d2b4e6b --- /dev/null +++ b/polis/app.yaml @@ -0,0 +1,4 @@ +name: polis +is: polis +description: Pol.is is an open-source large-scale conversational survey tool that helps communities gather, understand, and act on the expressed opinions of large groups of people. +latest: dev diff --git a/polis/versions/dev/db-init-job.yaml b/polis/versions/dev/db-init-job.yaml new file mode 100644 index 0000000..2a6ef83 --- /dev/null +++ b/polis/versions/dev/db-init-job.yaml @@ -0,0 +1,58 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: polis-db-init + labels: + component: db-init +spec: + template: + metadata: + labels: + component: db-init + spec: + restartPolicy: OnFailure + securityContext: + runAsNonRoot: true + runAsUser: 999 + runAsGroup: 999 + seccompProfile: + type: RuntimeDefault + containers: + - name: postgres-init + image: postgres:16 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + readOnlyRootFilesystem: false + env: + - name: PGHOST + value: {{ .db.host }} + - name: PGUSER + value: postgres + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: polis-secrets + key: postgres.password + - name: DB_NAME + value: {{ .db.name }} + - name: DB_USER + value: {{ .db.user }} + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: polis-secrets + key: dbPassword + command: + - /bin/bash + - -c + - | + set -e + until pg_isready; do sleep 2; done + psql -c "CREATE DATABASE ${DB_NAME};" || echo "Database already exists" + psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" || echo "User already exists" + psql -c "ALTER USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" + psql -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};" + psql -d ${DB_NAME} -c "GRANT ALL ON SCHEMA public TO ${DB_USER};" + echo "Done" diff --git a/polis/versions/dev/deployment-fileserver.yaml b/polis/versions/dev/deployment-fileserver.yaml new file mode 100644 index 0000000..ebbfcef --- /dev/null +++ b/polis/versions/dev/deployment-fileserver.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: polis-file-server +spec: + replicas: 1 + selector: + matchLabels: + component: file-server + template: + metadata: + labels: + component: file-server + spec: + securityContext: + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + containers: + - name: polis-file-server + image: compdemocracy/polis-file-server:dev + ports: + - name: http + containerPort: 8080 + protocol: TCP + env: + - name: API_SERVER_PORT + value: "5000" + - name: STATIC_FILES_PORT + value: "8080" + resources: + limits: + cpu: 500m + memory: 256Mi + ephemeral-storage: 512Mi + requests: + cpu: 50m + memory: 64Mi + ephemeral-storage: 50Mi + securityContext: + readOnlyRootFilesystem: false + restartPolicy: Always diff --git a/polis/versions/dev/deployment-math.yaml b/polis/versions/dev/deployment-math.yaml new file mode 100644 index 0000000..0ef7ee4 --- /dev/null +++ b/polis/versions/dev/deployment-math.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: polis-math +spec: + replicas: 1 + selector: + matchLabels: + component: math + template: + metadata: + labels: + component: math + spec: + securityContext: + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + containers: + - name: polis-math + image: compdemocracy/polis-math:dev + env: + - name: MATH_ENV + value: prod + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: polis-secrets + key: dbUrl + - name: DATABASE_IGNORE_SSL + value: "true" + resources: + limits: + cpu: 1000m + memory: 2Gi + ephemeral-storage: 1Gi + requests: + cpu: 50m + memory: 256Mi + ephemeral-storage: 50Mi + securityContext: + readOnlyRootFilesystem: false + restartPolicy: Always diff --git a/polis/versions/dev/deployment-server.yaml b/polis/versions/dev/deployment-server.yaml new file mode 100644 index 0000000..ad6c023 --- /dev/null +++ b/polis/versions/dev/deployment-server.yaml @@ -0,0 +1,101 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: polis-server +spec: + replicas: 1 + selector: + matchLabels: + component: server + template: + metadata: + labels: + component: server + spec: + securityContext: + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + containers: + - name: polis-server + image: compdemocracy/polis-server:dev + ports: + - name: http + containerPort: 5000 + protocol: TCP + env: + - name: NODE_ENV + value: production + - name: DEV_MODE + value: "false" + - name: MATH_ENV + value: prod + - name: API_SERVER_PORT + value: "5000" + - name: API_PROD_HOSTNAME + value: {{ .domain }} + - name: DOMAIN_OVERRIDE + value: {{ .domain }} + - name: STATIC_FILES_HOST + value: {{ .domain }} + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: polis-secrets + key: dbUrl + - name: POLIS_FROM_ADDRESS + value: {{ .adminEmail }} + - name: ADMIN_EMAILS + value: '["{{ .adminEmail }}"]' + - name: LOGIN_CODE_PEPPER + valueFrom: + secretKeyRef: + name: polis-secrets + key: loginCodePepper + - name: JWT_PRIVATE_KEY + valueFrom: + secretKeyRef: + name: polis-secrets + key: jwtPrivateKey + - name: JWT_PUBLIC_KEY + valueFrom: + secretKeyRef: + name: polis-secrets + key: jwtPublicKey + - name: POLIS_JWT_ISSUER + value: https://{{ .domain }}/ + - name: POLIS_JWT_AUDIENCE + value: participants + - name: AUTH_ISSUER + value: https://{{ .domain }}/ + - name: AUTH_AUDIENCE + value: users + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 1Gi + requests: + cpu: 50m + memory: 256Mi + ephemeral-storage: 50Mi + securityContext: + readOnlyRootFilesystem: false + livenessProbe: + httpGet: + path: /api/v3/testConnection + port: 5000 + initialDelaySeconds: 60 + timeoutSeconds: 5 + periodSeconds: 30 + failureThreshold: 6 + readinessProbe: + httpGet: + path: /api/v3/testConnection + port: 5000 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + failureThreshold: 3 + restartPolicy: Always diff --git a/polis/versions/dev/ingress.yaml b/polis/versions/dev/ingress.yaml new file mode 100644 index 0000000..e61834b --- /dev/null +++ b/polis/versions/dev/ingress.yaml @@ -0,0 +1,25 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: polis + annotations: + external-dns.alpha.kubernetes.io/target: {{ .externalDnsDomain }} + external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" + external-dns.alpha.kubernetes.io/ttl: "60" +spec: + ingressClassName: traefik + rules: + - host: {{ .domain }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: polis-file-server + port: + number: 80 + tls: + - hosts: + - {{ .domain }} + secretName: {{ .tlsSecretName }} diff --git a/polis/versions/dev/kustomization.yaml b/polis/versions/dev/kustomization.yaml new file mode 100644 index 0000000..1c17a50 --- /dev/null +++ b/polis/versions/dev/kustomization.yaml @@ -0,0 +1,17 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: {{ .namespace }} +labels: + - includeSelectors: true + pairs: + app: polis + managedBy: kustomize + partOf: wild-cloud +resources: + - namespace.yaml + - db-init-job.yaml + - deployment-server.yaml + - deployment-math.yaml + - deployment-fileserver.yaml + - service.yaml + - ingress.yaml diff --git a/polis/versions/dev/manifest.yaml b/polis/versions/dev/manifest.yaml new file mode 100644 index 0000000..0272142 --- /dev/null +++ b/polis/versions/dev/manifest.yaml @@ -0,0 +1,23 @@ +version: 2025.06-1 +requires: + - name: postgres +defaultConfig: + namespace: polis + domain: polis.{{ .cloud.domain }} + externalDnsDomain: '{{ .cloud.domain }}' + tlsSecretName: wildcard-wild-cloud-tls + adminEmail: '{{ .operator.email }}' + db: + host: '{{ .apps.postgres.host }}' + port: '{{ .apps.postgres.port }}' + name: polis + user: polis +defaultSecrets: + - key: dbPassword + - key: dbUrl + default: "postgresql://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host }}:{{ .app.db.port }}/{{ .app.db.name }}" + - key: loginCodePepper + - key: jwtPrivateKey + - key: jwtPublicKey +requiredSecrets: + - postgres.password diff --git a/polis/versions/dev/namespace.yaml b/polis/versions/dev/namespace.yaml new file mode 100644 index 0000000..054927e --- /dev/null +++ b/polis/versions/dev/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .namespace }} diff --git a/polis/versions/dev/service.yaml b/polis/versions/dev/service.yaml new file mode 100644 index 0000000..e483818 --- /dev/null +++ b/polis/versions/dev/service.yaml @@ -0,0 +1,32 @@ +--- +# Named "server" to match the upstream hostname in the file-server nginx config +apiVersion: v1 +kind: Service +metadata: + name: server + labels: + component: server +spec: + selector: + component: server + ports: + - name: http + port: 5000 + targetPort: 5000 + protocol: TCP +--- +# Named "polis-file-server" - this is the ingress entry point +apiVersion: v1 +kind: Service +metadata: + name: polis-file-server + labels: + component: file-server +spec: + selector: + component: file-server + ports: + - name: http + port: 80 + targetPort: 8080 + protocol: TCP