Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR for adding a first version of the Helm chart #125

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions safe-helm-chart/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
safe-wallet-web
README.md
24 changes: 24 additions & 0 deletions safe-helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: gnosis-safe
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.0.1

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.0.0"
20 changes: 20 additions & 0 deletions safe-helm-chart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
This is a first attempt in deploying the Safe infrastructure in Kubernetes [specifically EKS] using Helm.

### Notes

- The k8s resources are set up in two groups basically. The common ones and the chain-specific ones.
The common ones are the common for all chains.
The chain-specific, are gathered in the `templates/chain-specific` folder. In order to set up the chains that you wanna use, go to
the `values.yaml` file.


- The custom storage class has been created in order to give the choice to preserve the volumes created by specific components. You can enable/disable it on demand in the `values.yaml` file.


- You can deploy the hem chart using
```commandline
helm upgrade --install mysafe ./safe-helm-chart --values values_for_alb_ingress.yaml
```


- This is an early under heavy development version! Be kind :]
128 changes: 128 additions & 0 deletions safe-helm-chart/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# https://github.com/KyleAMathews/docker-nginx/blob/master/nginx.conf
# https://linode.com/docs/web-servers/nginx/configure-nginx-for-optimized-performance/
# https://docs.gunicorn.org/en/stable/deploy.html

worker_processes 1;

events {
worker_connections 2000; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
use epoll; # Enable epoll for Linux 2.6+
# 'use kqueue;' to enable for FreeBSD, OSX
}

http {
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
sendfile on;

## Transaction Service
upstream txs_app_server {
# ip_hash; # For load-balancing
#
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
server unix:/nginx-txs/gunicorn.socket fail_timeout=0;

# for a TCP configuration
# server web:8000 fail_timeout=0;
keepalive 32;
}

## Config service
upstream cfg_app_server {
ip_hash; # For load-balancing
# server cfg-web:8001 fail_timeout=0;
server unix:/nginx-cfg/gunicorn.socket fail_timeout=0;
#
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
keepalive 32;
}

## Client gateway
upstream cgw_app_server {
ip_hash; # For load-balancing
server {{ include "safe.fullname" . }}-cgw-web:3000 fail_timeout=0;
#
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
keepalive 32;
}

server {
access_log off;
listen 8000 deferred;
charset utf-8;
keepalive_timeout 75s;

# https://thoughts.t37.net/nginx-optimization-understanding-sendfile-tcp-nodelay-and-tcp-nopush-c55cdd276765
# tcp_nopush on;
# tcp_nodelay on;

gzip on;
gzip_min_length 1000;
gzip_comp_level 2;
# text/html is always included by default
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;
gzip_disable "MSIE [1-6]\.";

## Transaction service mounting point
location /txs/static {
alias /nginx-txs/staticfiles;
expires 365d;
}

location /txs/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://txs_app_server/;

proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header Front-End-Https on;
}

## Config service mounting point
location /cfg/static {
alias /nginx-cfg/staticfiles;
expires 365d;
}

location /cfg/ {
proxy_pass http://cfg_app_server/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
add_header Front-End-Https on;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# They default to 60s. Increase to avoid WORKER TIMEOUT in web container
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}

## Client gateway mounting point
location /cgw/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://cgw_app_server/;

proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header Front-End-Https on;
}
}
}
62 changes: 62 additions & 0 deletions safe-helm-chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "safe.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "safe.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 }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "safe.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

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

