diff --git a/README.md b/README.md index 660fe1f4f..a88717416 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,56 @@ from the defaults found in the `docker-compose.yml` file and pass it as the seco We use Cypress for automated, end-to-end browser testing for PRs on GitHub (see badge above). Please see [`e2e/README.md`](/e2e/README.md) for more information on running these tests locally. +### 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 #### Docker Problems 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-secret.yaml b/manifests/polis-secret.yaml new file mode 100644 index 000000000..8691b724d --- /dev/null +++ b/manifests/polis-secret.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Secret +metadata: + name: polis-secret +type: Opaque +data: + POSTGRES_USER: cG9zdGdyZXM= + POSTGRES_DB: cG9saXMtZGV2 + POSTGRES_PORT: NTQzMg== + POSTGRES_HOST: cG9zdGdyZXM6NTQzMg== + POSTGRES_PASSWORD: b2lQb3JnM05yejB5cURMRQ== + STRIPE_SECRET_KEY: c2tfdGVzdF9ORkJERVRoa3BIQ1lCelhQSnVCbFk4VFc= + + # 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: UExFQVNFX0NIQU5HRV9NRQ== + + # These may be the deprecated settings for submitting web requests to the math worker + WEBSERVER_USERNAME: d3MtdXNlcg== + WEBSERVER_PASS: d3MtcGFzcw== diff --git a/manifests/polis-server.yaml b/manifests/polis-server.yaml new file mode 100644 index 000000000..86a441f5a --- /dev/null +++ b/manifests/polis-server.yaml @@ -0,0 +1,138 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: polis-server +data: + #General Settings + ADMIN_UIDS: "[]" + GIT_HASH: "" + SERVER_ENV_FILE: ".env" + + # Database + READ_ONLY_DATABASE_URL: "" + POSTGRES_DOCKER: "true" + DATABASE_FOR_READS_NAME: DATABASE_URL + + # 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 + API_DEV_HOSTNAME: polis.local + API_PROD_HOSTNAME: 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" +--- +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 + env: + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_DB + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_PASSWORD + - name: POSTGRES_HOST + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_HOST + - name: DATABASE_URL + value: postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST)/$(POSTGRES_DB) + - name: STRIPE_SECRET_KEY + valueFrom: + secretKeyRef: + name: polis-secret + key: STRIPE_SECRET_KEY + - name: ENCRYPTION_PASSWORD_00001 + valueFrom: + secretKeyRef: + name: polis-secret + key: ENCRYPTION_PASSWORD_00001 + 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..18bbb39ea --- /dev/null +++ b/manifests/postgres.yaml @@ -0,0 +1,72 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +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 + env: + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_DB + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: polis-secret + key: POSTGRES_PASSWORD + 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..3297e2276 --- /dev/null +++ b/skaffold.yaml @@ -0,0 +1,33 @@ +apiVersion: skaffold/v4beta11 +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 +manifests: + rawYaml: + - manifests/polis-secret.yaml + - manifests/polis-file-server.yaml + - manifests/polis-math.yaml + - manifests/postgres.yaml + - manifests/polis-server.yaml +deploy: + kubectl: