diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index f829b57..48e700b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -24,7 +24,7 @@ jobs: [ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-arm64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind - + - name: "Setup k8s cluster" run: | cat <) + appSlug: "" # GitHub App credentials (stored in the shared secret) appId: "" clientId: "" diff --git a/kube/QUICKSTART.md b/kube/QUICKSTART.md deleted file mode 100644 index 839995f..0000000 --- a/kube/QUICKSTART.md +++ /dev/null @@ -1,101 +0,0 @@ -# Quick Start with Kind -> [!NOTE] -> kind does not require kubectl, but you will not be able to perform some of the examples in our docs without it. To install kubectl see the upstream kubectl installation docs. - -## Install - -**macOS:** -```bash -# For Intel Macs -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-darwin-amd64 -# For M1 / ARM Macs -[ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-darwin-arm64 -chmod +x ./kind -mv ./kind /some-dir-in-your-PATH/kind -``` - -**Linux:** -```bash -# For AMD64 / x86_64 -[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-amd64 -# For ARM64 -[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-arm64 -chmod +x ./kind -sudo mv ./kind /usr/local/bin/kind -``` - -## Setup cluster with port forwarding - -> [!NOTE] -> On the host computer, `localhost:80` should be accessible. - -```bash -cat < **Note:** Elasticsearch 7.14.2 is used (not OpenSearch) because Huly's +> fulltext service bundles `elasticsearch-js` which rejects non-Elasticsearch backends. -If you don't have any k8s cluster, consider using the [kind setup](QUICKSTART.md). +## Directory layout -## Check and update configuration +``` +kube/ + base/ + config/ # ConfigMap with URLs and app settings + infra/ # CockroachDB, Redpanda, Elasticsearch, MinIO + app/ # 8 Huly services + ingress/ # 6 nginx Ingress resources (path-based routing) + overlays/ + example/ # Copy this, set your domain + image tags +``` -Huly deployment configuration is located in [config.yaml](config/config.yaml) and [secret.yaml](config/secret.yaml) files. -The sample configuration assume that Huly is available on huly.example hostname with dedicated hostname per service. +## Prerequisites -## Deploy Huly to Kubernetes +- Kubernetes cluster with: + - [ingress-nginx](https://kubernetes.github.io/ingress-nginx/) + - [cert-manager](https://cert-manager.io/) with a `ClusterIssuer` named `letsencrypt-prod` +- `kubectl` configured for your cluster +- DNS A record pointing your domain to the ingress load-balancer IP +- (Optional) Google OAuth credentials for login -Deploy Huly with `kubectl`. +## Quick start ```bash -kubectl create namespace huly-v7 +# 1. Create your overlay (copy the example) +cp -r kube/overlays/example kube/overlays/my-site +# Edit kube/overlays/my-site/kustomization.yaml: +# - Uncomment the patches section +# - Replace huly.yourdomain.com with your actual domain +# - Replace you@yourdomain.com with your admin email +# - Pin image tags to a specific version (e.g., v0.7.382) + +# 2. Create namespace +kubectl create namespace huly -kubectl apply -R -f . --namespace huly-v7 +# 3. Create secrets +SERVER_SECRET=$(openssl rand -hex 32) +RP_PASS=$(openssl rand -hex 16) + +kubectl -n huly create secret generic huly-secret \ + --from-literal=SERVER_SECRET="$SERVER_SECRET" \ + --from-literal=STORAGE_CONFIG='minio|minio?accessKey=minioadmin&secretKey=minioadmin' \ + --from-literal=REDPANDA_SUPERUSER_PASSWORD="$RP_PASS" \ + --from-literal=CR_DB_URL='postgres://root@cockroach:26257/defaultdb?sslmode=disable' \ + --from-literal=GOOGLE_CLIENT_ID='' \ + --from-literal=GOOGLE_CLIENT_SECRET='' + +# 4. Deploy +kubectl apply -k kube/overlays/my-site/ + +# 5. Watch pods come up +kubectl -n huly get pods -w ``` -Now, launch your web browser and enjoy Huly! +## One-liner deploy + +If you have `envsubst` available, you can deploy with a single command after +creating the namespace and secret above: + +```bash +HULY_DOMAIN=huly.yourdomain.com \ +ADMIN_EMAIL=you@yourdomain.com \ +HULY_VERSION=v0.7.382 \ + bash kube/deploy.sh +``` + +> See the [deploy.sh script](#deploy-script) section below for details. + +## Authentication + +### Google OAuth + +1. Go to [Google Cloud Console](https://console.cloud.google.com/apis/credentials) +2. Create an OAuth 2.0 Client ID (Web application) +3. Add authorized redirect URI: `https:///_accounts/auth/google/callback` +4. Set `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` in `huly-secret` + +### GitHub OAuth (optional) + +1. Create a GitHub OAuth App at https://github.com/settings/developers +2. Set callback URL: `https:///_accounts/auth/github/callback` +3. Add `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` to `huly-secret` + +### OpenID Connect (optional) + +Add the following keys to `huly-secret`: +- `OPENID_CLIENT_ID` +- `OPENID_CLIENT_SECRET` +- `OPENID_ISSUER` (e.g. `https://accounts.google.com`) + +### Admin bootstrap + +The first user to sign up creates their workspace and becomes the workspace owner. +Set `ADMIN_EMAILS` in the ConfigMap to grant system-wide admin privileges (comma-separated). + +### Restricting sign-ups + +After creating admin accounts, add `DISABLE_SIGNUP=true` to the account and +front deployments. New users can then only join via workspace invites. + +## Upgrading + +Edit your overlay's `kustomization.yaml` — change all `newTag` values, then: + +```bash +kubectl apply -k kube/overlays/my-site/ +``` + +## Verify + +```bash +# All 13 pods should be Running (including kvs) +kubectl -n huly get pods + +# Front responds +curl -I https:/// + +# Account responds (405 = healthy, POST-only API) +curl -I https:///_accounts + +# CockroachDB admin UI (port-forward) +kubectl -n huly port-forward svc/cockroach 8080:8080 +``` + +## Troubleshooting + +| Symptom | Check | +|---------|-------| +| Pod stuck in `Init` | Infra not ready — `kubectl -n huly logs -c wait-cockroach` | +| Account CrashLoop | DB auth — `kubectl -n huly logs deploy/account` | +| Front CrashLoop | Missing env — check logs for `please provide ` | +| Redpanda won't start | Needs ≥1Gi memory limit | +| Elasticsearch permission denied | Pod spec needs `securityContext.fsGroup: 1000` | +| Fulltext `ProductNotSupportedError` | Must use ES 7.14.2, not OpenSearch | +| WebSocket 502 | Check ingress `proxy-read-timeout: "3600"` annotation | + +## Services + +| Service | Port | Protocol | Needs DB | Needs Redpanda | +|---------|------|----------|----------|----------------| +| front | 8080 | HTTP | - | - | +| account | 3000 | HTTP | yes | yes | +| transactor | 3333 | WebSocket | yes | yes | +| collaborator | 3078 | WebSocket | - | - | +| workspace | - | background | yes | yes | +| fulltext | 4700 | HTTP | yes | yes | +| kvs | 8094 | HTTP | yes | - | +| rekoni | 4004 | HTTP | - | - | +| stats | 4900 | HTTP | - | - | + +## Teardown + +```bash +kubectl delete -k kube/overlays/my-site/ +kubectl -n huly delete secret huly-secret +kubectl delete namespace huly +# PVCs are retained — delete manually if needed: +kubectl -n huly delete pvc --all +``` diff --git a/kube/account/account-ingress.yaml b/kube/account/account-ingress.yaml deleted file mode 100644 index 93a82ce..0000000 --- a/kube/account/account-ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.io/ingress.class: nginx - labels: - app: account - name: account -spec: - ingressClassName: nginx - rules: - - host: account.huly.example - http: - paths: - - backend: - service: - name: account - port: - number: 80 - path: / - pathType: Prefix diff --git a/kube/account/account-service.yaml b/kube/account/account-service.yaml deleted file mode 100644 index 031cca7..0000000 --- a/kube/account/account-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: account - name: account -spec: - ports: - - port: 80 - targetPort: 3000 - selector: - app: account diff --git a/kube/base/app/account/deployment.yaml b/kube/base/app/account/deployment.yaml new file mode 100644 index 0000000..cec11a4 --- /dev/null +++ b/kube/base/app/account/deployment.yaml @@ -0,0 +1,150 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: account + labels: + app.kubernetes.io/name: account + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: account + template: + metadata: + labels: + app.kubernetes.io/name: account + spec: + initContainers: + - name: wait-cockroach + image: busybox:1.36 + command: ["sh", "-c", "until nc -z cockroach 26257; do echo waiting for cockroach; sleep 2; done"] + - name: wait-redpanda + image: busybox:1.36 + command: ["sh", "-c", "until nc -z redpanda 9092; do echo waiting for redpanda; sleep 2; done"] + containers: + - name: account + image: hardcoreeng/account:latest + ports: + - name: http + containerPort: 3000 + env: + - name: SERVER_PORT + value: "3000" + - name: ACCOUNT_PORT + value: "3000" + - name: SERVER_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + - name: DB_URL + valueFrom: + secretKeyRef: + name: huly-secret + key: CR_DB_URL + - name: STORAGE_CONFIG + valueFrom: + secretKeyRef: + name: huly-secret + key: STORAGE_CONFIG + - name: TRANSACTOR_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: TRANSACTOR_URL + - name: FRONT_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: FRONT_URL + - name: ACCOUNTS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: ACCOUNTS_URL + - name: STATS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: STATS_URL + - name: QUEUE_CONFIG + valueFrom: + configMapKeyRef: + name: huly-config + key: QUEUE_CONFIG + - name: MODEL_ENABLED + valueFrom: + configMapKeyRef: + name: huly-config + key: MODEL_ENABLED + - name: GOOGLE_CLIENT_ID + valueFrom: + secretKeyRef: + name: huly-secret + key: GOOGLE_CLIENT_ID + optional: true + - name: GOOGLE_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: GOOGLE_CLIENT_SECRET + optional: true + - name: ADMIN_EMAILS + valueFrom: + configMapKeyRef: + name: huly-config + key: ADMIN_EMAILS + optional: true + - name: GITHUB_CLIENT_ID + valueFrom: + secretKeyRef: + name: huly-secret + key: GITHUB_CLIENT_ID + optional: true + - name: GITHUB_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: GITHUB_CLIENT_SECRET + optional: true + - name: OPENID_CLIENT_ID + valueFrom: + secretKeyRef: + name: huly-secret + key: OPENID_CLIENT_ID + optional: true + - name: OPENID_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: OPENID_CLIENT_SECRET + optional: true + - name: OPENID_ISSUER + valueFrom: + secretKeyRef: + name: huly-secret + key: OPENID_ISSUER + optional: true + - name: DISABLE_SIGNUP + valueFrom: + configMapKeyRef: + name: huly-config + key: DISABLE_SIGNUP + optional: true + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + readinessProbe: + tcpSocket: + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + periodSeconds: 30 diff --git a/kube/base/app/account/service.yaml b/kube/base/app/account/service.yaml new file mode 100644 index 0000000..2b4a92b --- /dev/null +++ b/kube/base/app/account/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: account + labels: + app.kubernetes.io/name: account + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: account + ports: + - name: http + port: 3000 + targetPort: http diff --git a/kube/base/app/collaborator/deployment.yaml b/kube/base/app/collaborator/deployment.yaml new file mode 100644 index 0000000..21849f2 --- /dev/null +++ b/kube/base/app/collaborator/deployment.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: collaborator + labels: + app.kubernetes.io/name: collaborator + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: collaborator + template: + metadata: + labels: + app.kubernetes.io/name: collaborator + spec: + containers: + - name: collaborator + image: hardcoreeng/collaborator:latest + ports: + - name: ws + containerPort: 3078 + env: + - name: COLLABORATOR_PORT + value: "3078" + - name: SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + - name: ACCOUNTS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: ACCOUNTS_URL_INTERNAL + - name: STATS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: STATS_URL_INTERNAL + - name: STORAGE_CONFIG + valueFrom: + secretKeyRef: + name: huly-secret + key: STORAGE_CONFIG + readinessProbe: + tcpSocket: + port: ws + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: ws + initialDelaySeconds: 30 + periodSeconds: 30 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi diff --git a/kube/base/app/collaborator/service.yaml b/kube/base/app/collaborator/service.yaml new file mode 100644 index 0000000..6a0f079 --- /dev/null +++ b/kube/base/app/collaborator/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: collaborator + labels: + app.kubernetes.io/name: collaborator + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: collaborator + ports: + - name: ws + port: 3078 + targetPort: ws diff --git a/kube/base/app/front/deployment.yaml b/kube/base/app/front/deployment.yaml new file mode 100644 index 0000000..da1cca1 --- /dev/null +++ b/kube/base/app/front/deployment.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: front + labels: + app.kubernetes.io/name: front + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: front + template: + metadata: + labels: + app.kubernetes.io/name: front + spec: + containers: + - name: front + image: hardcoreeng/front:latest + ports: + - name: http + containerPort: 8080 + env: + - name: SERVER_PORT + value: "8080" + - name: SERVER_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + - name: STORAGE_CONFIG + valueFrom: + secretKeyRef: + name: huly-secret + key: STORAGE_CONFIG + envFrom: + - configMapRef: + name: huly-config + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 15 + periodSeconds: 30 diff --git a/kube/base/app/front/service.yaml b/kube/base/app/front/service.yaml new file mode 100644 index 0000000..1425ce6 --- /dev/null +++ b/kube/base/app/front/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: front + labels: + app.kubernetes.io/name: front + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: front + ports: + - name: http + port: 8080 + targetPort: http diff --git a/kube/base/app/fulltext/deployment.yaml b/kube/base/app/fulltext/deployment.yaml new file mode 100644 index 0000000..80b22cd --- /dev/null +++ b/kube/base/app/fulltext/deployment.yaml @@ -0,0 +1,95 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fulltext + labels: + app.kubernetes.io/name: fulltext + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: fulltext + template: + metadata: + labels: + app.kubernetes.io/name: fulltext + spec: + initContainers: + - name: wait-cockroach + image: busybox:1.36 + command: ["sh", "-c", "until nc -z cockroach 26257; do echo waiting for cockroach; sleep 2; done"] + - name: wait-redpanda + image: busybox:1.36 + command: ["sh", "-c", "until nc -z redpanda 9092; do echo waiting for redpanda; sleep 2; done"] + - name: wait-elastic + image: busybox:1.36 + command: ["sh", "-c", "until nc -z elastic 9200; do echo waiting for elastic; sleep 2; done"] + containers: + - name: fulltext + image: hardcoreeng/fulltext:latest + ports: + - name: http + containerPort: 4700 + env: + - name: SERVER_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + - name: DB_URL + valueFrom: + secretKeyRef: + name: huly-secret + key: CR_DB_URL + - name: FULLTEXT_DB_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: ELASTIC_URL + - name: ELASTIC_INDEX_NAME + valueFrom: + configMapKeyRef: + name: huly-config + key: ELASTIC_INDEX_NAME + - name: STORAGE_CONFIG + valueFrom: + secretKeyRef: + name: huly-secret + key: STORAGE_CONFIG + - name: REKONI_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: REKONI_URL_INTERNAL + - name: ACCOUNTS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: ACCOUNTS_URL_INTERNAL + - name: STATS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: STATS_URL_INTERNAL + - name: QUEUE_CONFIG + valueFrom: + configMapKeyRef: + name: huly-config + key: QUEUE_CONFIG + readinessProbe: + tcpSocket: + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + periodSeconds: 30 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi diff --git a/kube/base/app/fulltext/service.yaml b/kube/base/app/fulltext/service.yaml new file mode 100644 index 0000000..5829885 --- /dev/null +++ b/kube/base/app/fulltext/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: fulltext + labels: + app.kubernetes.io/name: fulltext + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: fulltext + ports: + - name: http + port: 4700 + targetPort: http diff --git a/kube/base/app/kustomization.yaml b/kube/base/app/kustomization.yaml new file mode 100644 index 0000000..0337c73 --- /dev/null +++ b/kube/base/app/kustomization.yaml @@ -0,0 +1,20 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - front/deployment.yaml + - front/service.yaml + - account/deployment.yaml + - account/service.yaml + - transactor/deployment.yaml + - transactor/service.yaml + - collaborator/deployment.yaml + - collaborator/service.yaml + - workspace/deployment.yaml + - fulltext/deployment.yaml + - fulltext/service.yaml + - rekoni/deployment.yaml + - rekoni/service.yaml + - stats/deployment.yaml + - stats/service.yaml + - kvs/deployment.yaml + - kvs/service.yaml diff --git a/kube/base/app/kvs/deployment.yaml b/kube/base/app/kvs/deployment.yaml new file mode 100644 index 0000000..905705a --- /dev/null +++ b/kube/base/app/kvs/deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kvs + labels: + app.kubernetes.io/name: kvs + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: kvs + template: + metadata: + labels: + app.kubernetes.io/name: kvs + spec: + initContainers: + - name: wait-cockroach + image: busybox:1.36 + command: ["sh", "-c", "until nc -z cockroach 26257; do echo waiting for cockroach; sleep 2; done"] + containers: + - name: kvs + # hulykvs does not publish a :latest tag — pin explicitly + image: hardcoreeng/hulykvs:s0.7.392 + ports: + - name: http + containerPort: 8094 + env: + - name: HULY_DB_CONNECTION + valueFrom: + secretKeyRef: + name: huly-secret + key: CR_DB_URL + - name: HULY_TOKEN_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + readinessProbe: + tcpSocket: + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + periodSeconds: 30 diff --git a/kube/base/app/kvs/service.yaml b/kube/base/app/kvs/service.yaml new file mode 100644 index 0000000..288a7ba --- /dev/null +++ b/kube/base/app/kvs/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: kvs + labels: + app.kubernetes.io/name: kvs + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: kvs + ports: + - name: http + port: 8094 + targetPort: http diff --git a/kube/base/app/rekoni/deployment.yaml b/kube/base/app/rekoni/deployment.yaml new file mode 100644 index 0000000..f489d2f --- /dev/null +++ b/kube/base/app/rekoni/deployment.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rekoni + labels: + app.kubernetes.io/name: rekoni + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: rekoni + template: + metadata: + labels: + app.kubernetes.io/name: rekoni + spec: + containers: + - name: rekoni + image: hardcoreeng/rekoni-service:latest + ports: + - name: http + containerPort: 4004 + env: + - name: SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + readinessProbe: + tcpSocket: + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 15 + periodSeconds: 30 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi diff --git a/kube/base/app/rekoni/service.yaml b/kube/base/app/rekoni/service.yaml new file mode 100644 index 0000000..c6f0367 --- /dev/null +++ b/kube/base/app/rekoni/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: rekoni + labels: + app.kubernetes.io/name: rekoni + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: rekoni + ports: + - name: http + port: 4004 + targetPort: http diff --git a/kube/base/app/stats/deployment.yaml b/kube/base/app/stats/deployment.yaml new file mode 100644 index 0000000..db9d6b3 --- /dev/null +++ b/kube/base/app/stats/deployment.yaml @@ -0,0 +1,47 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: stats + labels: + app.kubernetes.io/name: stats + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: stats + template: + metadata: + labels: + app.kubernetes.io/name: stats + spec: + containers: + - name: stats + image: hardcoreeng/stats:latest + ports: + - name: http + containerPort: 4900 + env: + - name: PORT + value: "4900" + - name: SERVER_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + readinessProbe: + tcpSocket: + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 15 + periodSeconds: 30 + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + memory: 256Mi diff --git a/kube/base/app/stats/service.yaml b/kube/base/app/stats/service.yaml new file mode 100644 index 0000000..d93af65 --- /dev/null +++ b/kube/base/app/stats/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: stats + labels: + app.kubernetes.io/name: stats + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: stats + ports: + - name: http + port: 4900 + targetPort: http diff --git a/kube/base/app/transactor/deployment.yaml b/kube/base/app/transactor/deployment.yaml new file mode 100644 index 0000000..b78f9f8 --- /dev/null +++ b/kube/base/app/transactor/deployment.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: transactor + labels: + app.kubernetes.io/name: transactor + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: transactor + template: + metadata: + labels: + app.kubernetes.io/name: transactor + spec: + initContainers: + - name: wait-cockroach + image: busybox:1.36 + command: ["sh", "-c", "until nc -z cockroach 26257; do echo waiting for cockroach; sleep 2; done"] + - name: wait-redpanda + image: busybox:1.36 + command: ["sh", "-c", "until nc -z redpanda 9092; do echo waiting for redpanda; sleep 2; done"] + containers: + - name: transactor + image: hardcoreeng/transactor:latest + ports: + - name: ws + containerPort: 3333 + env: + - name: SERVER_PORT + value: "3333" + - name: SERVER_SECRET + valueFrom: + secretKeyRef: + name: huly-secret + key: SERVER_SECRET + - name: DB_URL + valueFrom: + secretKeyRef: + name: huly-secret + key: CR_DB_URL + - name: STORAGE_CONFIG + valueFrom: + secretKeyRef: + name: huly-secret + key: STORAGE_CONFIG + - name: ACCOUNTS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: ACCOUNTS_URL_INTERNAL + - name: FULLTEXT_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: FULLTEXT_URL + - name: STATS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: STATS_URL_INTERNAL + - name: FRONT_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: FRONT_URL + - name: QUEUE_CONFIG + valueFrom: + configMapKeyRef: + name: huly-config + key: QUEUE_CONFIG + - name: LAST_NAME_FIRST + valueFrom: + configMapKeyRef: + name: huly-config + key: LAST_NAME_FIRST + - name: SERVER_CURSOR_MAXTIMEMS + value: "30000" + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + memory: 1Gi + readinessProbe: + tcpSocket: + port: ws + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: ws + initialDelaySeconds: 30 + periodSeconds: 30 diff --git a/kube/base/app/transactor/service.yaml b/kube/base/app/transactor/service.yaml new file mode 100644 index 0000000..d2c8a0d --- /dev/null +++ b/kube/base/app/transactor/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: transactor + labels: + app.kubernetes.io/name: transactor + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: transactor + ports: + - name: ws + port: 3333 + targetPort: ws diff --git a/kube/account/account-deployment.yaml b/kube/base/app/workspace/deployment.yaml similarity index 52% rename from kube/account/account-deployment.yaml rename to kube/base/app/workspace/deployment.yaml index 3d10ebd..6a55b53 100644 --- a/kube/account/account-deployment.yaml +++ b/kube/base/app/workspace/deployment.yaml @@ -1,69 +1,79 @@ apiVersion: apps/v1 kind: Deployment metadata: + name: workspace labels: - app: account - name: account + app.kubernetes.io/name: workspace + app.kubernetes.io/part-of: huly spec: replicas: 1 selector: matchLabels: - app: account + app.kubernetes.io/name: workspace template: metadata: labels: - app: account + app.kubernetes.io/name: workspace spec: + initContainers: + - name: wait-cockroach + image: busybox:1.36 + command: ["sh", "-c", "until nc -z cockroach 26257; do echo waiting for cockroach; sleep 2; done"] + - name: wait-redpanda + image: busybox:1.36 + command: ["sh", "-c", "until nc -z redpanda 9092; do echo waiting for redpanda; sleep 2; done"] containers: - - env: - - name: ACCOUNTS_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: ACCOUNTS_URL - - name: ACCOUNT_PORT - value: '3000' - - name: FRONT_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: FRONT_URL - - name: STATS_URL - value: http://stats - - name: STORAGE_CONFIG + - name: workspace + image: hardcoreeng/workspace:latest + env: + - name: SERVER_SECRET valueFrom: secretKeyRef: name: huly-secret - key: STORAGE_CONFIG - - name: MODEL_ENABLED - value: '*' + key: SERVER_SECRET - name: DB_URL valueFrom: secretKeyRef: name: huly-secret key: CR_DB_URL - - name: MONGO_URL + - name: ACCOUNTS_DB_URL valueFrom: - configMapKeyRef: - name: huly-config - key: MONGO_URL - - name: SERVER_SECRET + secretKeyRef: + name: huly-secret + key: CR_DB_URL + - name: STORAGE_CONFIG valueFrom: secretKeyRef: name: huly-secret - key: SERVER_SECRET + key: STORAGE_CONFIG + - name: ACCOUNTS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: ACCOUNTS_URL_INTERNAL + - name: STATS_URL + valueFrom: + configMapKeyRef: + name: huly-config + key: STATS_URL_INTERNAL - name: TRANSACTOR_URL valueFrom: configMapKeyRef: name: huly-config key: TRANSACTOR_URL - name: QUEUE_CONFIG - value: redpanda:9092 - image: hardcoreeng/account:v0.7.382 - name: account - ports: - - containerPort: 3000 + valueFrom: + configMapKeyRef: + name: huly-config + key: QUEUE_CONFIG + - name: MODEL_ENABLED + valueFrom: + configMapKeyRef: + name: huly-config + key: MODEL_ENABLED resources: + requests: + cpu: 50m + memory: 128Mi limits: - memory: "512M" - restartPolicy: Always + memory: 512Mi diff --git a/kube/base/config/configmap.yaml b/kube/base/config/configmap.yaml new file mode 100644 index 0000000..7a64648 --- /dev/null +++ b/kube/base/config/configmap.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: huly-config +data: + # External URLs — override these in your overlay + ACCOUNTS_URL: "https://huly.example/_accounts" + COLLABORATOR_URL: "wss://huly.example/_collaborator" + FRONT_URL: "https://huly.example" + REKONI_URL: "https://huly.example/_rekoni" + STATS_URL: "https://huly.example/_stats" + TRANSACTOR_URL: "ws://transactor:3333;wss://huly.example/_transactor" + # Internal URLs (no need to override) + ELASTIC_URL: "http://elastic:9200" + ELASTIC_INDEX_NAME: "huly_storage_index" + FULLTEXT_URL: "http://fulltext:4700" + ACCOUNTS_URL_INTERNAL: "http://account:3000" + REKONI_URL_INTERNAL: "http://rekoni:4004" + STATS_URL_INTERNAL: "http://stats:4900" + QUEUE_CONFIG: "redpanda:9092" + # App settings + MODEL_ENABLED: "*" + LAST_NAME_FIRST: "true" + TITLE: "Huly Self Host" + DEFAULT_LANGUAGE: "en" + UPLOAD_URL: "/files" + ADMIN_EMAILS: "admin@example.com" + # Optional integration URLs (required by front even if unused) + GMAIL_URL: "https://huly.example/_gmail" + TELEGRAM_URL: "https://huly.example/_telegram" + CALENDAR_URL: "https://huly.example/_calendar" + LOVE_ENDPOINT: "https://huly.example/_love" + DESKTOP_UPDATES_CHANNEL: "selfhost" diff --git a/kube/base/config/kustomization.yaml b/kube/base/config/kustomization.yaml new file mode 100644 index 0000000..9fb65fa --- /dev/null +++ b/kube/base/config/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - configmap.yaml diff --git a/kube/base/infra/cockroach/deployment.yaml b/kube/base/infra/cockroach/deployment.yaml new file mode 100644 index 0000000..9103bd8 --- /dev/null +++ b/kube/base/infra/cockroach/deployment.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cockroach + labels: + app.kubernetes.io/name: cockroach + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: cockroach + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: cockroach + spec: + containers: + - name: cockroach + image: cockroachdb/cockroach:latest-v24.2 + command: ["cockroach"] + args: ["start-single-node", "--insecure"] + ports: + - name: sql + containerPort: 26257 + - name: http + containerPort: 8080 + env: + - name: COCKROACH_DATABASE + value: "defaultdb" + volumeMounts: + - name: data + mountPath: /cockroach/cockroach-data + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + memory: 2Gi + readinessProbe: + httpGet: + path: /health?ready=1 + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 30 + periodSeconds: 30 + volumes: + - name: data + persistentVolumeClaim: + claimName: cockroach-data diff --git a/kube/base/infra/cockroach/pvc.yaml b/kube/base/infra/cockroach/pvc.yaml new file mode 100644 index 0000000..edad5d5 --- /dev/null +++ b/kube/base/infra/cockroach/pvc.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: cockroach-data + labels: + app.kubernetes.io/name: cockroach + app.kubernetes.io/part-of: huly +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi diff --git a/kube/base/infra/cockroach/service.yaml b/kube/base/infra/cockroach/service.yaml new file mode 100644 index 0000000..60471ed --- /dev/null +++ b/kube/base/infra/cockroach/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: cockroach + labels: + app.kubernetes.io/name: cockroach + app.kubernetes.io/part-of: huly +spec: + clusterIP: None + selector: + app.kubernetes.io/name: cockroach + ports: + - name: sql + port: 26257 + targetPort: sql + - name: http + port: 8080 + targetPort: http diff --git a/kube/base/infra/elastic/deployment.yaml b/kube/base/infra/elastic/deployment.yaml new file mode 100644 index 0000000..88414e0 --- /dev/null +++ b/kube/base/infra/elastic/deployment.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: elastic + labels: + app.kubernetes.io/name: elastic + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: elastic + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: elastic + spec: + securityContext: + fsGroup: 1000 + runAsUser: 1000 + runAsGroup: 1000 + containers: + - name: elasticsearch + image: elasticsearch:7.14.2 + command: + - sh + - -c + - | + if ! /usr/share/elasticsearch/bin/elasticsearch-plugin list | grep -q ingest-attachment; then + /usr/share/elasticsearch/bin/elasticsearch-plugin install --batch ingest-attachment + fi + exec /usr/local/bin/docker-entrypoint.sh eswrapper + ports: + - name: http + containerPort: 9200 + env: + - name: discovery.type + value: "single-node" + - name: ES_JAVA_OPTS + value: "-Xms1024m -Xmx1024m" + - name: http.cors.enabled + value: "true" + - name: http.cors.allow-origin + value: "http://localhost:8082" + - name: BITNAMI_DEBUG + value: "true" + - name: ELASTICSEARCH_PORT_NUMBER + value: "9200" + volumeMounts: + - name: data + mountPath: /usr/share/elasticsearch/data + resources: + requests: + cpu: 200m + memory: 768Mi + limits: + memory: 1536Mi + readinessProbe: + exec: + command: + - sh + - -c + - 'curl -sf http://localhost:9200/_cluster/health | grep -vq ''"status":"red"''' + initialDelaySeconds: 30 + periodSeconds: 10 + livenessProbe: + exec: + command: + - sh + - -c + - 'curl -sf http://localhost:9200/_cluster/health | grep -vq ''"status":"red"''' + initialDelaySeconds: 60 + periodSeconds: 20 + failureThreshold: 10 + volumes: + - name: data + persistentVolumeClaim: + claimName: elastic-data diff --git a/kube/redpanda/redpanda-persistentvolumeclaim.yaml b/kube/base/infra/elastic/pvc.yaml similarity index 53% rename from kube/redpanda/redpanda-persistentvolumeclaim.yaml rename to kube/base/infra/elastic/pvc.yaml index fa24440..32f339a 100644 --- a/kube/redpanda/redpanda-persistentvolumeclaim.yaml +++ b/kube/base/infra/elastic/pvc.yaml @@ -1,12 +1,13 @@ apiVersion: v1 kind: PersistentVolumeClaim metadata: + name: elastic-data labels: - app: redpanda - name: redpanda + app.kubernetes.io/name: elastic + app.kubernetes.io/part-of: huly spec: accessModes: - ReadWriteOnce resources: requests: - storage: 100Mi + storage: 10Gi diff --git a/kube/base/infra/elastic/service.yaml b/kube/base/infra/elastic/service.yaml new file mode 100644 index 0000000..b4d8074 --- /dev/null +++ b/kube/base/infra/elastic/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: elastic + labels: + app.kubernetes.io/name: elastic + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: elastic + ports: + - name: http + port: 9200 + targetPort: http diff --git a/kube/base/infra/kustomization.yaml b/kube/base/infra/kustomization.yaml new file mode 100644 index 0000000..6435bd5 --- /dev/null +++ b/kube/base/infra/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - cockroach/deployment.yaml + - cockroach/service.yaml + - cockroach/pvc.yaml + - redpanda/deployment.yaml + - redpanda/service.yaml + - redpanda/pvc.yaml + - elastic/deployment.yaml + - elastic/service.yaml + - elastic/pvc.yaml + - minio/deployment.yaml + - minio/service.yaml + - minio/pvc.yaml diff --git a/kube/base/infra/minio/deployment.yaml b/kube/base/infra/minio/deployment.yaml new file mode 100644 index 0000000..3d78088 --- /dev/null +++ b/kube/base/infra/minio/deployment.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: minio + labels: + app.kubernetes.io/name: minio + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: minio + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: minio + spec: + containers: + - name: minio + image: minio/minio:latest + command: ["minio"] + args: ["server", "/data", "--address", ":9000", "--console-address", ":9001"] + ports: + - name: api + containerPort: 9000 + - name: console + containerPort: 9001 + volumeMounts: + - name: data + mountPath: /data + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + memory: 512Mi + readinessProbe: + httpGet: + path: /minio/health/ready + port: api + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /minio/health/live + port: api + initialDelaySeconds: 30 + periodSeconds: 20 + volumes: + - name: data + persistentVolumeClaim: + claimName: minio-data diff --git a/kube/minio/files-persistentvolumeclaim.yaml b/kube/base/infra/minio/pvc.yaml similarity index 54% rename from kube/minio/files-persistentvolumeclaim.yaml rename to kube/base/infra/minio/pvc.yaml index af0754d..28f8d51 100644 --- a/kube/minio/files-persistentvolumeclaim.yaml +++ b/kube/base/infra/minio/pvc.yaml @@ -1,12 +1,13 @@ apiVersion: v1 kind: PersistentVolumeClaim metadata: + name: minio-data labels: - app: files - name: files + app.kubernetes.io/name: minio + app.kubernetes.io/part-of: huly spec: accessModes: - ReadWriteOnce resources: requests: - storage: 100Mi + storage: 50Gi diff --git a/kube/base/infra/minio/service.yaml b/kube/base/infra/minio/service.yaml new file mode 100644 index 0000000..9568bab --- /dev/null +++ b/kube/base/infra/minio/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: minio + labels: + app.kubernetes.io/name: minio + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: minio + ports: + - name: api + port: 9000 + targetPort: api + - name: console + port: 9001 + targetPort: console diff --git a/kube/base/infra/redpanda/deployment.yaml b/kube/base/infra/redpanda/deployment.yaml new file mode 100644 index 0000000..2b5562b --- /dev/null +++ b/kube/base/infra/redpanda/deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redpanda + labels: + app.kubernetes.io/name: redpanda + app.kubernetes.io/part-of: huly +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: redpanda + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: redpanda + spec: + initContainers: + - name: set-datadir-ownership + image: busybox:1.36 + command: ["sh", "-c", "chown 101:101 /var/lib/redpanda/data"] + volumeMounts: + - name: data + mountPath: /var/lib/redpanda/data + containers: + - name: redpanda + image: docker.redpanda.com/redpandadata/redpanda:v24.3.6 + command: ["rpk"] + args: + - "redpanda" + - "start" + - "--kafka-addr" + - "internal://0.0.0.0:9092,external://0.0.0.0:19092" + - "--advertise-kafka-addr" + - "internal://redpanda:9092,external://localhost:19092" + - "--pandaproxy-addr" + - "internal://0.0.0.0:8082,external://0.0.0.0:18082" + - "--advertise-pandaproxy-addr" + - "internal://redpanda:8082,external://localhost:18082" + - "--schema-registry-addr" + - "internal://0.0.0.0:8081,external://0.0.0.0:18081" + - "--rpc-addr" + - "0.0.0.0:33145" + - "--advertise-rpc-addr" + - "redpanda:33145" + - "--mode" + - "dev-container" + - "--smp" + - "1" + - "--default-log-level=info" + ports: + - name: kafka + containerPort: 9092 + - name: rpc + containerPort: 33145 + env: + - name: REDPANDA_SUPERUSER_USERNAME + value: "superuser" + - name: REDPANDA_SUPERUSER_PASSWORD + valueFrom: + secretKeyRef: + name: huly-secret + key: REDPANDA_SUPERUSER_PASSWORD + volumeMounts: + - name: data + mountPath: /var/lib/redpanda/data + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + memory: 1536Mi + readinessProbe: + exec: + command: ["rpk", "cluster", "info"] + initialDelaySeconds: 15 + periodSeconds: 10 + volumes: + - name: data + persistentVolumeClaim: + claimName: redpanda-data diff --git a/kube/elastic/elastic-persistentvolumeclaim.yaml b/kube/base/infra/redpanda/pvc.yaml similarity index 53% rename from kube/elastic/elastic-persistentvolumeclaim.yaml rename to kube/base/infra/redpanda/pvc.yaml index 54049c0..a28acd6 100644 --- a/kube/elastic/elastic-persistentvolumeclaim.yaml +++ b/kube/base/infra/redpanda/pvc.yaml @@ -1,12 +1,13 @@ apiVersion: v1 kind: PersistentVolumeClaim metadata: + name: redpanda-data labels: - app: elastic - name: elastic + app.kubernetes.io/name: redpanda + app.kubernetes.io/part-of: huly spec: accessModes: - ReadWriteOnce resources: requests: - storage: 100Mi + storage: 5Gi diff --git a/kube/base/infra/redpanda/service.yaml b/kube/base/infra/redpanda/service.yaml new file mode 100644 index 0000000..ae92ffe --- /dev/null +++ b/kube/base/infra/redpanda/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: redpanda + labels: + app.kubernetes.io/name: redpanda + app.kubernetes.io/part-of: huly +spec: + selector: + app.kubernetes.io/name: redpanda + ports: + - name: kafka + port: 9092 + targetPort: kafka + - name: rpc + port: 33145 + targetPort: rpc diff --git a/kube/base/ingress/ingress-accounts.yaml b/kube/base/ingress/ingress-accounts.yaml new file mode 100644 index 0000000..7b5012f --- /dev/null +++ b/kube/base/ingress/ingress-accounts.yaml @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: huly-accounts + labels: + app.kubernetes.io/part-of: huly + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: nginx + tls: + - hosts: + - huly.example + secretName: huly-tls + rules: + - host: huly.example + http: + paths: + - path: /_accounts(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: account + port: + number: 3000 diff --git a/kube/base/ingress/ingress-collaborator.yaml b/kube/base/ingress/ingress-collaborator.yaml new file mode 100644 index 0000000..5795a3c --- /dev/null +++ b/kube/base/ingress/ingress-collaborator.yaml @@ -0,0 +1,30 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: huly-collaborator + labels: + app.kubernetes.io/part-of: huly + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-http-version: "1.1" +spec: + ingressClassName: nginx + tls: + - hosts: + - huly.example + secretName: huly-tls + rules: + - host: huly.example + http: + paths: + - path: /_collaborator(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: collaborator + port: + number: 3078 diff --git a/kube/front/front-ingress.yaml b/kube/base/ingress/ingress-front.yaml similarity index 52% rename from kube/front/front-ingress.yaml rename to kube/base/ingress/ingress-front.yaml index 675de0b..6a973d1 100644 --- a/kube/front/front-ingress.yaml +++ b/kube/base/ingress/ingress-front.yaml @@ -1,21 +1,25 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - annotations: - kubernetes.io/ingress.class: nginx + name: huly-front labels: - app: front - name: front + app.kubernetes.io/part-of: huly + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod spec: ingressClassName: nginx + tls: + - hosts: + - huly.example + secretName: huly-tls rules: - host: huly.example http: paths: - - backend: + - path: / + pathType: Prefix + backend: service: name: front port: - number: 80 - path: / - pathType: Prefix + number: 8080 diff --git a/kube/base/ingress/ingress-rekoni.yaml b/kube/base/ingress/ingress-rekoni.yaml new file mode 100644 index 0000000..714b177 --- /dev/null +++ b/kube/base/ingress/ingress-rekoni.yaml @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: huly-rekoni + labels: + app.kubernetes.io/part-of: huly + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: nginx + tls: + - hosts: + - huly.example + secretName: huly-tls + rules: + - host: huly.example + http: + paths: + - path: /_rekoni(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: rekoni + port: + number: 4004 diff --git a/kube/base/ingress/ingress-stats.yaml b/kube/base/ingress/ingress-stats.yaml new file mode 100644 index 0000000..69ae0e1 --- /dev/null +++ b/kube/base/ingress/ingress-stats.yaml @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: huly-stats + labels: + app.kubernetes.io/part-of: huly + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: nginx + tls: + - hosts: + - huly.example + secretName: huly-tls + rules: + - host: huly.example + http: + paths: + - path: /_stats(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: stats + port: + number: 4900 diff --git a/kube/base/ingress/ingress-transactor.yaml b/kube/base/ingress/ingress-transactor.yaml new file mode 100644 index 0000000..8459ba1 --- /dev/null +++ b/kube/base/ingress/ingress-transactor.yaml @@ -0,0 +1,30 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: huly-transactor + labels: + app.kubernetes.io/part-of: huly + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-http-version: "1.1" +spec: + ingressClassName: nginx + tls: + - hosts: + - huly.example + secretName: huly-tls + rules: + - host: huly.example + http: + paths: + - path: /_transactor(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: transactor + port: + number: 3333 diff --git a/kube/base/ingress/kustomization.yaml b/kube/base/ingress/kustomization.yaml new file mode 100644 index 0000000..bf46078 --- /dev/null +++ b/kube/base/ingress/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ingress-front.yaml + - ingress-accounts.yaml + - ingress-transactor.yaml + - ingress-collaborator.yaml + - ingress-rekoni.yaml + - ingress-stats.yaml diff --git a/kube/base/kustomization.yaml b/kube/base/kustomization.yaml new file mode 100644 index 0000000..cec20a7 --- /dev/null +++ b/kube/base/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - config/ + - infra/ + - app/ + - ingress/ diff --git a/kube/cockroach/cockroach-deployment.yaml b/kube/cockroach/cockroach-deployment.yaml deleted file mode 100644 index b761991..0000000 --- a/kube/cockroach/cockroach-deployment.yaml +++ /dev/null @@ -1,52 +0,0 @@ - apiVersion: apps/v1 - kind: Deployment - metadata: - name: cockroachdb-single-node - spec: - replicas: 1 - selector: - matchLabels: - app: cockroach - template: - metadata: - labels: - app: cockroach - spec: - # initContainers: - # - name: init-certs-dir - # image: busybox - # command: ['sh', '-c', 'mkdir -p /cockroach/cockroach-certs && chmod -R 700 /cockroach'] - # volumeMounts: - # - name: certs - # mountPath: /cockroach/certs - containers: - - name: cockroachdb - image: cockroachdb/cockroach:latest-v24.2 - args: - - start-single-node - - --accept-sql-without-tls - env: - - name: COCKROACH_DATABASE - value: "defaultdb" - - name: COCKROACH_USER - value: "selfhost" - - name: COCKROACH_PASSWORD - valueFrom: - secretKeyRef: - name: huly-secret - key: COCKROACH_PASSWORD - ports: - - containerPort: 26257 - - containerPort: 8080 - volumeMounts: - - name: cockroachdb-data - mountPath: /cockroach/cockroach-data - - name: cockroachdb-certs - mountPath: /cockroach/certs - volumes: - - name: cockroachdb-data - persistentVolumeClaim: - claimName: cockroachdb-data - - name: cockroachdb-certs - persistentVolumeClaim: - claimName: cockroachdb-certs \ No newline at end of file diff --git a/kube/cockroach/cockroach-persistentvolumeclaim.yaml b/kube/cockroach/cockroach-persistentvolumeclaim.yaml deleted file mode 100644 index 1f02264..0000000 --- a/kube/cockroach/cockroach-persistentvolumeclaim.yaml +++ /dev/null @@ -1,21 +0,0 @@ - apiVersion: v1 - kind: PersistentVolumeClaim - metadata: - name: cockroachdb-data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi ---- - apiVersion: v1 - kind: PersistentVolumeClaim - metadata: - name: cockroachdb-certs - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 100Mi \ No newline at end of file diff --git a/kube/cockroach/cockroach-service.yaml b/kube/cockroach/cockroach-service.yaml deleted file mode 100644 index 51edf28..0000000 --- a/kube/cockroach/cockroach-service.yaml +++ /dev/null @@ -1,17 +0,0 @@ - apiVersion: v1 - kind: Service - metadata: - labels: - app: cockroach - name: cockroach - spec: - selector: - app: cockroach - ports: - - name: grpc - port: 26257 - targetPort: 26257 - - name: http - port: 8080 - targetPort: 8080 - clusterIP: None \ No newline at end of file diff --git a/kube/collaborator/collaborator-deployment.yaml b/kube/collaborator/collaborator-deployment.yaml deleted file mode 100644 index 2bc9293..0000000 --- a/kube/collaborator/collaborator-deployment.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: collaborator - name: collaborator -spec: - replicas: 1 - selector: - matchLabels: - app: collaborator - template: - metadata: - labels: - app: collaborator - spec: - containers: - - env: - - name: ACCOUNTS_URL - value: http://account - - name: STATS_URL - value: http://stats - - name: COLLABORATOR_PORT - value: "3078" - - name: STORAGE_CONFIG - valueFrom: - secretKeyRef: - name: huly-secret - key: STORAGE_CONFIG - - name: SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - image: hardcoreeng/collaborator:v0.7.382 - name: collaborator - ports: - - containerPort: 3078 - resources: - limits: - memory: '512M' - restartPolicy: Always diff --git a/kube/collaborator/collaborator-ingress.yaml b/kube/collaborator/collaborator-ingress.yaml deleted file mode 100644 index 2091140..0000000 --- a/kube/collaborator/collaborator-ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.io/ingress.class: nginx - labels: - app: collaborator - name: collaborator -spec: - ingressClassName: nginx - rules: - - host: collaborator.huly.example - http: - paths: - - backend: - service: - name: collaborator - port: - number: 80 - path: / - pathType: Prefix diff --git a/kube/collaborator/collaborator-service.yaml b/kube/collaborator/collaborator-service.yaml deleted file mode 100644 index cb5db83..0000000 --- a/kube/collaborator/collaborator-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: collaborator - name: collaborator -spec: - ports: - - port: 80 - targetPort: 3078 - selector: - app: collaborator diff --git a/kube/config/config.yaml b/kube/config/config.yaml deleted file mode 100644 index 257e28d..0000000 --- a/kube/config/config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: huly-config -data: - ACCOUNTS_URL: 'http://account.huly.example/' - COLLABORATOR_URL: 'ws://collaborator.huly.example/' - FRONT_URL: 'http://huly.example' - REKONI_URL: 'http://rekoni.huly.example/' - STATS_URL: 'http://stats.huly.example/' - TRANSACTOR_URL: 'ws://transactor;ws://transactor.huly.example/' - MINIO_ENDPOINT: 'minio' - MONGO_URL: 'mongodb://mongodb:27017' - ELASTIC_URL: 'http://elastic:9200' - ELASTIC_INDEX_NAME: 'huly_storage_index' diff --git a/kube/config/secret.yaml b/kube/config/secret.yaml deleted file mode 100644 index e95e3cf..0000000 --- a/kube/config/secret.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: huly-secret -type: Opaque -stringData: - SERVER_SECRET: secret - STORAGE_CONFIG: minio|minio?accessKey=minioadmin&secretKey=minioadmin - COCKROACH_PASSWORD: cockroach_user_secret - REDPANDA_SUPERUSER_PASSWORD: superpassword - CR_DB_URL: postgres://selfhost:cockroach_user_secret@cockroach:26257/defaultdb \ No newline at end of file diff --git a/kube/deploy.sh b/kube/deploy.sh new file mode 100755 index 0000000..5439619 --- /dev/null +++ b/kube/deploy.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +# Quick deploy script for Huly on Kubernetes. +# +# Prerequisites: kubectl, kustomize (or kubectl >= 1.14), cert-manager, +# ingress-nginx, DNS A record for $HULY_DOMAIN +# +# Usage: +# HULY_DOMAIN=huly.yourdomain.com \ +# ADMIN_EMAIL=you@yourdomain.com \ +# HULY_VERSION=v0.7.382 \ +# GOOGLE_CLIENT_ID=xxx \ +# GOOGLE_CLIENT_SECRET=yyy \ +# bash kube/deploy.sh +# +# Optional: +# HULY_NAMESPACE (default: huly) +# HULY_VERSION (default: latest) + +set -euo pipefail + +: "${HULY_DOMAIN:?Set HULY_DOMAIN to your Huly hostname (e.g. huly.yourdomain.com)}" +: "${ADMIN_EMAIL:=admin@example.com}" +: "${HULY_VERSION:=latest}" +: "${HULY_NAMESPACE:=huly}" +: "${GOOGLE_CLIENT_ID:=}" +: "${GOOGLE_CLIENT_SECRET:=}" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +echo "==> Deploying Huly to namespace '$HULY_NAMESPACE' at https://$HULY_DOMAIN" + +# 1. Create namespace +kubectl create namespace "$HULY_NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - + +# 2. Create/update secret +SERVER_SECRET=$(openssl rand -hex 32) +RP_PASS=$(openssl rand -hex 16) + +kubectl -n "$HULY_NAMESPACE" create secret generic huly-secret \ + --from-literal=SERVER_SECRET="$SERVER_SECRET" \ + --from-literal=STORAGE_CONFIG='minio|minio?accessKey=minioadmin&secretKey=minioadmin' \ + --from-literal=REDPANDA_SUPERUSER_PASSWORD="$RP_PASS" \ + --from-literal=CR_DB_URL='postgres://root@cockroach:26257/defaultdb?sslmode=disable' \ + --from-literal=GOOGLE_CLIENT_ID="$GOOGLE_CLIENT_ID" \ + --from-literal=GOOGLE_CLIENT_SECRET="$GOOGLE_CLIENT_SECRET" \ + --dry-run=client -o yaml | kubectl apply -f - + +# 3. Generate overlay with user's domain +cat > "$TMPDIR/kustomization.yaml" < Huly deployed! Waiting for pods..." +kubectl -n "$HULY_NAMESPACE" get pods +echo "" +echo "Visit https://$HULY_DOMAIN once all pods are Running." diff --git a/kube/elastic/elastic-deployment.yaml b/kube/elastic/elastic-deployment.yaml deleted file mode 100644 index 45651ff..0000000 --- a/kube/elastic/elastic-deployment.yaml +++ /dev/null @@ -1,66 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: elastic - name: elastic -spec: - replicas: 1 - selector: - matchLabels: - app: elastic - strategy: - type: Recreate - template: - metadata: - labels: - app: elastic - spec: - securityContext: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 - containers: - - args: - - /bin/sh - - -c - - |- - chown -R 1000:1000 /usr/share/elasticsearch/data; - apt-get update && apt-get install -y curl; - ./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment; - /usr/local/bin/docker-entrypoint.sh eswrapper - env: - - name: BITNAMI_DEBUG - value: "true" - - name: ELASTICSEARCH_PORT_NUMBER - value: "9200" - - name: ES_JAVA_OPTS - value: -Xms1024m -Xmx1024m - - name: discovery.type - value: single-node - - name: http.cors.allow-origin - value: http://localhost:8082 - - name: http.cors.enabled - value: "true" - image: elasticsearch:7.14.2 - livenessProbe: - exec: - command: - - /bin/sh - - -c - - curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' - initialDelaySeconds: 60 - periodSeconds: 20 - failureThreshold: 10 - name: elastic - ports: - - containerPort: 9200 - protocol: TCP - volumeMounts: - - mountPath: /usr/share/elasticsearch/data - name: elastic - restartPolicy: Always - volumes: - - name: elastic - persistentVolumeClaim: - claimName: elastic diff --git a/kube/elastic/elastic-service.yaml b/kube/elastic/elastic-service.yaml deleted file mode 100644 index 656d7be..0000000 --- a/kube/elastic/elastic-service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - labels: - app: elastic - name: elastic -spec: - ports: - - name: "9200" - port: 9200 - targetPort: 9200 - selector: - app: elastic diff --git a/kube/front/front-deployment.yaml b/kube/front/front-deployment.yaml deleted file mode 100644 index 52a7f30..0000000 --- a/kube/front/front-deployment.yaml +++ /dev/null @@ -1,78 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: front - name: front -spec: - replicas: 1 - selector: - matchLabels: - app: front - template: - metadata: - labels: - app: front - spec: - containers: - - env: - - name: ACCOUNTS_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: ACCOUNTS_URL - - name: ACCOUNTS_URL_INTERNAL - value: http://account - - name: CALENDAR_URL - value: http://calendar - - name: COLLABORATOR_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: COLLABORATOR_URL - - name: DEFAULT_LANGUAGE - value: en - - name: ELASTIC_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: ELASTIC_URL - - name: GMAIL_URL - value: http://gmail:8088 - - name: STORAGE_CONFIG - valueFrom: - secretKeyRef: - name: huly-secret - key: STORAGE_CONFIG - - name: MONGO_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: MONGO_URL - - name: REKONI_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: REKONI_URL - - name: SERVER_PORT - value: "8080" - - name: SERVER_SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - - name: TELEGRAM_URL - value: http://telegram:8086 - - name: TITLE - value: Huly Self Hosted - - name: UPLOAD_URL - value: /files - - name: STATS_URL - value: http://stats - - name: DESKTOP_UPDATES_CHANNEL - value: selfhost - image: hardcoreeng/front:v0.7.382 - name: front - ports: - - containerPort: 8080 - restartPolicy: Always diff --git a/kube/front/front-service.yaml b/kube/front/front-service.yaml deleted file mode 100644 index e9a6a0c..0000000 --- a/kube/front/front-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: front - name: front -spec: - ports: - - port: 80 - targetPort: 8080 - selector: - app: front diff --git a/kube/fulltext/fulltext-deployment.yaml b/kube/fulltext/fulltext-deployment.yaml deleted file mode 100644 index 19d1369..0000000 --- a/kube/fulltext/fulltext-deployment.yaml +++ /dev/null @@ -1,61 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: fulltext - name: fulltext -spec: - replicas: 1 - selector: - matchLabels: - app: fulltext - template: - metadata: - labels: - app: fulltext - spec: - containers: - - env: - - name: SERVER_SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - - name: DB_URL - valueFrom: - secretKeyRef: - name: huly-secret - key: CR_DB_URL - - name: FULLTEXT_DB_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: ELASTIC_URL - - name: ELASTIC_INDEX_NAME - valueFrom: - configMapKeyRef: - name: huly-config - key: ELASTIC_INDEX_NAME - - name: STORAGE_CONFIG - valueFrom: - secretKeyRef: - name: huly-secret - key: STORAGE_CONFIG - - name: REKONI_URL - value: http://rekoni - - name: ACCOUNTS_URL - value: http://account - - name: STATS_URL - value: http://stats - - name: QUEUE_CONFIG - value: redpanda:9092 - image: hardcoreeng/fulltext:v0.7.382 - name: fulltext - ports: - - containerPort: 4700 - hostPort: 4700 - protocol: TCP - resources: - limits: - memory: "512M" - restartPolicy: Always diff --git a/kube/fulltext/fulltext-service.yaml b/kube/fulltext/fulltext-service.yaml deleted file mode 100644 index c05a877..0000000 --- a/kube/fulltext/fulltext-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: fulltext - name: fulltext -spec: - ports: - - port: 80 - targetPort: 4700 - selector: - app: fulltext diff --git a/kube/minio/minio-deployment.yaml b/kube/minio/minio-deployment.yaml deleted file mode 100644 index 604dcbd..0000000 --- a/kube/minio/minio-deployment.yaml +++ /dev/null @@ -1,43 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: minio - name: minio -spec: - replicas: 1 - selector: - matchLabels: - app: minio - strategy: - type: Recreate - template: - metadata: - labels: - app: minio - spec: - containers: - - args: - - server - - /data - - --address - - :9000 - - --console-address - - :9001 - image: minio/minio - name: minio - ports: - - containerPort: 9000 - hostPort: 9000 - protocol: TCP - - containerPort: 9001 - hostPort: 9001 - protocol: TCP - volumeMounts: - - mountPath: /data - name: files - restartPolicy: Always - volumes: - - name: files - persistentVolumeClaim: - claimName: files diff --git a/kube/minio/minio-service.yaml b/kube/minio/minio-service.yaml deleted file mode 100644 index bbbc269..0000000 --- a/kube/minio/minio-service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: minio - name: minio -spec: - ports: - - name: "9000" - port: 9000 - targetPort: 9000 - - name: "9001" - port: 9001 - targetPort: 9001 - selector: - app: minio diff --git a/kube/overlays/example/kustomization.yaml b/kube/overlays/example/kustomization.yaml new file mode 100644 index 0000000..18f78c9 --- /dev/null +++ b/kube/overlays/example/kustomization.yaml @@ -0,0 +1,82 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# Set your namespace +namespace: huly + +resources: + - ../../base + +# Pin all Huly images to a specific version. +# Find the latest tag at https://hub.docker.com/u/hardcoreeng +images: + - name: hardcoreeng/front + newTag: latest + - name: hardcoreeng/account + newTag: latest + - name: hardcoreeng/transactor + newTag: latest + - name: hardcoreeng/collaborator + newTag: latest + - name: hardcoreeng/workspace + newTag: latest + - name: hardcoreeng/fulltext + newTag: latest + - name: hardcoreeng/rekoni-service + newTag: latest + - name: hardcoreeng/stats + newTag: latest + # hulykvs does not publish a :latest tag — pin explicitly + - name: hardcoreeng/hulykvs + newTag: s0.7.392 + +# Uncomment and set your domain to override the placeholder (huly.example). +# This replaces the ConfigMap values and Ingress hosts/TLS. +# +# patches: +# - target: +# kind: ConfigMap +# name: huly-config +# patch: | +# - op: replace +# path: /data/FRONT_URL +# value: "https://huly.yourdomain.com" +# - op: replace +# path: /data/ACCOUNTS_URL +# value: "https://huly.yourdomain.com/_accounts" +# - op: replace +# path: /data/COLLABORATOR_URL +# value: "wss://huly.yourdomain.com/_collaborator" +# - op: replace +# path: /data/REKONI_URL +# value: "https://huly.yourdomain.com/_rekoni" +# - op: replace +# path: /data/STATS_URL +# value: "https://huly.yourdomain.com/_stats" +# - op: replace +# path: /data/TRANSACTOR_URL +# value: "ws://transactor:3333;wss://huly.yourdomain.com/_transactor" +# - op: replace +# path: /data/GMAIL_URL +# value: "https://huly.yourdomain.com/_gmail" +# - op: replace +# path: /data/TELEGRAM_URL +# value: "https://huly.yourdomain.com/_telegram" +# - op: replace +# path: /data/CALENDAR_URL +# value: "https://huly.yourdomain.com/_calendar" +# - op: replace +# path: /data/LOVE_ENDPOINT +# value: "https://huly.yourdomain.com/_love" +# - op: replace +# path: /data/ADMIN_EMAILS +# value: "you@yourdomain.com" +# - target: +# kind: Ingress +# patch: | +# - op: replace +# path: /spec/tls/0/hosts/0 +# value: huly.yourdomain.com +# - op: replace +# path: /spec/rules/0/host +# value: huly.yourdomain.com diff --git a/kube/redpanda/redpanda-deployment.yaml b/kube/redpanda/redpanda-deployment.yaml deleted file mode 100644 index 3d58ef8..0000000 --- a/kube/redpanda/redpanda-deployment.yaml +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: redpanda - name: redpanda -spec: - replicas: 1 - selector: - matchLabels: - app: redpanda - template: - metadata: - labels: - app: redpanda - spec: - containers: - - env: - - name: REDPANDA_SUPERUSER_USERNAME - value: superuser - - name: REDPANDA_SUPERUSER_PASSWORD - valueFrom: - secretKeyRef: - name: huly-secret - key: REDPANDA_SUPERUSER_PASSWORD - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: docker.redpanda.com/redpandadata/redpanda:v24.3.6 - args: - - redpanda - - start - - --kafka-addr internal://0.0.0.0:9092,external://0.0.0.0:19092 - - --advertise-kafka-addr internal://redpanda:9092,external://localhost:19092 - - --pandaproxy-addr internal://0.0.0.0:8082,external://0.0.0.0:18082 - - --advertise-pandaproxy-addr internal://redpanda:8082,external://localhost:18082 - - --schema-registry-addr internal://0.0.0.0:8081,external://0.0.0.0:18081 - - --rpc-addr 0.0.0.0:33145 - - --advertise-rpc-addr redpanda:33145 - - --mode dev-container - - --smp 1 - - --default-log-level=info - name: redpanda - ports: - - containerPort: 9092 - - containerPort: 33145 - volumeMounts: - - mountPath: /var/lib/redpanda/data - name: redpanda - resources: - limits: - memory: "512M" - restartPolicy: Always - volumes: - - name: redpanda - persistentVolumeClaim: - claimName: redpanda diff --git a/kube/redpanda/redpanda-service.yaml b/kube/redpanda/redpanda-service.yaml deleted file mode 100644 index c548fef..0000000 --- a/kube/redpanda/redpanda-service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: redpanda - name: redpanda -spec: - ports: - - port: 9092 - targetPort: 9092 - name: kafka - - port: 33145 - targetPort: 33145 - name: rpc - selector: - app: redpanda diff --git a/kube/rekoni/rekoni-deployment.yaml b/kube/rekoni/rekoni-deployment.yaml deleted file mode 100644 index feee5a4..0000000 --- a/kube/rekoni/rekoni-deployment.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: rekoni - name: rekoni -spec: - replicas: 1 - selector: - matchLabels: - app: rekoni - template: - metadata: - labels: - app: rekoni - spec: - containers: - - image: hardcoreeng/rekoni-service:v0.7.382 - name: rekoni - env: - - name: SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - ports: - - containerPort: 4004 - hostPort: 4004 - protocol: TCP - resources: - limits: - memory: "500M" - restartPolicy: Always diff --git a/kube/rekoni/rekoni-ingress.yaml b/kube/rekoni/rekoni-ingress.yaml deleted file mode 100644 index bb598be..0000000 --- a/kube/rekoni/rekoni-ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.io/ingress.class: nginx - labels: - app: rekoni - name: rekoni -spec: - ingressClassName: nginx - rules: - - host: rekoni.huly.example - http: - paths: - - backend: - service: - name: rekoni - port: - number: 80 - path: / - pathType: Prefix diff --git a/kube/rekoni/rekoni-service.yaml b/kube/rekoni/rekoni-service.yaml deleted file mode 100644 index 0995308..0000000 --- a/kube/rekoni/rekoni-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: rekoni - name: rekoni -spec: - ports: - - port: 80 - targetPort: 4004 - selector: - app: rekoni diff --git a/kube/stats/stats-deployment.yaml b/kube/stats/stats-deployment.yaml deleted file mode 100644 index 661545a..0000000 --- a/kube/stats/stats-deployment.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: stats - name: stats -spec: - replicas: 1 - selector: - matchLabels: - app: stats - template: - metadata: - labels: - app: stats - spec: - containers: - - image: hardcoreeng/stats:v0.7.382 - name: stats - env: - - name: PORT - value: "4900" - - name: SERVER_SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - ports: - - containerPort: 4900 - hostPort: 4900 - protocol: TCP - resources: - limits: - memory: "500M" - restartPolicy: Always diff --git a/kube/stats/stats-ingress.yaml b/kube/stats/stats-ingress.yaml deleted file mode 100644 index e7088fe..0000000 --- a/kube/stats/stats-ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.io/ingress.class: nginx - labels: - app: stats - name: stats -spec: - ingressClassName: nginx - rules: - - host: stats.huly.example - http: - paths: - - backend: - service: - name: stats - port: - number: 80 - path: / - pathType: Prefix diff --git a/kube/stats/stats-service.yaml b/kube/stats/stats-service.yaml deleted file mode 100644 index 28b321b..0000000 --- a/kube/stats/stats-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: stats - name: stats -spec: - ports: - - port: 80 - targetPort: 4900 - selector: - app: stats diff --git a/kube/transactor/transactor-deployment.yaml b/kube/transactor/transactor-deployment.yaml deleted file mode 100644 index 6677e1f..0000000 --- a/kube/transactor/transactor-deployment.yaml +++ /dev/null @@ -1,62 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: transactor - name: transactor -spec: - replicas: 1 - selector: - matchLabels: - app: transactor - template: - metadata: - labels: - app: transactor - spec: - containers: - - env: - - name: ACCOUNTS_URL - value: http://account - - name: FULLTEXT_URL - value: http://fulltext - - name: FRONT_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: FRONT_URL - - name: STATS_URL - value: http://stats - - name: STORAGE_CONFIG - valueFrom: - secretKeyRef: - name: huly-secret - key: STORAGE_CONFIG - - name: MONGO_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: MONGO_URL - - name: DB_URL - valueFrom: - secretKeyRef: - name: huly-secret - key: CR_DB_URL - - name: SERVER_CURSOR_MAXTIMEMS - value: "30000" - - name: SERVER_PORT - value: "3333" - - name: SERVER_SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - - name: QUEUE_CONFIG - value: redpanda:9092 - image: hardcoreeng/transactor:v0.7.382 - name: transactor - ports: - - containerPort: 3333 - hostPort: 3333 - protocol: TCP - restartPolicy: Always diff --git a/kube/transactor/transactor-ingress.yaml b/kube/transactor/transactor-ingress.yaml deleted file mode 100644 index 84bfc33..0000000 --- a/kube/transactor/transactor-ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.io/ingress.class: nginx - labels: - app: transactor - name: transactor -spec: - ingressClassName: nginx - rules: - - host: transactor.huly.example - http: - paths: - - backend: - service: - name: transactor - port: - number: 80 - path: / - pathType: Prefix diff --git a/kube/transactor/transactor-service.yaml b/kube/transactor/transactor-service.yaml deleted file mode 100644 index bb14e3b..0000000 --- a/kube/transactor/transactor-service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: transactor - name: transactor -spec: - ports: - - port: 80 - protocol: TCP - targetPort: 3333 - selector: - app: transactor diff --git a/kube/workspace/workspace-deployment.yaml b/kube/workspace/workspace-deployment.yaml deleted file mode 100644 index 9d53939..0000000 --- a/kube/workspace/workspace-deployment.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: workspace - name: workspace -spec: - replicas: 1 - selector: - matchLabels: - app: workspace - template: - metadata: - labels: - app: workspace - spec: - containers: - - env: - - name: ACCOUNTS_URL - value: http://account - - name: STATS_URL - value: http://stats - - name: TRANSACTOR_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: TRANSACTOR_URL - - name: STORAGE_CONFIG - valueFrom: - secretKeyRef: - name: huly-secret - key: STORAGE_CONFIG - - name: MODEL_ENABLED - value: '*' - - name: DB_URL - valueFrom: - secretKeyRef: - name: huly-secret - key: CR_DB_URL - - name: MONGO_URL - valueFrom: - configMapKeyRef: - name: huly-config - key: MONGO_URL - - name: SERVER_SECRET - valueFrom: - secretKeyRef: - name: huly-secret - key: SERVER_SECRET - - name: QUEUE_CONFIG - value: redpanda:9092 - image: hardcoreeng/workspace:v0.7.382 - name: workspace - resources: - limits: - memory: "512M" - restartPolicy: Always