diff --git a/README.md b/README.md index f25292de1..37f33911a 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,56 @@ docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --scale server Where `3` is the number of replicas you'd like to use. +### Kubernetes + +**Warning:** This is work in progress and should not be used in production. + +Under the `manifests` folder you can find a first version of polis running under +Kubernetes. It uses an in-cluster postegres as a stateful set, with a persistent +volume claim, and exposes the polis server using the cluster's ingress. + +The setting of the ingress is not part of the provided resources as it will vary +between providers. + +#### Todo + +- [ ] Use official postgres image, decouple migrations +- [ ] Figure out and document the default resources for the services +- [ ] Document architecture, deployement, pitfalls, and best practices + +### Notes + +- Look for `polis.local` in the `manifests/*.yaml` and replace with your hostname + +### Requirements + +- Local development: + - [Minikube](https://minikube.sigs.k8s.io/docs/) + - [Skaffold](https://skaffold.dev/) + +Skaffold deals with the local development flow, syncing updated files to their +in-cluster containers. + +#### Running in Minikube + +Start minikube, and enable the ingress and ingress-dns addons. + +- `minikube start` +- `minikube addons enable ingress` +- `minikube addons enable ingress-dns` + +You can now build and deploy the containers in the local cluster via either: + +- `skaffold run` - Builds and deploys everything on demand. +- `skaffold dev` - While running will watch and automatically build and deploy + updated containers. + +The final part is to expose the nginx ingress to your local machine and connect +to it. + +- `minikube tunnel` - You need to leave this running +- `open http://polis.local` + ### Miscellaneous & troubleshooting #### Git Configuration diff --git a/client-admin/polis.config.template.js b/client-admin/polis.config.template.js index 90cfa90b5..8ff628779 100644 --- a/client-admin/polis.config.template.js +++ b/client-admin/polis.config.template.js @@ -12,6 +12,7 @@ module.exports = { // These allow for local ip routing for remote dev deployment "^(n|ssl)ip\\.io$", ".+\\.(n|ssl)ip\\.io$", + "^polis\\.local", ], DISABLE_INTERCOM: true, diff --git a/client-participation/polis.config.template.js b/client-participation/polis.config.template.js index ec6ea1de8..9f75da599 100644 --- a/client-participation/polis.config.template.js +++ b/client-participation/polis.config.template.js @@ -10,6 +10,7 @@ module.exports = { // These allow for local ip routing for remote dev deployment "^(n|ssl)ip\\.io$", ".+\\.(n|ssl)ip\\.io$", + "^polis\\.local", ], // Point to a polisServer instance (local recommended for dev) diff --git a/manifests/polis-file-server.yaml b/manifests/polis-file-server.yaml new file mode 100644 index 000000000..5e184a951 --- /dev/null +++ b/manifests/polis-file-server.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: polis-file-server +spec: + selector: + matchLabels: + app: polis-file-server + template: + metadata: + labels: + app: polis-file-server + spec: + containers: + - image: docker.io/compdem/polis-file-server:dev + name: polis-file-server + ports: + - containerPort: 8080 + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 1000m + memory: 1000Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: polis-file-server +spec: + ports: + - name: http + port: 80 + targetPort: 8080 + selector: + app: polis-file-server diff --git a/manifests/polis-math.yaml b/manifests/polis-math.yaml new file mode 100644 index 000000000..75871ca36 --- /dev/null +++ b/manifests/polis-math.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: polis-math +data: + DATABASE_URL: postgres://postgres:oiPorg3Nrz0yqDLE@postgres:5432/polis-dev + WEBSERVER_USERNAME: ws-user + WEBSERVER_PASS: ws-pass +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: polis-math +spec: + selector: + matchLabels: + app: polis-math + template: + metadata: + labels: + app: polis-math + spec: + containers: + - image: docker.io/compdem/polis-math:dev + name: polis-math + envFrom: + - configMapRef: + name: polis-math + ports: + - containerPort: 5000 + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 1000m + memory: 1000Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: polis-math +spec: + ports: + - name: http + port: 80 + targetPort: 5000 + selector: + app: polis-math + + diff --git a/manifests/polis-server.yaml b/manifests/polis-server.yaml new file mode 100644 index 000000000..b62ca1eb5 --- /dev/null +++ b/manifests/polis-server.yaml @@ -0,0 +1,112 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: polis-server +data: + # For admin functionality, fill this out + ADMIN_EMAILS: "[]" + ADMIN_EMAIL_DATA_EXPORT: "" + ADMIN_EMAIL_DATA_EXPORT_TEST: "" + ADMIN_EMAIL_EMAIL_TEST: "" + ADMIN_UIDS: "[]" + + DATABASE_FOR_READS_NAME: DATABASE_URL + DATABASE_URL: postgres://postgres:oiPorg3Nrz0yqDLE@postgres:5432/polis-dev + + # These may be the deprecated settings for submitting web requests to the math worker + WEBSERVER_USERNAME: ws-user + WEBSERVER_PASS: ws-pass + + # Set to `false` for production + DEV_MODE: "true" + + # Set the domain name; make sure this matches what"s running on math node + DOMAIN_OVERRIDE: polis.local + + # Options: prod, preprod, dev + MATH_ENV: dev + PORT: "5000" + + # Set to `true` and insert google creds if desired + SHOULD_USE_TRANSLATION_API: "false" + # GOOGLE_CREDENTIALS_BASE64: ... + # GOOGLE_CREDS_STRINGIFIED: ... + + # These need to be configured to point to the local file server + STATIC_FILES_HOST: polis-file-server + STATIC_FILES_ADMINDASH_PORT: "80" + STATIC_FILES_PORT: "80" + + AWS_REGION: us-east-1 + + # Options: maildev, aws-ses, mailgun + EMAIL_TRANSPORT_TYPES: maildev + POLIS_FROM_ADDRESS: "Example " + + # These pieces of functionality will likely be removed in the near future + DISABLE_INTERCOM: "true" + STRIPE_SECRET_KEY: sk_test_NFBDEThkpHCYBzXPJuBlY8TW + + # Note(geoah): This seems to be needed until the following TODO is resolved: + # https://github.com/compdemocracy/polis/blob/9a294140bbfc50d5bbb50ce4e474f4ad72541881/server/src/session.ts#L8-L10 + ENCRYPTION_PASSWORD_00001: "PLEASE-CHANGE-ME" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: polis-server +spec: + selector: + matchLabels: + app: polis-server + template: + metadata: + labels: + app: polis-server + spec: + containers: + - image: docker.io/compdem/polis-server:dev + name: polis-server + envFrom: + - configMapRef: + name: polis-server + ports: + - containerPort: 5000 + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 1000m + memory: 1000Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: polis-server +spec: + ports: + - name: http + port: 80 + targetPort: 5000 + selector: + app: polis-server +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: polis-server +spec: + rules: + - host: polis.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: polis-server + port: + number: 80 + + diff --git a/manifests/postgres.yaml b/manifests/postgres.yaml new file mode 100644 index 000000000..adec55dc6 --- /dev/null +++ b/manifests/postgres.yaml @@ -0,0 +1,70 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres + labels: + app: postgres +data: + POSTGRES_DB: polis-dev + POSTGRES_USER: postgres + POSTGRES_PASSWORD: oiPorg3Nrz0yqDLE +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: postgres-pv-claim + labels: + app: postgres +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgres-statefulset + labels: + app: postgres +spec: + serviceName: postgres + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: docker.io/compdem/polis-postgres:dev + envFrom: + - configMapRef: + name: postgres + ports: + - containerPort: 5432 + name: postgresdb + volumeMounts: + - name: pv-data + mountPath: /var/lib/postgresql/data + volumes: + - name: pv-data + persistentVolumeClaim: + claimName: postgres-pv-claim +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + labels: + app: postgres +spec: + ports: + - port: 5432 + name: postgres + selector: + app: postgres diff --git a/skaffold.yaml b/skaffold.yaml new file mode 100644 index 000000000..1ecc96377 --- /dev/null +++ b/skaffold.yaml @@ -0,0 +1,31 @@ +apiVersion: skaffold/v2beta28 +kind: Config +metadata: + name: polis +build: + local: + useBuildkit: true + push: false + artifacts: + - image: docker.io/compdem/polis-file-server + docker: + dockerfile: file-server/Dockerfile + - image: docker.io/compdem/polis-math + context: math + docker: + dockerfile: math/Dockerfile + - image: docker.io/compdem/polis-postgres + context: server + docker: + dockerfile: server/Dockerfile-db + - image: docker.io/compdem/polis-server + context: server + docker: + dockerfile: server/Dockerfile +deploy: + kubectl: + manifests: + - manifests/polis-file-server.yaml + - manifests/polis-math.yaml + - manifests/postgres.yaml + - manifests/polis-server.yaml