diff --git a/.gitignore b/.gitignore index 1339a53b7..a899c29dd 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,7 @@ yarn-error.log # System Files .DS_Store Thumbs.db + + +k8s/charts/ +k8s/Chart.lock \ No newline at end of file diff --git a/README.md b/README.md index af5a7a8c9..9d3368ee4 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,19 @@ docker-compose --env-file ./.env -f docker/docker-compose.build.yml build docker-compose --env-file ./.env -f docker/docker-compose.build.yml up -d ``` +### Run on Kubernetes + +Run the following commands to run ghostfolio in a k8s environment ([more details](./k8s/README.md)). + +```bash +kubectl create namespace ghostfolio +helm dependency update +helm install ghostfolio . --namespace ghostfolio +kubectl get svc --namespace ghostfolio +#If using Minikube, expose the service to localhost: +#minikube service ghostfolio-ghostfolio -n ghostfolio +``` + #### Setup 1. Open http://localhost:3333 in your browser diff --git a/k8s/.helmignore b/k8s/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/k8s/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/k8s/Chart.yaml b/k8s/Chart.yaml new file mode 100644 index 000000000..00f9448d4 --- /dev/null +++ b/k8s/Chart.yaml @@ -0,0 +1,33 @@ +apiVersion: v2 +name: ghostfolio-k8s +description: A Helm chart for deploying Ghostfolio on Kubernetes + +# This chart is designed for deploying Ghostfolio as an application on Kubernetes. + +# Chart Version: +# Increment this version number each time you make changes to the chart or its templates, +# including the app version. Follow Semantic Versioning (https://semver.org/). +version: 0.2.0 + +# Application Version: +# This is the version number of the application being deployed. Increment it for each +# change to the application. It doesn't follow Semantic Versioning and should reflect +# the actual version the application is using. Use quotes for compatibility. +appVersion: "1.0.0" + +# Dependencies: +# Specify dependencies for the chart. These are additional services or components +# required for Ghostfolio to run. Make sure to check and adjust version numbers +# accordingly. +dependencies: + - name: postgresql + version: 13.2.27 + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled + # Additional comments can be added to explain why this dependency is required. + + - name: redis + version: 18.6.2 + repository: https://charts.bitnami.com/bitnami + condition: redis.enabled + # Provide helpful comments to clarify the purpose of each dependency. diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 000000000..a0126b1ca --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,68 @@ +# Ghostfolio on Kubernetes with Helm - Developer's Quick Start Guide + +Welcome to the Ghostfolio Kubernetes deployment using Helm! This guide is designed to assist developers with limited Kubernetes (k8s) experience in effortlessly setting up Ghostfolio on any k8s platform. + +## Prerequisites + +Make sure you have the following dependencies installed: + +- [Kubernetes](https://kubernetes.io/) +- [Helm](https://helm.sh/) + +## Configuration + +1. Adjust Dependencies: + + Edit the `Charts.yaml` file to customize dependencies. + +2. Additional Configuration: + + Modify the `values.yaml` file to include extra configurations, like `API_KEY_COINGECKO_DEMO` or `API_KEY_COINGECKO_PRO`. + +## Deployment Steps + +1. Create a New Namespace: + + Run the following command to create a dedicated namespace for Ghostfolio: + + ```bash + kubectl create namespace ghostfolio + ``` + +2. Update Helm Dependencies: + + Keep your Helm dependencies up to date by running: + + ```bash + helm dependency update + ``` + +3. Deploy Ghostfolio with Helm: + + Execute the Helm installation command: + + ```bash + helm install ghostfolio . --namespace ghostfolio + ``` + +4. Verify Service Readiness: + + Check if the deployment is ready and the service is running: + + ```bash + kubectl get svc,deploy --namespace ghostfolio + ``` + +5. Access Ghostfolio in your Browser: + + Open your browser and navigate to: + + ```plaintext + localhost:32222 + ``` + + If using Minikube, expose the service to localhost with: + + ```bash + minikube service ghostfolio-ghostfolio -n ghostfolio + ``` \ No newline at end of file diff --git a/k8s/templates/deployment.yaml b/k8s/templates/deployment.yaml new file mode 100644 index 000000000..ccaa243b8 --- /dev/null +++ b/k8s/templates/deployment.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-ghostfolio + labels: + app: ghostfolio +spec: + replicas: {{ .Values.ghostfolio.replicaCount }} + selector: + matchLabels: + app: ghostfolio + template: + metadata: + labels: + app: ghostfolio + spec: + containers: + - name: ghostfolio + image: {{ .Values.ghostfolio.repository }}:{{ .Values.ghostfolio.tag }} + imagePullPolicy: {{ .Values.ghostfolio.pullPolicy }} + env: + {{- range .Values.ghostfolio.env }} + - name: {{ .name }} + value: {{ .value }} + {{- end }} + ports: + - containerPort: {{ .Values.ghostfolio.port }} + readinessProbe: + httpGet: + path: /api/v1/health + port: {{ .Values.ghostfolio.port }} + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + livenessProbe: + httpGet: + path: /api/v1/health + port: {{ .Values.ghostfolio.port }} + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 3 \ No newline at end of file diff --git a/k8s/templates/service.yaml b/k8s/templates/service.yaml new file mode 100644 index 000000000..97613ac90 --- /dev/null +++ b/k8s/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-ghostfolio +spec: + type: {{ .Values.service.type }} + selector: + app: ghostfolio + ports: + - port: {{ .Values.ghostfolio.port }} + targetPort: {{ .Values.ghostfolio.port }} + nodePort: {{ .Values.service.port }} + protocol: TCP \ No newline at end of file diff --git a/k8s/values.yaml b/k8s/values.yaml new file mode 100644 index 000000000..89651eae4 --- /dev/null +++ b/k8s/values.yaml @@ -0,0 +1,35 @@ +# Default values for ghostfolio-k8s. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +service: + type: NodePort + port: 32222 + +ghostfolio: + repository: ghostfolio/ghostfolio + tag: latest + replicaCount: 1 + port: 3333 + pullPolicy: IfNotPresent + env: + - name: DATABASE_URL + value: postgresql://user:ghostfolio@ghostfolio-postgresql/postgres?connect_timeout=300&sslmode=prefer + - name: ACCESS_TOKEN_SALT + value: ghostfolio-salty + - name: JWT_SECRET_KEY + value: ghostfolio-jwt + - name: REDIS_HOST + value: ghostfolio-redis-master + - name: REDIS_PASSWORD + value: ghostfolio + +postgresql: + auth: + username: user + password: ghostfolio + +redis: + architecture: standalone + auth: + password: ghostfolio