Skip to content
Open
43 changes: 43 additions & 0 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Build & Deploy to Production
on:
push:
branches: ['chore/initial-k8-config']
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check Out Repo
uses: actions/checkout@v4
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push to mail-server
uses: docker/build-push-action@v5
with:
context: ./
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/mail-server:${{ github.sha }}

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: production
steps:
- uses: actions/checkout@v4

- name: Update mail-server image
uses: steebchen/kubectl@v2.0.0
with:
config: ${{ secrets.KUBE_CONFIG_DATA }}
command: set image --record deployment/mail-server mail-server=${{ secrets.DOCKERHUB_USERNAME }}/mail-server:${{ github.sha }} -n mail
- name: Verify mail-server rollout
uses: steebchen/kubectl@v2.0.0
with:
config: ${{ secrets.KUBE_CONFIG_DATA }}
command: rollout status deployment/mail-server -n mail
6 changes: 6 additions & 0 deletions deploy/charts/mail-server/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: mail-server
description: Internxt Mail Server (NestJS) — stateless service in front of Stalwart
type: application
version: 0.1.0
appVersion: "0.1.0"
72 changes: 72 additions & 0 deletions deploy/charts/mail-server/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mail-server
labels:
app: mail-server
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: mail-server
template:
metadata:
labels:
app: mail-server
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:

Check warning

Code scanning / SonarCloud

Service account permissions should be restricted Medium

Bind this resource's automounted service account to RBAC or disable automounting. See more on SonarQube Cloud

Check warning on line 21 in deploy/charts/mail-server/templates/deployment.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Bind this resource's automounted service account to RBAC or disable automounting.

See more on https://sonarcloud.io/project/issues?id=internxt_mail-server&issues=AZ3BusRnRuvhNyq5hzmZ&open=AZ3BusRnRuvhNyq5hzmZ&pullRequest=21
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
- name: mail-server

Check warning on line 22 in deploy/charts/mail-server/templates/deployment.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Specify a storage request for this container.

See more on https://sonarcloud.io/project/issues?id=internxt_mail-server&issues=AZ3BusRnRuvhNyq5hzmY&open=AZ3BusRnRuvhNyq5hzmY&pullRequest=21
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Check warning on line 23 in deploy/charts/mail-server/templates/deployment.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use a specific version tag for the image instead of "latest".

See more on https://sonarcloud.io/project/issues?id=internxt_mail-server&issues=AZ3BusRnRuvhNyq5hzma&open=AZ3BusRnRuvhNyq5hzma&pullRequest=21
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
env:
- name: NODE_ENV
value: {{ .Values.nodeEnv | quote }}
- name: PORT
value: {{ .Values.service.port | quote }}
- name: RDS_HOSTNAME
value: {{ .Values.database.host | quote }}
- name: RDS_PORT
value: {{ .Values.database.port | quote }}
- name: RDS_DBNAME
value: {{ .Values.database.name | quote }}
- name: RDS_USERNAME
value: {{ .Values.database.username | quote }}
- name: STALWART_JMAP_URL
value: {{ .Values.stalwart.jmapUrl | quote }}
- name: STALWART_ADMIN_URL
value: {{ .Values.stalwart.adminUrl | quote }}
- name: STALWART_ADMIN_USER
value: {{ .Values.stalwart.adminUser | quote }}
- name: STALWART_MASTER_USER
value: {{ .Values.stalwart.masterUser | quote }}
- name: PAYMENTS_API_URL
value: {{ .Values.paymentsApiUrl | quote }}
- name: REDIS_URL
value: {{ .Values.redisUrl | quote }}
- name: MTA_HOOKS_USERNAME
value: {{ .Values.mta.hooksUsername | quote }}

