diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 6601068..dff6c84 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -465,3 +465,37 @@ jobs: body: ${{ steps.changelog.outputs.changelog }} draft: false prerelease: false + + publish-helm-chart: + runs-on: ubuntu-latest + needs: [determine-version, build-and-push] + if: ${{ needs.determine-version.outputs.should_release == 'true' }} + permissions: + contents: read + packages: write + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.14.0 + + - name: Log in to GHCR + run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Update Chart.yaml with release version + run: | + VERSION="${{ needs.determine-version.outputs.new_version }}" + sed -i "s/^version: .*/version: ${VERSION}/" deploy/helm/Chart.yaml + sed -i "s/^appVersion: .*/appVersion: \"v${VERSION}\"/" deploy/helm/Chart.yaml + cat deploy/helm/Chart.yaml + + - name: Package Helm chart + run: helm package deploy/helm --destination . + + - name: Push Helm chart to GHCR + run: | + VERSION="${{ needs.determine-version.outputs.new_version }}" + helm push postgresus-${VERSION}.tgz oci://ghcr.io/rostislavdugin/charts diff --git a/README.md b/README.md index b4240fa..1a25071 100644 --- a/README.md +++ b/README.md @@ -159,32 +159,43 @@ docker compose up -d ### Option 4: Kubernetes with Helm -For Kubernetes deployments, use the official Helm chart. +For Kubernetes deployments, install directly from the OCI registry. -**Step 1:** Clone the repository: +**With ClusterIP + port-forward (development/testing):** ```bash -git clone https://github.com/RostislavDugin/postgresus.git -cd postgresus +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus \ + -n postgresus --create-namespace ``` -**Step 2:** Install with Helm: - ```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace +kubectl port-forward svc/postgresus-service 4005:4005 -n postgresus +# Access at http://localhost:4005 ``` -**Step 3:** Get the external IP: +**With LoadBalancer (cloud environments):** ```bash -kubectl get svc -n postgresus +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus \ + -n postgresus --create-namespace \ + --set service.type=LoadBalancer ``` -Access Postgresus at `http://` (port 80). +```bash +kubectl get svc postgresus-service -n postgresus +# Access at http://:4005 +``` -To customize the installation (e.g., storage size, NodePort instead of LoadBalancer), see the [Helm chart README](deploy/helm/README.md) for all configuration options. +**With Ingress (domain-based access):** -Config uses by default LoadBalancer, but has predefined values for Ingress and HTTPRoute as well. +```bash +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus \ + -n postgresus --create-namespace \ + --set ingress.enabled=true \ + --set ingress.hosts[0].host=backup.example.com +``` + +For more options (NodePort, TLS, HTTPRoute for Gateway API), see the [Helm chart README](deploy/helm/README.md). --- diff --git a/deploy/helm/Chart.yaml b/deploy/helm/Chart.yaml index 4fdf0b5..11c2a9c 100644 --- a/deploy/helm/Chart.yaml +++ b/deploy/helm/Chart.yaml @@ -2,11 +2,21 @@ apiVersion: v2 name: postgresus description: A Helm chart for Postgresus - PostgreSQL backup and management system type: application -version: 1.0.0 -appVersion: "v1.45.3" +version: 0.0.0 +appVersion: "latest" keywords: - postgresql - backup - database - restore home: https://github.com/RostislavDugin/postgresus + +sources: + - https://github.com/RostislavDugin/postgresus + - https://github.com/RostislavDugin/postgresus/tree/main/deploy/helm + +maintainers: + - name: Rostislav Dugin + url: https://github.com/RostislavDugin + +icon: https://raw.githubusercontent.com/RostislavDugin/postgresus/main/frontend/public/logo.svg diff --git a/deploy/helm/README.md b/deploy/helm/README.md index 60874ec..4333340 100644 --- a/deploy/helm/README.md +++ b/deploy/helm/README.md @@ -2,17 +2,21 @@ ## Installation -```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace -``` - -After installation, get the external IP: +Install directly from the OCI registry (no need to clone the repository): ```bash -kubectl get svc -n postgresus +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus --create-namespace ``` -Access Postgresus at `http://` (port 80). +## Accessing Postgresus + +By default, the chart creates a ClusterIP service. Use port-forward to access: + +```bash +kubectl port-forward svc/postgresus-service 4005:4005 -n postgresus +``` + +Then open `http://localhost:4005` in your browser. ## Configuration @@ -27,14 +31,14 @@ Access Postgresus at `http://` (port 80). | `image.pullPolicy` | Image pull policy | `Always` | | `replicaCount` | Number of replicas | `1` | -### Resources +### Service -| Parameter | Description | Default Value | -| --------------------------- | -------------- | ------------- | -| `resources.requests.memory` | Memory request | `1Gi` | -| `resources.requests.cpu` | CPU request | `500m` | -| `resources.limits.memory` | Memory limit | `1Gi` | -| `resources.limits.cpu` | CPU limit | `500m` | +| Parameter | Description | Default Value | +| -------------------------- | ----------------------- | ------------- | +| `service.type` | Service type | `ClusterIP` | +| `service.port` | Service port | `4005` | +| `service.targetPort` | Container port | `4005` | +| `service.headless.enabled` | Enable headless service | `true` | ### Storage @@ -46,93 +50,76 @@ Access Postgresus at `http://` (port 80). | `persistence.size` | Storage size | `10Gi` | | `persistence.mountPath` | Mount path | `/postgresus-data` | -### Service +### Resources -| Parameter | Description | Default Value | -| -------------------------- | ----------------------- | -------------- | -| `service.type` | Service type | `LoadBalancer` | -| `service.port` | External port | `80` | -| `service.targetPort` | Container port | `4005` | -| `service.headless.enabled` | Enable headless service | `true` | +| Parameter | Description | Default Value | +| --------------------------- | -------------- | ------------- | +| `resources.requests.memory` | Memory request | `1Gi` | +| `resources.requests.cpu` | CPU request | `500m` | +| `resources.limits.memory` | Memory limit | `1Gi` | +| `resources.limits.cpu` | CPU limit | `500m` | -### Traffic Exposure (3 Options) +## External Access Options -The chart supports 3 ways to expose Postgresus: +### Option 1: Port Forward (Default) -| Method | Use Case | Default | -| ------ | -------- | ------- | -| **LoadBalancer/NodePort** | Simple cloud clusters | Enabled | -| **Ingress** | Traditional nginx/traefik ingress controllers | Disabled | -| **HTTPRoute (Gateway API)** | Modern gateways (Istio, Envoy, Cilium) | Disabled | - -#### Ingress - -| Parameter | Description | Default Value | -| ----------------------- | ----------------- | ------------------------ | -| `ingress.enabled` | Enable Ingress | `false` | -| `ingress.className` | Ingress class | `nginx` | -| `ingress.hosts[0].host` | Hostname | `postgresus.example.com` | -| `ingress.tls` | TLS configuration | `[]` | - -#### HTTPRoute (Gateway API) - -| Parameter | Description | Default Value | -| --------------------- | -------------------------- | ---------------------------------- | -| `route.enabled` | Enable HTTPRoute | `false` | -| `route.apiVersion` | Gateway API version | `gateway.networking.k8s.io/v1` | -| `route.hostnames` | Hostnames for the route | `["postgresus.example.com"]` | -| `route.parentRefs` | Gateway references | `[]` | -| `route.annotations` | Route annotations | `{}` | - -### Health Checks - -| Parameter | Description | Default Value | -| ------------------------ | ---------------------- | ------------- | -| `livenessProbe.enabled` | Enable liveness probe | `true` | -| `readinessProbe.enabled` | Enable readiness probe | `true` | - -## Examples - -### Basic Installation (LoadBalancer on port 80) - -Default installation exposes Postgresus via LoadBalancer on port 80: +Best for development or quick access: ```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace +kubectl port-forward svc/postgresus-service 4005:4005 -n postgresus ``` -Access via `http://` +Access at `http://localhost:4005` -### Using NodePort +### Option 2: NodePort -If your cluster doesn't support LoadBalancer: +For direct access via node IP: ```yaml # nodeport-values.yaml service: type: NodePort - port: 80 + port: 4005 targetPort: 4005 nodePort: 30080 ``` ```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace -f nodeport-values.yaml +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus --create-namespace -f nodeport-values.yaml ``` -Access via `http://:30080` +Access at `http://:30080` -### Enable Ingress with HTTPS +### Option 3: LoadBalancer + +For cloud environments with load balancer support: + +```yaml +# loadbalancer-values.yaml +service: + type: LoadBalancer + port: 80 + targetPort: 4005 +``` + +```bash +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus --create-namespace -f loadbalancer-values.yaml +``` + +Get the external IP: + +```bash +kubectl get svc -n postgresus +``` + +Access at `http://` + +### Option 4: Ingress For domain-based access with TLS: ```yaml # ingress-values.yaml -service: - type: ClusterIP - port: 4005 - targetPort: 4005 - ingress: enabled: true className: nginx @@ -151,18 +138,15 @@ ingress: ``` ```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace -f ingress-values.yaml +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus --create-namespace -f ingress-values.yaml ``` -### HTTPRoute (Gateway API) +### Option 5: HTTPRoute (Gateway API) For clusters using Istio, Envoy Gateway, Cilium, or other Gateway API implementations: ```yaml # httproute-values.yaml -service: - type: ClusterIP - route: enabled: true hostnames: @@ -173,10 +157,35 @@ route: ``` ```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace -f httproute-values.yaml +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus --create-namespace -f httproute-values.yaml ``` -### Custom Storage Size +## Ingress Configuration + +| Parameter | Description | Default Value | +| ----------------------- | ----------------- | ------------------------ | +| `ingress.enabled` | Enable Ingress | `false` | +| `ingress.className` | Ingress class | `nginx` | +| `ingress.hosts[0].host` | Hostname | `postgresus.example.com` | +| `ingress.tls` | TLS configuration | `[]` | + +## HTTPRoute Configuration + +| Parameter | Description | Default Value | +| ------------------ | ----------------------- | ------------------------------ | +| `route.enabled` | Enable HTTPRoute | `false` | +| `route.apiVersion` | Gateway API version | `gateway.networking.k8s.io/v1` | +| `route.hostnames` | Hostnames for the route | `["postgresus.example.com"]` | +| `route.parentRefs` | Gateway references | `[]` | + +## Health Checks + +| Parameter | Description | Default Value | +| ------------------------ | ---------------------- | ------------- | +| `livenessProbe.enabled` | Enable liveness probe | `true` | +| `readinessProbe.enabled` | Enable readiness probe | `true` | + +## Custom Storage Size ```yaml # storage-values.yaml @@ -186,5 +195,17 @@ persistence: ``` ```bash -helm install postgresus ./deploy/helm -n postgresus --create-namespace -f storage-values.yaml +helm install postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus --create-namespace -f storage-values.yaml +``` + +## Upgrade + +```bash +helm upgrade postgresus oci://ghcr.io/rostislavdugin/charts/postgresus -n postgresus +``` + +## Uninstall + +```bash +helm uninstall postgresus -n postgresus ``` diff --git a/deploy/helm/values.yaml b/deploy/helm/values.yaml index 968de8d..ab946d0 100644 --- a/deploy/helm/values.yaml +++ b/deploy/helm/values.yaml @@ -16,8 +16,8 @@ replicaCount: 1 # Service configuration service: - type: LoadBalancer - port: 80 # External port (HTTP default) + type: ClusterIP + port: 4005 # Service port targetPort: 4005 # Internal container port # Headless service for StatefulSet headless: