Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/publish-helm-chart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Publish Helm Chart to S3

on:
push:
branches:
- master
paths:
- "deployments/helm-chart/**"
release:
types: [published]

workflow_dispatch:

# Required permissions for the workflow
permissions:
contents: read # for actions/checkout

jobs:
publish:
runs-on: ubuntu-latest

env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ENDPOINT_URL_S3: ${{ secrets.AWS_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

steps:
- name: Checkout repository
uses: actions/checkout@v5

- name: Set up Helm
uses: azure/setup-helm@v4

- name: Install helm-s3 plugin
run: |
helm plugin install https://github.com/hypnoglow/helm-s3.git

- name: Package Helm chart
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
RAW_TAG="${{ github.event.release.tag_name }}"
CHART_VERSION="${RAW_TAG#v}"
APP_VERSION="${RAW_TAG#v}"
else
CHART_VERSION="0.0.0-$(git rev-parse --short HEAD)"
APP_VERSION="latest"
fi
helm package deployments/helm-chart --version "${CHART_VERSION}" --app-version "${APP_VERSION}"

- name: Initialize S3 repository
run: |
if ! helm repo list | grep s3-repo; then
helm repo add s3-repo s3://${{ secrets.AWS_BUCKET }}/charts
fi

- name: Push Helm chart to S3
run: |
helm s3 push server-*.tgz s3-repo

- name: Clean up
run: |
rm -f server-*.tgz index.yaml
17 changes: 17 additions & 0 deletions deployments/helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v2
name: server
description: Helm chart for SMSGate Server
type: application
version: 0.1.0
appVersion: "1.29.3"
keywords:
- sms
- gateway
- android
- messaging
home: https://github.com/android-sms-gateway/server
sources:
- https://github.com/android-sms-gateway/server
maintainers:
- name: Aleksandr Soloshenko
email: [email protected]
157 changes: 157 additions & 0 deletions deployments/helm-chart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# SMSGate Server Helm Chart

This Helm chart deploys the SMSGate Server to a Kubernetes cluster. The server acts as the backend component for the [SMSGate app](https://github.com/capcom6/android-sms-gateway), facilitating SMS messaging through connected Android devices.

## Prerequisites

- Kubernetes 1.19+
- Helm 3.2.0+
- PV provisioner support in the underlying infrastructure (if using persistent storage for database)

## Installation

To install the chart with the release name `my-release`:

```bash
helm repo add sms-gate https://s3.sms-gate.app/charts
helm repo update
helm install my-release sms-gate/server
```

## Uninstallation

To uninstall/delete the `my-release` deployment:

```bash
helm delete my-release
```

## Configuration

The following table lists the configurable parameters of the SMSGate chart and their default values.

| Parameter | Description | Default |
| ----------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------- |
| `replicaCount` | Number of replicas | `1` |
| `image.repository` | Container image repository | `ghcr.io/android-sms-gateway/server` |
| `image.tag` | Container image tag | `latest` |
| `image.pullPolicy` | Container image pull policy | `IfNotPresent` |
| `service.type` | Kubernetes service type | `ClusterIP` |
| `service.port` | Service port | `3000` |
| `ingress.enabled` | Enable ingress | `false` |
| `ingress.className` | Ingress class name | `""` |
| `ingress.hosts` | Ingress hosts configuration | `[{host: sms-gateway.local, paths: [{path: /, pathType: ImplementationSpecific}]}]` |
| `resources` | Resource requests/limits | `{requests: {cpu: 100m, memory: 128Mi}, limits: {cpu: 500m, memory: 512Mi}}` |
| `autoscaling.enabled` | Enable autoscaling | `false` |
| `autoscaling.minReplicas` | Minimum replicas for autoscaling | `1` |
| `autoscaling.maxReplicas` | Maximum replicas for autoscaling | `5` |
| `autoscaling.targetCPUUtilizationPercentage` | Target CPU utilization percentage | `80` |
| `autoscaling.targetMemoryUtilizationPercentage` | Target memory utilization percentage | `80` |
| `database.host` | Database host | `db` |
| `database.port` | Database port | `3306` |
| `database.user` | Database user | `sms` |
| `database.password` | Database password | `""` |
| `database.name` | Database name | `sms` |
| `database.deployInternal` | Deploy internal MariaDB | `true` |
| `gateway.privateToken` | Private token for device registration | `""` |
| `gateway.fcmCredentials` | Firebase Cloud Messaging credentials | `""` |
| `gateway.config.enabled` | Enable config file mounting | `false` |
| `gateway.config.existingConfigMap` | Existing ConfigMap to use | `""` |
| `gateway.config.data` | Inline YAML config content | `""` |
| `env` | Additional environment variables | `{}` |

## Custom Configuration

### Using an External Database

To use an external database instead of the built-in MariaDB:

```yaml
database:
deployInternal: false
host: external-db-host
port: 3306
user: external-user
password: "secure-password"
name: external-db
```

### Configuring Ingress

To enable ingress with TLS:

```yaml
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: sms-gateway.example.com
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- sms-gateway.example.com
secretName: sms-gateway-tls
```

### Setting Resource Limits

To adjust resource requests and limits:

```yaml
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 200m
memory: 256Mi
```

### Configuring Config File Mounting

#### Using an Existing ConfigMap

To use an existing ConfigMap for configuration:

```yaml
gateway:
config:
enabled: true
existingConfigMap: my-existing-configmap
```

#### Using Inline YAML Configuration

To provide configuration using inline YAML:

```yaml
gateway:
config:
enabled: true
data: |
tasks:
hashing:
interval_seconds: 900
```

## Notes

- The application health endpoint is available at `/health`
- When using private mode, you must set `gateway.privateToken`
- For production use, always set secure passwords and enable TLS
- The chart supports persistent storage for the internal MariaDB database
- The config file mounting feature is optional and can be enabled by setting `gateway.config.enabled` to `true`
- When using config file mounting, you can either specify an existing ConfigMap with `gateway.config.existingConfigMap` or provide inline YAML configuration with `gateway.config.data`
- Environment variables remain an alternative configuration method and can be set using the `env` parameter

## License

This Helm chart is licensed under the Apache-2.0 license. See [LICENSE](LICENSE) for more information.

## Legal Notice

Android is a trademark of Google LLC.
33 changes: 33 additions & 0 deletions deployments/helm-chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
SMSGate Server has been deployed!

1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.hosts }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }}{{ if .paths }}{{ index .paths 0 "path" }}{{ else }}/{{ end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "sms-gateway.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "sms-gateway.fullname" . }}'
export SERVICE_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "sms-gateway.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}')
echo http://$SERVICE_HOST:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "sms-gateway.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

2. Check the application health:
curl http://<address>/health

3. Database information:
{{- if .Values.database.deployInternal }}
Internal MariaDB deployed at: {{ include "sms-gateway.fullname" . }}-db:3306
Root password: (stored in secret {{ include "sms-gateway.fullname" . }}-db-secrets)
{{- else }}
Using external database at: {{ .Values.database.host }}:{{ .Values.database.port }}
{{- end }}
42 changes: 42 additions & 0 deletions deployments/helm-chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{{- define "sms-gateway.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{- define "sms-gateway.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "sms-gateway.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "sms-gateway.selectorLabels" -}}
app.kubernetes.io/name: {{ include "sms-gateway.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{- define "sms-gateway.labels" -}}
helm.sh/chart: {{ include "sms-gateway.chart" . }}
{{ include "sms-gateway.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "sms-gateway.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "sms-gateway.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
11 changes: 11 additions & 0 deletions deployments/helm-chart/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if and .Values.gateway.config.enabled (not .Values.gateway.config.existingConfigMap) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "sms-gateway.fullname" . }}-config
labels:
{{- include "sms-gateway.labels" . | nindent 4 }}
data:
config.yml: |
{{- .Values.gateway.config.data | nindent 4 }}
{{- end }}
Loading
Loading