{{/*
Selector labels
*/}}
{{- define "safe.selectorLabels" -}}
app.kubernetes.io/name: {{ include "safe.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "safe.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "safe.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
42 changes: 42 additions & 0 deletions safe-helm-chart/templates/chain-specific/cm-txs-env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{{- $releaseName := .Release.Name }} # define the local var here

{{- range $chain, $chainValues := .Values.chains }}

{{ $pg_password := $chainValues.txs_db_pg_password }}
{{ $pg_user := $chainValues.txs_db_pg_user }}
{{ $txs_external_pg_endpoint := $chainValues.txs_db_pg_endpoint }}
{{ $pg_dbname := $chainValues.txs_db_pg_dbname }}
{{ $pg_db_port := $chainValues.txs_db_pg_db_port }}

{{ if $chainValues.enabled }}
---
apiVersion: v1
kind: ConfigMap

metadata:
name: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-env

data:
PYTHONPATH: /app/
DJANGO_SETTINGS_MODULE: config.settings.production
DJANGO_SECRET_KEY: 'Very-secure-secret-string'
DEBUG: '0'
ETH_L2_NETWORK: '1'

{{ if $txs_external_pg_endpoint }}
DATABASE_URL: psql://{{ $pg_user }}:{{ $pg_password }}@{{ $txs_external_pg_endpoint }}:{{ $pg_db_port }}/{{ $pg_dbname }}
{{ else }}
DATABASE_URL: psql://{{ $pg_user }}:{{ $pg_password }}@{{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-db:{{ $pg_db_port }}/{{ $pg_dbname }}
{{ end }}

REDIS_URL: redis://{{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-redis:6379/0
CELERY_BROKER_URL: amqp://guest:guest@{{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-rabbitmq/
DJANGO_ALLOWED_HOSTS: "*"
FORCE_SCRIPT_NAME: /txs/
CSRF_TRUSTED_ORIGINS: "http://localhost:8000"
EVENTS_QUEUE_URL: amqp://{{ $releaseName }}-general-rabbitmq:5672
EVENTS_QUEUE_ASYNC_CONNECTION: 'True'
EVENTS_QUEUE_EXCHANGE_NAME: "safe-transaction-service-events"

{{- end }} # if
{{- end }} # range
45 changes: 45 additions & 0 deletions safe-helm-chart/templates/chain-specific/deploy-txs-flower.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{{- $releaseName := .Release.Name }} # define the local var here

{{- range $chain, $chainValues := .Values.chains }}
{{ if $chainValues.enabled }}
---
apiVersion: apps/v1
kind: Deployment

metadata:
# A flower is a web-based tool for monitoring and administrating Celery clusters.
# ref: https://medium.com/featurepreneur/flower-celery-monitoring-tool-50fba1c8f623
name: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-flower

spec:
replicas: 1
selector:
matchLabels:
app: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-flower
template:
metadata:
labels:
app: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-flower
spec:
containers:
- name: {{ $chainValues.network_name | lower }}-txs-flower
image: safeglobal/safe-transaction-service:latest
command: ["docker/web/celery/flower/run.sh"]
ports:
- name: flower
containerPort: 5555
env:
- name: ETHEREUM_NODE_URL
value: {{ $chainValues.node_url }}
- name: RUN_MIGRATIONS
value: "1"
- name: WORKER_QUEUES
value: default,indexing
#- name: ETHEREUM_TRACING_NODE_URL
# value: http://tracing-node-url
envFrom:
- configMapRef:
name: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-env

{{- end }} # if
{{- end }} # range
48 changes: 48 additions & 0 deletions safe-helm-chart/templates/chain-specific/deploy-txs-pgdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{{- $releaseName := .Release.Name }} # define the local var here

{{- range $chain, $chainValues := .Values.chains }}

{{ $pg_password := $chainValues.txs_db_pg_password }}
{{ $pg_user := $chainValues.txs_db_pg_user }}
{{ $txs_external_pg_endpoint := $chainValues.txs_db_pg_endpoint }}
# if the chain is activated AND there is no external db endpoint set, then create the db pod
{{ if and $chainValues.enabled (ne $txs_external_pg_endpoint false) }}
---
apiVersion: apps/v1
kind: Deployment

metadata:
name: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-db

spec:
replicas: 1
selector:
matchLabels:
app: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-db
template:
metadata:
labels:
app: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-db
spec:
containers:
- name: {{ $chainValues.network_name | lower }}-txs-db
image: postgres:14-alpine
#
env:
- name: POSTGRES_PASSWORD
value: {{ $pg_password }}
- name: POSTGRES_USER
value: {{ $pg_user }}
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
#
volumeMounts:
- name: txs-db-claim0
mountPath: /var/lib/postgresql/data
subPath: txs-db-data
volumes:
- name: txs-db-claim0
persistentVolumeClaim:
claimName: {{ $releaseName }}-{{ $chainValues.network_name | lower }}-txs-db-claim0
{{- end }} # if
{{- end }} # range
Loading
Loading