diff --git a/deploy/kubernetes/README.md b/deploy/kubernetes/README.md new file mode 100644 index 000000000..daf5573c7 --- /dev/null +++ b/deploy/kubernetes/README.md @@ -0,0 +1,252 @@ +# OpenVSX Kubernetes Deployment + +Kubernetes manifests for deploying a self-hosted [OpenVSX](https://github.com/eclipse/openvsx) extension registry. + +## Architecture + +``` + ┌──────────┐ + │ Ingress │ (TLS termination) + └────┬─────┘ + │ + ┌────────────┼────────────┐ + │ /api, /user, /login, │ / (all other paths) + │ /oauth2, /admin, ... │ + │ │ + ┌──────▼──────┐ ┌───────▼──────┐ + │ OpenVSX │ │ OpenVSX │ + │ Server :8080│ │ WebUI :3000 │ + └──┬───────┬──┘ └──────────────┘ + │ │ +┌─────▼────┐ ┌▼──────────────┐ +│PostgreSQL│ │ Elasticsearch │ +│ :5432 │ │ :9200 │ +└──────────┘ └───────────────┘ + +┌──────────────┐ +│ OVSX CLI │ (utility pod) +└──────────────┘ +``` + +The Ingress splits traffic between the server and the WebUI based on the URL path. API, authentication, and admin routes go to the Spring Boot server; everything else is served by the WebUI (React SPA on Express). The WebUI resolves its backend URL from the browser's `location.host`, so both services must share the same hostname. + +## Components + +| File | Resources | Description | +|------|-----------|-------------| +| `namespace.yaml` | Namespace | `openvsx` namespace | +| `secrets.yaml` | Secret (x2) | Database credentials, OVSX PAT | +| `configmap.yaml` | ConfigMap | Spring Boot `application.yml` for the server | +| `postgresql.yaml` | Deployment, Service, PVC | PostgreSQL 16 database (1Gi storage) | +| `elasticsearch.yaml` | Deployment, Service | Elasticsearch 8.7.1 single-node for search | +| `openvsx-server.yaml` | Deployment, Service, PVC | OpenVSX server application (5Gi extension storage) | +| `openvsx-webui.yaml` | Deployment, Service | React frontend served via Express on port 3000 | +| `ovsx-cli.yaml` | Deployment | Utility pod with the `ovsx` CLI for admin tasks | +| `ingress.yaml` | Ingress | Nginx ingress with path-based routing and TLS | + +## Image Architectures + +The pre-built images from `ghcr.io/eclipse-openvsx/` are **amd64-only**. If your cluster runs on a different architecture (e.g. Apple Silicon / arm64), you must build the images from source: + +| Image | Default | Architectures | Source Dockerfile | +|-------|---------|---------------|-------------------| +| OpenVSX Server | `ghcr.io/eclipse-openvsx/openvsx-server:latest` | amd64 | `server/Dockerfile` | +| OpenVSX WebUI | `ghcr.io/eclipse-openvsx/openvsx-webui:latest` | amd64 | `webui/Dockerfile` | + +## Prerequisites + +- Kubernetes 1.24+ +- An Ingress controller (nginx-ingress by default) +- `kubectl` configured for your cluster +- _(Optional)_ A GitHub OAuth App for user authentication via GitHub login + +## Quick Start + +### 1. Configure secrets + +Encode your values in base64 and update `secrets.yaml`: + +```bash +# Database password +echo -n 'your-db-password' | base64 + +# Personal access token for the OVSX CLI +echo -n 'your-pat-token' | base64 +``` + +### 2. Configure the Ingress hostname + +Edit `ingress.yaml` and replace `openvsx.example.com` with your actual domain. Update the `secretName` under `tls` to point to a valid TLS certificate Secret, or remove the `tls` block to disable HTTPS. + +### 3. Deploy + +Apply manifests in order (secrets and config before workloads): + +```bash +kubectl apply -f deploy/kubernetes/namespace.yaml +kubectl apply -f deploy/kubernetes/secrets.yaml +kubectl apply -f deploy/kubernetes/configmap.yaml +kubectl apply -f deploy/kubernetes/postgresql.yaml +kubectl apply -f deploy/kubernetes/elasticsearch.yaml +kubectl apply -f deploy/kubernetes/openvsx-server.yaml +kubectl apply -f deploy/kubernetes/openvsx-webui.yaml +kubectl apply -f deploy/kubernetes/ovsx-cli.yaml +kubectl apply -f deploy/kubernetes/ingress.yaml +``` + +Or apply everything at once: + +```bash +kubectl apply -f deploy/kubernetes/ +``` + +### 4. Verify + +```bash +# Watch pods come up +kubectl -n openvsx get pods -w + +# Check the server logs +kubectl -n openvsx logs -f deployment/openvsx-server + +# Check the webui logs +kubectl -n openvsx logs -f deployment/openvsx-webui + +# Test the API once the server is ready +kubectl -n openvsx port-forward svc/openvsx-server 8080:8080 +curl http://localhost:8080/api/version + +# Test the WebUI +kubectl -n openvsx port-forward svc/openvsx-webui 3000:3000 +# Open http://localhost:3000 in a browser +``` + +The server has a long startup time (~1-2 minutes) due to Spring Boot initialization, Flyway migrations, and Elasticsearch index creation. The WebUI starts in seconds. + +## Configuration + +### Application settings + +The server's Spring Boot configuration lives in the `openvsx-server-config` ConfigMap (`configmap.yaml`). Key settings: + +| Setting | Default | Description | +|---------|---------|-------------| +| `spring.datasource.url` | `jdbc:postgresql://postgresql:5432/openvsx` | Database connection URL | +| `ovsx.elasticsearch.host` | `elasticsearch:9200` | Elasticsearch endpoint | +| `ovsx.storage.local.directory` | `/tmp/extensions` | Local extension file storage path | +| `ovsx.elasticsearch.clear-on-start` | `true` | Rebuild search index on startup | +| `ovsx.integrity.key-pair` | `create` | Integrity key pair mode (`create`, `renew`, `delete`) | +| `bucket4j.enabled` | `false` | API rate limiting | +| `ovsx.registry.version` | _(empty)_ | Version string displayed in the UI (e.g. `0.33.0`) | + +### Resource requirements + +| Component | CPU request | CPU limit | Memory request | Memory limit | +|-----------|------------|-----------|----------------|--------------| +| PostgreSQL | 200m | 1 | 512Mi | 2Gi | +| Elasticsearch | 500m | 1 | 1Gi | 2Gi | +| OpenVSX Server | 100m | 1 | 512Mi | 4Gi | +| OpenVSX WebUI | 50m | 500m | 128Mi | 512Mi | +| OVSX CLI | 20m | 250m | 128Mi | 256Mi | + +### Persistent storage + +| PVC | Default size | Mount path | Purpose | +|-----|-------------|------------|---------| +| `postgres-pvc` | 1Gi | `/var/lib/postgresql/data` | Database files | +| `extensions-pvc` | 5Gi | `/tmp/extensions` | Extension file storage | + +Adjust the `storage` values in the PVC specs as needed for your expected extension volume. + +## Ingress Routing + +The Ingress uses path-based routing so the WebUI and Server share a single hostname. The WebUI SPA derives the server URL from the browser's `location.host`, so this shared-hostname setup is required. + +| Path prefix | Backend | +|-------------|---------| +| `/api` | openvsx-server:8080 | +| `/user` | openvsx-server:8080 | +| `/login` | openvsx-server:8080 | +| `/logout` | openvsx-server:8080 | +| `/oauth2` | openvsx-server:8080 | +| `/login-providers` | openvsx-server:8080 | +| `/admin` | openvsx-server:8080 | +| `/actuator` | openvsx-server:8080 | +| `/documents` | openvsx-server:8080 | +| `/swagger-ui` | openvsx-server:8080 | +| `/v3/api-docs` | openvsx-server:8080 | +| `/` (everything else) | openvsx-webui:3000 | + +## Publishing Extensions + +Before publishing extensions, you need to create a user and a personal access token (PAT) directly in the database. Without GitHub OAuth configured, this is the only way to authenticate. + +### 1. Create a user in the database + +```bash +kubectl -n openvsx exec -it deployment/postgresql -- psql -U openvsx -d openvsx +``` + +```sql +INSERT INTO user_data (id, login_name, role) VALUES (1001, 'admin', 'admin'); +``` + +### 2. Create a personal access token + +```sql +INSERT INTO personal_access_token (id, user_data, value, active, created_timestamp, description, notified) +VALUES (1001, 1001, 'your_token_value', true, NOW(), 'CLI token', false); +``` + +### 3. Publish using the OVSX CLI + +The CLI pod runs as a long-lived utility container. Exec into it to publish or manage extensions: + +```bash +kubectl -n openvsx exec -it deployment/ovsx-cli -- sh + +# Inside the pod: +ovsx publish my-extension.vsix +ovsx get publisher.extension +``` + +The `OVSX_REGISTRY_URL` and `OVSX_PAT` environment variables are pre-configured. Update the `ovsx-pat` secret in `secrets.yaml` to match the token value you inserted into the database. + +## Deploying without Elasticsearch + +To use database-based search instead of Elasticsearch: + +1. Skip applying `elasticsearch.yaml` +2. Update `configmap.yaml` — set `ovsx.databasesearch.enabled` to `true` and remove the `ovsx.elasticsearch` section + +## Deploying without the WebUI + +If you use a combined server image that already bundles the WebUI (e.g. built from `deploy/docker/Dockerfile`): + +1. Skip applying `openvsx-webui.yaml` +2. Simplify `ingress.yaml` to route all traffic to the server on port 8080 + +## Monitoring + +The server exposes Actuator endpoints for monitoring: + +| Endpoint | Description | +|----------|-------------| +| `/actuator/health` | Health status (used by probes) | +| `/actuator/metrics` | Application metrics | +| `/actuator/prometheus` | Prometheus-compatible metrics | + +## Customization + +### Using a different Ingress controller + +Replace the `ingressClassName` and annotations in `ingress.yaml`. For example, for Traefik: + +```yaml +spec: + ingressClassName: traefik +``` + +### Cloud-based extension storage + +To use cloud storage (S3, GCS, Azure Blob) instead of local PVC storage, add the appropriate environment variables to the server deployment and update the ConfigMap. See the [OpenVSX documentation](https://github.com/eclipse/openvsx/wiki) for details on storage configuration. diff --git a/deploy/kubernetes/configmap.yaml b/deploy/kubernetes/configmap.yaml new file mode 100644 index 000000000..fe35c0ad2 --- /dev/null +++ b/deploy/kubernetes/configmap.yaml @@ -0,0 +1,123 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: openvsx-server-config + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server +data: + application.yml: | + logging: + pattern: + level: '%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]' + + server: + port: 8080 + jetty: + threads: + max-queue-capacity: 100 + + spring: + application: + name: openvsx-server + autoconfigure: + exclude: + - org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration + profiles: + include: ovsx + cache: + jcache: + config: classpath:ehcache.xml + datasource: + url: jdbc:postgresql://postgresql:5432/openvsx + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + flyway: + baseline-on-migrate: true + baseline-version: 0.1.0 + baseline-description: JobRunr tables + jpa: + open-in-view: false + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + hibernate: + ddl-auto: none + session: + store-type: jdbc + jdbc: + initialize-schema: never + thymeleaf: + enabled: false + # Uncomment and configure to enable GitHub OAuth authentication + # security: + # oauth2: + # client: + # registration: + # github: + # client-id: "" + # client-secret: "" + + management: + health: + redis: + enabled: false + probes: + enabled: true + endpoints: + web: + exposure: + include: + - health + - metrics + - prometheus + metrics: + distribution: + percentiles-histogram: + http: + server: + requests: true + client: + requests: true + + springdoc: + swagger-ui: + path: /swagger-ui + docExpansion: list + operationsSorter: alpha + supportedSubmitMethods: + - get + + org: + jobrunr: + job-scheduler: + enabled: true + background-job-server: + enabled: true + worker-count: 2 + dashboard: + enabled: false + database: + type: sql + miscellaneous: + allow-anonymous-data-usage: false + + bucket4j: + enabled: false + + ovsx: + databasesearch: + enabled: false + elasticsearch: + clear-on-start: true + host: elasticsearch:9200 + eclipse: + base-url: https://api.eclipse.org + publisher-agreement: + timezone: US/Eastern + integrity: + key-pair: create + storage: + local: + directory: /tmp/extensions diff --git a/deploy/kubernetes/elasticsearch.yaml b/deploy/kubernetes/elasticsearch.yaml new file mode 100644 index 000000000..777b2fd25 --- /dev/null +++ b/deploy/kubernetes/elasticsearch.yaml @@ -0,0 +1,104 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: elasticsearch + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: elasticsearch + app.kubernetes.io/instance: elasticsearch +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: elasticsearch + template: + metadata: + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: elasticsearch + app.kubernetes.io/instance: elasticsearch + spec: + initContainers: + - name: sysctl + image: busybox:1.36 + command: ["sysctl", "-w", "vm.max_map_count=262144"] + securityContext: + privileged: true + containers: + - name: elasticsearch + image: docker.elastic.co/elasticsearch/elasticsearch:8.18.8 + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 9200 + protocol: TCP + - name: transport + containerPort: 9300 + protocol: TCP + env: + - name: discovery.type + value: single-node + - name: xpack.security.enabled + value: "false" + - name: xpack.ml.enabled + value: "false" + - name: bootstrap.memory_lock + value: "true" + - name: cluster.routing.allocation.disk.threshold_enabled + value: "false" + - name: ES_JAVA_OPTS + value: "-Xms512m -Xmx512m" + resources: + requests: + cpu: 500m + memory: 1Gi + limits: + cpu: "1" + memory: 2Gi + livenessProbe: + httpGet: + path: /_cluster/health + port: 9200 + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 50 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /_cluster/health + port: 9200 + initialDelaySeconds: 15 + periodSeconds: 10 + failureThreshold: 50 + timeoutSeconds: 5 + securityContext: + capabilities: + drop: + - ALL +--- +apiVersion: v1 +kind: Service +metadata: + name: elasticsearch + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: elasticsearch + app.kubernetes.io/instance: elasticsearch +spec: + ports: + - name: http + port: 9200 + targetPort: 9200 + protocol: TCP + - name: transport + port: 9300 + targetPort: 9300 + protocol: TCP + selector: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: elasticsearch diff --git a/deploy/kubernetes/ingress.yaml b/deploy/kubernetes/ingress.yaml new file mode 100644 index 000000000..2b97e3d7a --- /dev/null +++ b/deploy/kubernetes/ingress.yaml @@ -0,0 +1,105 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: openvsx + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "true" +spec: + ingressClassName: nginx + tls: + - hosts: + - openvsx.example.com + secretName: openvsx-tls + rules: + - host: openvsx.example.com + http: + paths: + # API, authentication, and admin routes -> server + - path: /api + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /user + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /login + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /logout + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /oauth2 + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /login-providers + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /admin + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /actuator + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /documents + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /swagger-ui + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + - path: /v3/api-docs + pathType: Prefix + backend: + service: + name: openvsx-server + port: + number: 8080 + # Everything else -> webui + - path: / + pathType: Prefix + backend: + service: + name: openvsx-webui + port: + number: 3000 diff --git a/deploy/kubernetes/namespace.yaml b/deploy/kubernetes/namespace.yaml new file mode 100644 index 000000000..6bcdefe28 --- /dev/null +++ b/deploy/kubernetes/namespace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/part-of: openvsx diff --git a/deploy/kubernetes/openvsx-server.yaml b/deploy/kubernetes/openvsx-server.yaml new file mode 100644 index 000000000..86569593e --- /dev/null +++ b/deploy/kubernetes/openvsx-server.yaml @@ -0,0 +1,115 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: extensions-pvc + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: openvsx-server + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server + app.kubernetes.io/instance: openvsx-server +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server + template: + metadata: + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server + app.kubernetes.io/instance: openvsx-server + spec: + containers: + - name: openvsx-server + image: ghcr.io/eclipse-openvsx/openvsx-server:latest + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + protocol: TCP + env: + - name: DB_USERNAME + valueFrom: + secretKeyRef: + name: postgresql-credentials + key: username + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: postgresql-credentials + key: password + volumeMounts: + - name: config + mountPath: /home/openvsx/server/config + readOnly: true + - name: extensions-storage + mountPath: /tmp/extensions + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: "1" + memory: 4Gi + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 30 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 20 + failureThreshold: 30 + timeoutSeconds: 5 + securityContext: + capabilities: + drop: + - ALL + volumes: + - name: config + configMap: + name: openvsx-server-config + - name: extensions-storage + persistentVolumeClaim: + claimName: extensions-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: openvsx-server + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server + app.kubernetes.io/instance: openvsx-server +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + protocol: TCP + selector: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-server diff --git a/deploy/kubernetes/openvsx-webui.yaml b/deploy/kubernetes/openvsx-webui.yaml new file mode 100644 index 000000000..cae90a4e3 --- /dev/null +++ b/deploy/kubernetes/openvsx-webui.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: openvsx-webui + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-webui + app.kubernetes.io/instance: openvsx-webui +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-webui + template: + metadata: + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-webui + app.kubernetes.io/instance: openvsx-webui + spec: + containers: + - name: openvsx-webui + image: ghcr.io/eclipse-openvsx/openvsx-webui:latest + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 3000 + protocol: TCP + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + readinessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 15 + periodSeconds: 20 + failureThreshold: 3 + timeoutSeconds: 5 + securityContext: + capabilities: + drop: + - ALL +--- +apiVersion: v1 +kind: Service +metadata: + name: openvsx-webui + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-webui + app.kubernetes.io/instance: openvsx-webui +spec: + ports: + - name: http + port: 3000 + targetPort: 3000 + protocol: TCP + selector: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: openvsx-webui diff --git a/deploy/kubernetes/ovsx-cli.yaml b/deploy/kubernetes/ovsx-cli.yaml new file mode 100644 index 000000000..e16e61d99 --- /dev/null +++ b/deploy/kubernetes/ovsx-cli.yaml @@ -0,0 +1,47 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ovsx-cli + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: ovsx-cli + app.kubernetes.io/instance: ovsx-cli +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: ovsx-cli + template: + metadata: + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: ovsx-cli + app.kubernetes.io/instance: ovsx-cli + spec: + containers: + - name: ovsx-cli + image: node:22-alpine + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c"] + args: ["npm install -g ovsx && tail -f /dev/null"] + env: + - name: OVSX_REGISTRY_URL + value: http://openvsx-server:8080 + - name: OVSX_PAT + valueFrom: + secretKeyRef: + name: ovsx-pat + key: token + resources: + requests: + cpu: 20m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + securityContext: + capabilities: + drop: + - ALL diff --git a/deploy/kubernetes/postgresql.yaml b/deploy/kubernetes/postgresql.yaml new file mode 100644 index 000000000..6849477ea --- /dev/null +++ b/deploy/kubernetes/postgresql.yaml @@ -0,0 +1,121 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pvc + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgresql + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql + app.kubernetes.io/instance: postgresql +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql + template: + metadata: + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql + app.kubernetes.io/instance: postgresql + spec: + securityContext: + runAsUser: 999 + runAsGroup: 999 + fsGroup: 999 + containers: + - name: postgresql + image: postgres:16.2 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 5432 + protocol: TCP + env: + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: postgresql-credentials + key: database + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: postgresql-credentials + key: username + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgresql-credentials + key: password + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + volumeMounts: + - name: postgres-storage + mountPath: /var/lib/postgresql/data + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: "1" + memory: 2Gi + livenessProbe: + exec: + command: + - pg_isready + - -U + - openvsx + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + exec: + command: + - pg_isready + - -U + - openvsx + initialDelaySeconds: 15 + periodSeconds: 10 + failureThreshold: 3 + timeoutSeconds: 5 + volumes: + - name: postgres-storage + persistentVolumeClaim: + claimName: postgres-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: postgresql + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql + app.kubernetes.io/instance: postgresql +spec: + ports: + - name: postgresql + port: 5432 + targetPort: 5432 + protocol: TCP + selector: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql diff --git a/deploy/kubernetes/secrets.yaml b/deploy/kubernetes/secrets.yaml new file mode 100644 index 000000000..c128882fa --- /dev/null +++ b/deploy/kubernetes/secrets.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Secret +metadata: + name: postgresql-credentials + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: postgresql +type: Opaque +data: + # base64 encoded values — replace with your own + # echo -n 'openvsx' | base64 + database: b3BlbnZzeA== + username: b3BlbnZzeA== + password: b3BlbnZzeA== +--- +apiVersion: v1 +kind: Secret +metadata: + name: ovsx-pat + namespace: openvsx + labels: + app.kubernetes.io/name: openvsx + app.kubernetes.io/component: ovsx-cli +type: Opaque +data: + # base64 encoded value — replace with your own + token: ""