envFrom:
- secretRef:
name: {{ .Values.secretName }}
livenessProbe:
httpGet:
path: {{ .Values.probes.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
readinessProbe:
httpGet:
path: {{ .Values.probes.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
15 changes: 15 additions & 0 deletions deploy/charts/mail-server/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: mail-server
labels:
app: mail-server
spec:
type: {{ .Values.service.type }}
selector:
app: mail-server
ports:
- name: http
port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
53 changes: 53 additions & 0 deletions deploy/charts/mail-server/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
replicaCount: 2

image:
repository: internxt/mail-server
tag: latest
pullPolicy: IfNotPresent

imagePullSecrets: []

service:
type: LoadBalancer
port: 3100

resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi

nodeEnv: production

paymentsApiUrl: 'https://gateway.internxt.com/payments'

redisUrl: REPLACE_ME

database:
host: REPLACE_ME
port: '5432'
name: REPLACE_ME
username: REPLACE_ME

stalwart:
jmapUrl: http://stalwart:8080
adminUrl: http://stalwart:8080
adminUser: mail-server
masterUser: master

mta:
hooksUsername: stalwart

secretName: mail-server-secrets

probes:
liveness:
path: /health
initialDelaySeconds: 20
periodSeconds: 10
readiness:
path: /health
initialDelaySeconds: 5
periodSeconds: 5
6 changes: 6 additions & 0 deletions deploy/charts/stalwart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: stalwart
description: Stalwart mail server (SMTP/IMAP/JMAP)
type: application
version: 0.1.0
appVersion: "0.11.0"
9 changes: 9 additions & 0 deletions deploy/charts/stalwart/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: stalwart-config
labels:
app: stalwart
data:
config.toml: |
{{ tpl .Values.config . | indent 4 }}
39 changes: 39 additions & 0 deletions deploy/charts/stalwart/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: stalwart
labels:
app: stalwart
spec:
type: {{ .Values.service.type }}
selector:
app: stalwart
ports:
- name: http
port: {{ .Values.service.ports.http }}
targetPort: http
protocol: TCP
- name: smtp
port: {{ .Values.service.ports.smtp }}
targetPort: smtp
protocol: TCP
- name: submission
port: {{ .Values.service.ports.submission }}
targetPort: submission
protocol: TCP
- name: imap
port: {{ .Values.service.ports.imap }}
targetPort: imap
protocol: TCP
{{- if gt (int .Values.service.ports.submissions) 0 }}
- name: submissions
port: {{ .Values.service.ports.submissions }}
targetPort: submissions
protocol: TCP
{{- end }}
{{- if gt (int .Values.service.ports.imaps) 0 }}
- name: imaps
port: {{ .Values.service.ports.imaps }}
targetPort: imaps
protocol: TCP
{{- end }}
79 changes: 79 additions & 0 deletions deploy/charts/stalwart/templates/statefulset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: stalwart
labels:
app: stalwart
spec:
serviceName: stalwart
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: stalwart
template:
metadata:
labels:
app: stalwart
annotations:
checksum/config: {{ .Values.config | sha256sum }}
spec:
containers:

Check warning

Code scanning / SonarCloud

Service account permissions should be restricted Medium

Bind this resource's automounted service account to RBAC or disable automounting. See more on SonarQube Cloud

Check warning on line 20 in deploy/charts/stalwart/templates/statefulset.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Bind this resource's automounted service account to RBAC or disable automounting.

See more on https://sonarcloud.io/project/issues?id=internxt_mail-server&issues=AZ2RlqyS8vXIT0bFC5II&open=AZ2RlqyS8vXIT0bFC5II&pullRequest=21
- name: stalwart

Check warning

Code scanning / SonarCloud

Storage limits should be enforced Medium

Specify a storage limit for this container. See more on SonarQube Cloud

Check warning on line 21 in deploy/charts/stalwart/templates/statefulset.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Specify a storage request for this container.

See more on https://sonarcloud.io/project/issues?id=internxt_mail-server&issues=AZ2RlqyS8vXIT0bFC5IH&open=AZ2RlqyS8vXIT0bFC5IH&pullRequest=21

Check warning on line 21 in deploy/charts/stalwart/templates/statefulset.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Specify a storage limit for this container.

See more on https://sonarcloud.io/project/issues?id=internxt_mail-server&issues=AZ2RlqyS8vXIT0bFC5IJ&open=AZ2RlqyS8vXIT0bFC5IJ&pullRequest=21
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.ports.http }}
- name: smtp
containerPort: {{ .Values.service.ports.smtp }}
- name: submission
containerPort: {{ .Values.service.ports.submission }}
- name: imap
containerPort: {{ .Values.service.ports.imap }}
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
envFrom:
- secretRef:
name: {{ .Values.secretName }}
livenessProbe:
httpGet:
path: /healthz/live
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /healthz/ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
volumeMounts:
- name: config
mountPath: /opt/stalwart/etc/config.toml
subPath: config.toml
{{- if .Values.persistence.enabled }}
- name: data
mountPath: /opt/stalwart
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: config
configMap:
name: stalwart-config
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
{{- if .Values.persistence.storageClass }}
storageClassName: {{ .Values.persistence.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}
Loading
Loading