Add Stalwart all-in-one mail server: SMTP (cluster-internal relay for Mattermost), IMAP + HTTPS admin via Tailscale proxy. RocksDB storage, self-signed TLS (stalwart-tls secret). No public MX, no outbound SMTP. SCW TEM relay noted in NetworkPolicy comments for future use. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
349 lines
10 KiB
YAML
349 lines
10 KiB
YAML
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: tailscale-gitlab
|
|
namespace: foxhunt
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: Role
|
|
metadata:
|
|
name: tailscale-gitlab
|
|
namespace: foxhunt
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["secrets"]
|
|
verbs: ["create", "get", "update", "patch"]
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: tailscale-gitlab
|
|
namespace: foxhunt
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: tailscale-gitlab
|
|
namespace: foxhunt
|
|
roleRef:
|
|
kind: Role
|
|
name: tailscale-gitlab
|
|
apiGroup: rbac.authorization.k8s.io
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: tailscale-gitlab-proxy
|
|
namespace: foxhunt
|
|
labels:
|
|
app.kubernetes.io/name: tailscale-gitlab-proxy
|
|
app.kubernetes.io/part-of: foxhunt
|
|
spec:
|
|
replicas: 1
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: tailscale-gitlab-proxy
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: tailscale-gitlab-proxy
|
|
spec:
|
|
serviceAccountName: tailscale-gitlab
|
|
nodeSelector:
|
|
k8s.scaleway.com/pool-name: platform
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:alpine
|
|
ports:
|
|
- containerPort: 80
|
|
- containerPort: 443
|
|
- containerPort: 5050
|
|
volumeMounts:
|
|
- name: nginx-conf
|
|
mountPath: /etc/nginx/conf.d
|
|
- name: tls-certs
|
|
mountPath: /etc/nginx/certs
|
|
readOnly: true
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 100m
|
|
memory: 64Mi
|
|
- name: ssh-proxy
|
|
image: alpine/socat:latest
|
|
args:
|
|
- "TCP-LISTEN:2222,fork,reuseaddr,sndbuf=1048576,rcvbuf=1048576"
|
|
- "TCP:gitlab-gitlab-shell.foxhunt.svc.cluster.local:2222,sndbuf=1048576,rcvbuf=1048576"
|
|
ports:
|
|
- containerPort: 2222
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 64Mi
|
|
limits:
|
|
cpu: 200m
|
|
memory: 128Mi
|
|
- name: imap-proxy
|
|
image: alpine/socat:latest
|
|
args:
|
|
- "TCP-LISTEN:993,fork,reuseaddr"
|
|
- "TCP:stalwart.foxhunt.svc.cluster.local:993"
|
|
ports:
|
|
- containerPort: 993
|
|
resources:
|
|
requests:
|
|
cpu: 10m
|
|
memory: 16Mi
|
|
limits:
|
|
cpu: 50m
|
|
memory: 32Mi
|
|
- name: tailscale
|
|
image: ghcr.io/tailscale/tailscale:latest
|
|
env:
|
|
- name: TS_AUTHKEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: tailscale-auth
|
|
key: TS_AUTHKEY
|
|
- name: TS_KUBE_SECRET
|
|
value: tailscale-gitlab-state
|
|
- name: TS_USERSPACE
|
|
value: "false"
|
|
- name: TS_HOSTNAME
|
|
value: "foxhunt-gitlab"
|
|
- name: TS_ACCEPT_DNS
|
|
value: "false"
|
|
- name: TS_EXTRA_ARGS
|
|
value: ""
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 100m
|
|
memory: 64Mi
|
|
securityContext:
|
|
capabilities:
|
|
add:
|
|
- NET_ADMIN
|
|
- NET_RAW
|
|
volumes:
|
|
- name: nginx-conf
|
|
configMap:
|
|
name: tailscale-gitlab-nginx
|
|
- name: tls-certs
|
|
secret:
|
|
secretName: gitlab-tls-cert
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: tailscale-gitlab-nginx
|
|
namespace: foxhunt
|
|
data:
|
|
default.conf: |
|
|
# HTTP → HTTPS redirect for all subdomains
|
|
server {
|
|
listen 80;
|
|
server_name *.fxhnt.ai;
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
# GitLab — git.fxhnt.ai
|
|
server {
|
|
listen 443 ssl;
|
|
server_name git.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
proxy_pass http://gitlab-webservice-default.foxhunt.svc.cluster.local:8181;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
|
|
proxy_buffering off;
|
|
proxy_request_buffering off;
|
|
proxy_http_version 1.1;
|
|
proxy_read_timeout 3600s;
|
|
proxy_send_timeout 3600s;
|
|
proxy_connect_timeout 300s;
|
|
}
|
|
}
|
|
|
|
# Container Registry — git.fxhnt.ai:5050
|
|
server {
|
|
listen 5050 ssl;
|
|
server_name git.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
proxy_pass http://gitlab-registry.foxhunt.svc.cluster.local:5000;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
|
|
proxy_buffering off;
|
|
proxy_request_buffering off;
|
|
proxy_http_version 1.1;
|
|
proxy_read_timeout 3600s;
|
|
proxy_send_timeout 3600s;
|
|
}
|
|
}
|
|
|
|
# Grafana — grafana.fxhnt.ai
|
|
server {
|
|
listen 443 ssl;
|
|
server_name grafana.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
location / {
|
|
proxy_pass http://grafana.foxhunt.svc.cluster.local:80;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
}
|
|
}
|
|
|
|
# Web Dashboard — dashboard.fxhnt.ai
|
|
server {
|
|
listen 443 ssl;
|
|
server_name dashboard.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
location / {
|
|
proxy_pass http://web-dashboard.foxhunt.svc.cluster.local:80;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
}
|
|
}
|
|
|
|
# API Gateway (gRPC-Web + gRPC) — api.fxhnt.ai
|
|
# Browser dashboard uses gRPC-web (HTTP/1.1 POST), so proxy_pass not grpc_pass
|
|
server {
|
|
listen 443 ssl;
|
|
http2 on;
|
|
server_name api.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
location / {
|
|
proxy_pass http://api.foxhunt.svc.cluster.local:50051;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
proxy_http_version 1.1;
|
|
proxy_read_timeout 3600s;
|
|
proxy_send_timeout 3600s;
|
|
proxy_connect_timeout 30s;
|
|
}
|
|
}
|
|
|
|
# Stalwart Admin — mail.fxhnt.ai
|
|
server {
|
|
listen 443 ssl;
|
|
server_name mail.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
location / {
|
|
proxy_pass https://stalwart.foxhunt.svc.cluster.local:443;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
proxy_http_version 1.1;
|
|
proxy_ssl_verify off;
|
|
}
|
|
}
|
|
|
|
# Mattermost — chat.fxhnt.ai
|
|
server {
|
|
listen 443 ssl;
|
|
server_name chat.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
client_max_body_size 50m;
|
|
|
|
location / {
|
|
proxy_pass http://mattermost.foxhunt.svc.cluster.local:8065;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_read_timeout 3600s;
|
|
proxy_send_timeout 3600s;
|
|
}
|
|
}
|
|
|
|
# MinIO S3 API — minio.fxhnt.ai
|
|
server {
|
|
listen 443 ssl;
|
|
server_name minio.fxhnt.ai;
|
|
|
|
ssl_certificate /etc/nginx/certs/tls.crt;
|
|
ssl_certificate_key /etc/nginx/certs/tls.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
proxy_pass http://minio.foxhunt.svc.cluster.local:9000;
|
|
proxy_set_header Host $http_host;
|
|
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 https;
|
|
|
|
proxy_buffering off;
|
|
proxy_request_buffering off;
|
|
proxy_http_version 1.1;
|
|
proxy_read_timeout 3600s;
|
|
proxy_send_timeout 3600s;
|
|
proxy_connect_timeout 300s;
|
|
|
|
# MinIO uses self-signed TLS internally
|
|
proxy_ssl_verify off;
|
|
}
|
|
}
|
|
|