forked from hswaw/hscloud
Bartosz Stebel
4703e55b5c
also add manual db dumper job config Change-Id: Ifbd85c7452893c26ec1db416b20f2fd8610e1b19 Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1691 Reviewed-by: q3k <q3k@hackerspace.pl>
336 lines
13 KiB
Text
336 lines
13 KiB
Text
local kube = import "../../../kube/kube.libsonnet";
|
|
local postgres = import "../../../kube/postgres_v.libsonnet";
|
|
local redis = import "../../../kube/redis.libsonnet";
|
|
|
|
{
|
|
local app = self,
|
|
local cfg = app.cfg,
|
|
|
|
cfg:: {
|
|
namespace: error "cfg.namespace must be set",
|
|
# Domain as seen in the fediverse.
|
|
localDomain: error "cfg.localDomain must be set",
|
|
# Domain where the web interface is running. If different,
|
|
# localDomain's real server must be configured to forward
|
|
# /.well-known/webfinger to webDomain.
|
|
webDomain: cfg.localDomain,
|
|
images: {
|
|
mastodon: "tootsuite/mastodon:v4.1.9@sha256:525032827b5438c47670f44194e4adaed9f2c46f39c28cb37e9feb54b93b9ebf",
|
|
},
|
|
passwords: {
|
|
# generate however you like
|
|
postgres: error "cfg.secrets.postgres must be set",
|
|
# generate however you like
|
|
redis: error "cfg.secrets.redis must be set",
|
|
},
|
|
smtp: {
|
|
user: "mastodon",
|
|
from: "mastodon-noreply@hackerspace.pl",
|
|
# from mail server
|
|
password: error "cfg.smtp.password must be set",
|
|
},
|
|
secrets: {
|
|
# generate with podman run --rm -it tootsuite/mastodon:v4.0.2 bundle exec rake secret
|
|
keyBase: error "cfg.secrets.keyBase must be set",
|
|
# generate with podman run --rm -it tootsuite/mastodon:v4.0.2 bundle exec rake secret
|
|
otp: error "cfg.secrets.otp must be set",
|
|
# generate with podman run --rm -it tootsuite/mastodon:v4.0.2 bundle exec rake mastodon:webpush:generate_vapid_key
|
|
vapid: {
|
|
private: error "cfg.secrets.vapid.private must be set",
|
|
public: error "cfg.secrets.vapid.public must be set",
|
|
}
|
|
},
|
|
oidc: {
|
|
clientID: error "cfg.oidc.clientID must be set",
|
|
clientSecret: error "cfg.oidc.clientSecret must be set",
|
|
},
|
|
objectStorage: {
|
|
bucket: error "cfg.objectStorage.bucket must be set",
|
|
accessKeyId: error "cfg.objectStorage.accessKeyId must be set",
|
|
secretAccessKey: error "cfg.objectStorage.secretAccessKey must be set",
|
|
},
|
|
|
|
scaling: {
|
|
web: 1,
|
|
sidekiq: 1,
|
|
},
|
|
},
|
|
|
|
// Unified env var based config used for {web, streaming, sidekiq}.
|
|
// Sample available in https://github.com/mastodon/mastodon/blob/main/.env.production.sample
|
|
env:: {
|
|
LOCAL_DOMAIN: cfg.localDomain,
|
|
WEB_DOMAIN: cfg.webDomain,
|
|
|
|
// REDIS_PASS is not used directly by the apps, it's just used to embed
|
|
// a secret fragment into REDIS_URL.
|
|
REDIS_PASS: kube.SecretKeyRef(app.config, "redis-pass"),
|
|
REDIS_URL: "redis://:$(REDIS_PASS)@%s" % [app.redis.svc.host_colon_port],
|
|
|
|
DB_HOST: app.postgres.svc.host,
|
|
DB_USER: "mastodon",
|
|
DB_NAME: "mastodon",
|
|
DB_PASS: kube.SecretKeyRef(app.config, "postgres-pass"),
|
|
DB_PORT: "5432",
|
|
|
|
ES_ENABLED: "false",
|
|
|
|
SECRET_KEY_BASE: kube.SecretKeyRef(app.config, "secret-key-base"),
|
|
OTP_SECRET: kube.SecretKeyRef(app.config, "otp-secret"),
|
|
|
|
VAPID_PRIVATE_KEY: kube.SecretKeyRef(app.config, "vapid-private"),
|
|
VAPID_PUBLIC_KEY: kube.SecretKeyRef(app.config, "vapid-public"),
|
|
|
|
SMTP_SERVER: "mail.hackerspace.pl",
|
|
SMTP_PORT: "587",
|
|
SMTP_LOGIN: "mastodon",
|
|
SMTP_PASSWORD: kube.SecretKeyRef(app.config, "smtp-password"),
|
|
SMTP_FROM_ADDRESS: "mastodon-noreply@hackerspace.pl",
|
|
|
|
S3_ENABLED: "true",
|
|
S3_BUCKET: cfg.objectStorage.bucket,
|
|
AWS_ACCESS_KEY_ID: kube.SecretKeyRef(app.config, "object-access-key-id"),
|
|
AWS_SECRET_ACCESS_KEY: kube.SecretKeyRef(app.config, "object-secret-access-key"),
|
|
S3_HOSTNAME: "object.ceph-waw3.hswaw.net",
|
|
S3_ENDPOINT: "https://object.ceph-waw3.hswaw.net",
|
|
|
|
IP_RETENTION_PERIOD: "31556952",
|
|
SESSION_RETENTION_PERIOD: "31556952",
|
|
|
|
OIDC_ENABLED: "true",
|
|
OIDC_DISPLAY_NAME: "Use Warsaw Hackerspace SSO",
|
|
OIDC_ISSUER: "https://sso.hackerspace.pl",
|
|
OIDC_DISCOVERY: "false",
|
|
OIDC_SCOPE: "openid,profile:read",
|
|
OIDC_UID_FIELD: "uid",
|
|
OIDC_CLIENT_ID: cfg.oidc.clientId,
|
|
OIDC_REDIRECT_URI: "https://%s/auth/auth/openid_connect/callback" % [cfg.webDomain],
|
|
OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED: "true",
|
|
OIDC_CLIENT_SECRET: kube.SecretKeyRef(app.config, "oidc-client-secret"),
|
|
OIDC_AUTH_ENDPOINT: "https://sso.hackerspace.pl/oauth/authorize",
|
|
OIDC_TOKEN_ENDPOINT: "https://sso.hackerspace.pl/oauth/token",
|
|
OIDC_USER_INFO_ENDPOINT: "https://sso.hackerspace.pl/api/1/userinfo",
|
|
OIDC_JWKS_URI: "https://sso.hackerspace.pl/.well-known/jwks.json",
|
|
},
|
|
|
|
namespace: kube.Namespace(cfg.namespace),
|
|
local ns = self.namespace,
|
|
|
|
# there used to be a nonversioned postgres (10.4) here
|
|
# at time of writing it exists in prod, scaled down to 0, to preserve the PVC
|
|
postgres: postgres {
|
|
cfg+: {
|
|
version: "13.9",
|
|
namespace: cfg.namespace,
|
|
appName: "mastodon",
|
|
database: "mastodon",
|
|
username: "mastodon",
|
|
prefix: "waw3-",
|
|
password: kube.SecretKeyRef(app.config, "postgres-pass"),
|
|
storageClassName: "waw-hdd-redundant-3",
|
|
storageSize: "100Gi",
|
|
opts: { wal_level: "logical" },
|
|
},
|
|
},
|
|
|
|
redis: redis {
|
|
cfg+: {
|
|
namespace: cfg.namespace,
|
|
appName: "mastodon",
|
|
storageClassName: "waw-hdd-redundant-3",
|
|
prefix: "waw3-",
|
|
password: kube.SecretKeyRef(app.config, "redis-pass"),
|
|
},
|
|
},
|
|
|
|
web: ns.Contain(kube.Deployment("web")) {
|
|
spec+: {
|
|
minReadySeconds: 10,
|
|
replicas: cfg.scaling.web,
|
|
template+: {
|
|
spec+: {
|
|
initContainers_: {
|
|
migrate: kube.Container("migrate") {
|
|
image: cfg.images.mastodon,
|
|
env_: app.env {
|
|
//That's confusing one - all the random "how to mastodon in docker" tutorials
|
|
//say you need to set it. However, with this set, the web dashboard was sad
|
|
//about unfinished migrations.
|
|
//I can't obviously tell if we'd ever want this to be enabled though.
|
|
//Leaving it commented out here for now.
|
|
//SKIP_POST_DEPLOYMENT_MIGRATIONS: "true",
|
|
},
|
|
command: [
|
|
"bundle", "exec",
|
|
"rails", "db:migrate",
|
|
],
|
|
},
|
|
},
|
|
containers_: {
|
|
default: kube.Container("default") {
|
|
image: cfg.images.mastodon,
|
|
env_: app.env,
|
|
command: [
|
|
"bundle", "exec",
|
|
"rails", "s", "-p", "3000",
|
|
],
|
|
ports_: {
|
|
web: { containerPort: 3000 },
|
|
},
|
|
readinessProbe: {
|
|
httpGet: {
|
|
path: "/health",
|
|
port: "web",
|
|
},
|
|
failureThreshold: 10,
|
|
periodSeconds: 5,
|
|
},
|
|
resources: {
|
|
requests: {
|
|
cpu: "250m",
|
|
memory: "1024M",
|
|
},
|
|
limits: {
|
|
cpu: "1",
|
|
memory: "1024M",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
sidekiq: ns.Contain(kube.Deployment("sidekiq")) {
|
|
spec+: {
|
|
replicas: cfg.scaling.sidekiq,
|
|
minReadySeconds: 10,
|
|
template+: {
|
|
spec+: {
|
|
containers_: {
|
|
default: kube.Container("default") {
|
|
image: cfg.images.mastodon,
|
|
env_: app.env,
|
|
command: [
|
|
"bundle", "exec",
|
|
"sidekiq",
|
|
],
|
|
resources: {
|
|
requests: {
|
|
cpu: "250m",
|
|
memory: "1024M",
|
|
},
|
|
limits: {
|
|
cpu: "1",
|
|
memory: "1024M",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
streaming: ns.Contain(kube.Deployment("streaming")) {
|
|
spec+: {
|
|
minReadySeconds: 10,
|
|
template+: {
|
|
spec+: {
|
|
containers_: {
|
|
default: kube.Container("default") {
|
|
image: cfg.images.mastodon,
|
|
env_: app.env {
|
|
"STREAMING_CLUSTER_NUM": "1",
|
|
},
|
|
command: [
|
|
"node", "./streaming",
|
|
],
|
|
ports_: {
|
|
web: { containerPort: 4000 },
|
|
},
|
|
readinessProbe: {
|
|
httpGet: {
|
|
path: "/api/v1/streaming/health",
|
|
port: "web",
|
|
},
|
|
failureThreshold: 1,
|
|
periodSeconds: 5,
|
|
},
|
|
resources: {
|
|
requests: {
|
|
cpu: "250m",
|
|
memory: "1024M",
|
|
},
|
|
limits: {
|
|
cpu: "1",
|
|
memory: "1024M",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
svcWeb: ns.Contain(kube.Service("web")) {
|
|
target_pod: app.web.spec.template,
|
|
},
|
|
|
|
svcStreaming: ns.Contain(kube.Service("streaming")) {
|
|
target_pod: app.streaming.spec.template,
|
|
},
|
|
|
|
|
|
ingress: ns.Contain(kube.Ingress("mastodon")) {
|
|
// TODO(https://issues.hackerspace.pl/issues/74): mastodon's docs say we should enable CSP. Figure it out.
|
|
metadata+: {
|
|
annotations+: {
|
|
"kubernetes.io/tls-acme": "true",
|
|
"cert-manager.io/cluster-issuer": "letsencrypt-prod",
|
|
"nginx.ingress.kubernetes.io/proxy-body-size": "0",
|
|
},
|
|
},
|
|
spec+: {
|
|
tls: [
|
|
{
|
|
hosts: [cfg.webDomain],
|
|
secretName: "mastodon-ingress-tls",
|
|
},
|
|
],
|
|
rules: [
|
|
{
|
|
host: cfg.webDomain,
|
|
http: {
|
|
paths: [
|
|
{ path: "/", backend: app.svcWeb.name_port },
|
|
{ path: "/api/v1/streaming", backend: app.svcStreaming.name_port },
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
|
|
config: ns.Contain(kube.Secret("config")) {
|
|
data_: {
|
|
"postgres-pass": cfg.passwords.postgres,
|
|
"redis-pass": cfg.passwords.redis,
|
|
|
|
"secret-key-base": cfg.secrets.keyBase,
|
|
"otp-secret": cfg.secrets.otp,
|
|
|
|
"vapid-private": cfg.secrets.vapid.private,
|
|
"vapid-public": cfg.secrets.vapid.public,
|
|
|
|
"smtp-password": cfg.smtp.password,
|
|
|
|
"object-access-key-id": cfg.objectStorage.accessKeyId,
|
|
"object-secret-access-key": cfg.objectStorage.secretAccessKey,
|
|
|
|
"oidc-client-secret": cfg.oidc.clientSecret,
|
|
},
|
|
},
|
|
}
|