diff --git a/bin/Tiltfile b/bin/Tiltfile index 4cbaa10c..2671e25a 100644 --- a/bin/Tiltfile +++ b/bin/Tiltfile @@ -85,6 +85,13 @@ clean_old_images('localhost:5001/meet-livekit') k8s_yaml(local('cd ../src/helm && helmfile -n meet -e ${DEV_ENV:-dev} template .')) +k8s_resource('minio-bucket', resource_deps=['minio']) +k8s_resource('meet-backend', resource_deps=['postgresql', 'minio', 'redis', 'livekit-livekit-server']) +k8s_resource('meet-backend-migrate', resource_deps=['meet-backend']) +k8s_resource('livekit-livekit-server-test-connection', resource_deps=['livekit-livekit-server']) +k8s_resource('keycloak', resource_deps=['kc-postgresql']) +k8s_resource('meet-backend-createsuperuser', resource_deps=['meet-backend-migrate']) + migration = ''' set -eu # get k8s pod name from tilt resource name diff --git a/src/helm/env.d/dev-dinum/values.meet.yaml.gotmpl b/src/helm/env.d/dev-dinum/values.meet.yaml.gotmpl index 0cfce6fc..35a12356 100644 --- a/src/helm/env.d/dev-dinum/values.meet.yaml.gotmpl +++ b/src/helm/env.d/dev-dinum/values.meet.yaml.gotmpl @@ -35,7 +35,7 @@ backend: LOGIN_REDIRECT_URL: https://meet.127.0.0.1.nip.io LOGIN_REDIRECT_URL_FAILURE: https://meet.127.0.0.1.nip.io LOGOUT_REDIRECT_URL: https://meet.127.0.0.1.nip.io - DB_HOST: postgres-postgresql + DB_HOST: postgres DB_NAME: meet DB_USER: dinum DB_PASSWORD: pass @@ -78,8 +78,11 @@ backend: - "/bin/sh" - "-c" - | - python manage.py migrate --no-input && - python manage.py create_demo --force + if ! python manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); import sys; sys.exit(0 if User.objects.filter(admin_email='user0@example.com').exists() else 1)" + then + python manage.py migrate --no-input && + python manage.py create_demo --force || echo "create_demo already run" + fi restartPolicy: Never command: diff --git a/src/helm/env.d/dev-keycloak/values.meet.yaml.gotmpl b/src/helm/env.d/dev-keycloak/values.meet.yaml.gotmpl index d27204ed..d97035fd 100644 --- a/src/helm/env.d/dev-keycloak/values.meet.yaml.gotmpl +++ b/src/helm/env.d/dev-keycloak/values.meet.yaml.gotmpl @@ -35,7 +35,7 @@ backend: LOGIN_REDIRECT_URL: https://meet.127.0.0.1.nip.io LOGIN_REDIRECT_URL_FAILURE: https://meet.127.0.0.1.nip.io LOGOUT_REDIRECT_URL: https://meet.127.0.0.1.nip.io - DB_HOST: postgres-postgresql + DB_HOST: postgres DB_NAME: meet DB_USER: dinum DB_PASSWORD: pass @@ -79,15 +79,11 @@ backend: - "/bin/sh" - "-c" - | - while ! python manage.py check --database default > /dev/null 2>&1 - do - echo "Database not ready" - sleep 2 - done - echo "Database is ready" - - python manage.py migrate --no-input && - python manage.py create_demo --force + if ! python manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); import sys; sys.exit(0 if User.objects.filter(admin_email='user0@example.com').exists() else 1)" + then + python manage.py migrate --no-input && + python manage.py create_demo --force || echo "create_demo already run" + fi restartPolicy: Never command: @@ -102,13 +98,6 @@ backend: - "/bin/sh" - "-c" - | - while ! python manage.py check --database default > /dev/null 2>&1 - do - echo "Database not ready" - sleep 2 - done - echo "Database is ready" - python manage.py createsuperuser --email admin@example.com --password admin restartPolicy: Never diff --git a/src/helm/env.d/dev/values.meet.yaml.gotmpl b/src/helm/env.d/dev/values.meet.yaml.gotmpl index f9461b50..dee50413 100644 --- a/src/helm/env.d/dev/values.meet.yaml.gotmpl +++ b/src/helm/env.d/dev/values.meet.yaml.gotmpl @@ -57,7 +57,7 @@ backend: LOGIN_REDIRECT_URL: https://meet.127.0.0.1.nip.io LOGIN_REDIRECT_URL_FAILURE: https://meet.127.0.0.1.nip.io LOGOUT_REDIRECT_URL: https://meet.127.0.0.1.nip.io - DB_HOST: postgres-postgresql + DB_HOST: postgres DB_NAME: meet DB_USER: dinum DB_PASSWORD: pass @@ -100,15 +100,11 @@ backend: - "/bin/sh" - "-c" - | - while ! python manage.py check --database default > /dev/null 2>&1 - do - echo "Database not ready" - sleep 2 - done - echo "Database is ready" - - python manage.py migrate --no-input && - python manage.py create_demo --force + if ! python manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); import sys; sys.exit(0 if User.objects.filter(admin_email='user0@example.com').exists() else 1)" + then + python manage.py migrate --no-input && + python manage.py create_demo --force || echo "create_demo already run" + fi restartPolicy: Never command: @@ -123,13 +119,6 @@ backend: - "/bin/sh" - "-c" - | - while ! python manage.py check --database default > /dev/null 2>&1 - do - echo "Database not ready" - sleep 2 - done - echo "Database is ready" - python manage.py createsuperuser --email admin@example.com --password admin restartPolicy: Never diff --git a/src/helm/extra/templates/kc-postgresql-sts.yaml b/src/helm/extra/templates/kc-postgresql-sts.yaml new file mode 100644 index 00000000..07e7f742 --- /dev/null +++ b/src/helm/extra/templates/kc-postgresql-sts.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: kc-postgres + namespace: {{ .Release.Namespace | quote }} +spec: + ports: + - name: tcp-postgresql + port: 5432 + protocol: TCP + targetPort: tcp-postgresql + selector: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: kc-postgresql + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: kc-postgresql + namespace: {{ .Release.Namespace | quote }} +spec: + selector: + matchLabels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: kc-postgresql + serviceName: "kc-postgres" + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: kc-postgresql + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: pg + image: postgres:16-alpine + ports: + - containerPort: 5432 + name: tcp-postgresql + env: + - name: POSTGRES_PASSWORD + value: pass + - name: POSTGRES_USER + value: dinum + - name: POSTGRES_DB + value: keycloak + volumeMounts: + - name: data + mountPath: /var/lib/postgresql + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi + diff --git a/src/helm/extra/templates/keycloak-sts.yaml b/src/helm/extra/templates/keycloak-sts.yaml new file mode 100644 index 00000000..32188f45 --- /dev/null +++ b/src/helm/extra/templates/keycloak-sts.yaml @@ -0,0 +1,104 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: keycloak +spec: + rules: + - host: "keycloak.127.0.0.1.nip.io" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: keycloak + port: + number: 8080 + tls: + - hosts: + - keycloak.127.0.0.1.nip.io + secretName: meet-tls +--- +apiVersion: v1 +kind: Service +metadata: + name: keycloak + namespace: {{ .Release.Namespace | quote }} +spec: + ports: + - name: tcp-keycloak + port: 8080 + protocol: TCP + targetPort: tcp-keycloak + selector: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: keycloak + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: realm +data: + meet.json: | +{{ .Values.realm | indent 4 }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: keycloak + namespace: {{ .Release.Namespace | quote }} +spec: + selector: + matchLabels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: keycloak + serviceName: "keycloak" + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: keycloak + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: keycloak + image: quay.io/keycloak/keycloak:20.0.1 + args: + - start-dev + - --features=preview + - --import-realm + - --proxy=edge + - --hostname=keycloak.127.0.0.1.nip.io + - --hostname-strict=false + - --hostname-strict-https=false + ports: + - containerPort: 8080 + name: tcp-keycloak + env: + - name: KEYCLOAK_ADMIN + value: admin + - name: KEYCLOAK_ADMIN_PASSWORD + value: admin + - name: PROXY_ADDRESS_FORWARDING + value: 'true' + - name: KC_DB_URL_HOST + value: kc_postgresql + - name: KC_DB_URL_DATABASE + value: keycloak + - name: KC_DB_PASSWORD + value: pass + - name: KC_DB_USERNAME + value: dinum + - name: KC_DB_SCHEMA + value: public + volumeMounts: + - name: realm + mountPath: "/opt/keycloak/data/import" + readOnly: true + volumes: + - name: realm + configMap: + name: realm diff --git a/src/helm/extra/templates/minio.yaml b/src/helm/extra/templates/minio.yaml new file mode 100644 index 00000000..8729567b --- /dev/null +++ b/src/helm/extra/templates/minio.yaml @@ -0,0 +1,107 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: minio +spec: + rules: + - host: "minio.127.0.0.1.nip.io" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: minio + port: + number: 9001 + tls: + - hosts: + - minio.127.0.0.1.nip.io + secretName: meet-tls +--- +apiVersion: v1 +kind: Service +metadata: + name: minio + namespace: {{ .Release.Namespace | quote }} +spec: + ports: + - name: client + port: 9000 + protocol: TCP + targetPort: 9000 + - name: console + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: minio + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: minio + namespace: {{ .Release.Namespace | quote }} + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: minio +spec: + selector: + matchLabels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: minio + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: minio + spec: + containers: + - name: minio + command: + - /bin/sh + - -c + - | + minio server --console-address :9001 /data + env: + - name: MINIO_ROOT_USER + value: meet + - name: MINIO_ROOT_PASSWORD + value: password + image: "minio/minio" + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9000 + name: client + - containerPort: 9001 + name: console + volumeMounts: + - mountPath: /data + name: data + volumes: + - name: data + emptyDir: +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: minio-bucket +spec: + template: + spec: + containers: + - name: mc + image: minio/mc + command: + - /bin/sh + - -c + - | + /usr/bin/mc alias set meet http://minio:9000 meet password && \ + /usr/bin/mc mb meet/meet-media-storage && \ + exit 0 + restartPolicy: Never + backoffLimit: 1 diff --git a/src/helm/extra/templates/postgresql-sts.yaml b/src/helm/extra/templates/postgresql-sts.yaml new file mode 100644 index 00000000..c7e4e307 --- /dev/null +++ b/src/helm/extra/templates/postgresql-sts.yaml @@ -0,0 +1,70 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: {{ .Release.Namespace | quote }} +spec: + ports: + - name: tcp-postgresql + port: 5432 + protocol: TCP + targetPort: tcp-postgresql + selector: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: postgresql + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgresql + namespace: {{ .Release.Namespace | quote }} +spec: + selector: + matchLabels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: postgresql + serviceName: "postgres" + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: postgresql + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: pg + image: postgres:16-alpine + readinessProbe: + exec: + command: [ "pg_isready", "-U", "dinum", "-d", "meet", "-h", "127.0.0.1" ] + initialDelaySeconds: 5 + periodSeconds: 5 + livenessProbe: + exec: + command: [ "pg_isready", "-U", "dinum", "-d", "meet", "-h", "127.0.0.1" ] + initialDelaySeconds: 15 + periodSeconds: 10 + ports: + - containerPort: 5432 + name: tcp-postgresql + env: + - name: POSTGRES_PASSWORD + value: pass + - name: POSTGRES_USER + value: dinum + - name: POSTGRES_DB + value: meet + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi diff --git a/src/helm/extra/templates/redis.yaml b/src/helm/extra/templates/redis.yaml new file mode 100644 index 00000000..fd99f823 --- /dev/null +++ b/src/helm/extra/templates/redis.yaml @@ -0,0 +1,65 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-master + namespace: {{ .Release.Namespace | quote }} +spec: + ports: + - name: tcp-redis + port: 6379 + protocol: TCP + targetPort: tcp-redis + selector: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: redis + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: redis +data: + redis.conf: | + bind 0.0.0.0 + port 6379 + user default on >pass ~* &* +@all +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: {{ .Release.Namespace | quote }} + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: redis +spec: + selector: + matchLabels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: redis + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: extra + app.kubernetes.io/name: redis + spec: + containers: + - name: redis + args: + - redis-server + - /usr/local/etc/redis/redis.conf + image: "redis:8.2-alpine" + imagePullPolicy: IfNotPresent + ports: + - containerPort: 6379 + name: tcp-redis + volumeMounts: + - name: redis + mountPath: "/usr/local/etc/redis" + readOnly: true + volumes: + - name: redis + configMap: + name: redis diff --git a/src/helm/helmfile.yaml b/src/helm/helmfile.yaml index 0b6cefdd..707d1bb1 100644 --- a/src/helm/helmfile.yaml +++ b/src/helm/helmfile.yaml @@ -13,109 +13,10 @@ environments: - env.d/{{ .Environment.Name }}/values.secrets.yaml repositories: -- name: bitnami - url: registry-1.docker.io/bitnamicharts - oci: true - name: livekit url: https://helm.livekit.io releases: - - name: postgres - installed: {{ regexMatch "^dev.*" .Environment.Name | toYaml }} - missingFileHandler: Warn - namespace: {{ .Namespace }} - chart: bitnami/postgresql - version: 13.1.5 - values: - - auth: - username: dinum - password: pass - database: meet - - tls: - enabled: true - autoGenerated: true - - - name: keycloak - installed: {{ or (eq .Environment.Name "dev-keycloak") (eq .Environment.Name "dev-dinum") | toYaml }} - missingFileHandler: Warn - namespace: {{ .Namespace }} - chart: bitnami/keycloak - version: 17.3.6 - values: - - postgresql: - auth: - username: keycloak - password: keycloak - database: keycloak - - extraEnvVars: - - name: KEYCLOAK_EXTRA_ARGS - value: "--import-realm" - - name: KC_HOSTNAME_URL - value: https://keycloak.127.0.0.1.nip.io - - extraVolumes: - - name: import - configMap: - name: meet-keycloak - - extraVolumeMounts: - - name: import - mountPath: /opt/bitnami/keycloak/data/import/ - - auth: - adminUser: su - adminPassword: su - - proxy: edge - - ingress: - enabled: true - hostname: keycloak.127.0.0.1.nip.io - - extraDeploy: - - apiVersion: v1 - kind: ConfigMap - metadata: - name: meet-keycloak - data: - meet.json: | -{{ readFile "../../docker/auth/realm.json" | replace "http://localhost:3200" "https://meet.127.0.0.1.nip.io" | indent 14 }} - - - name: minio - installed: {{ regexMatch "^dev.*" .Environment.Name | toYaml }} - namespace: {{ .Namespace }} - missingFileHandler: Warn - chart: bitnami/minio - version: 12.10.10 - values: - - auth: - rootUser: meet - rootPassword: password - - provisioning: - enabled: true - buckets: - - name: meet-media-storage - versioning: true - - ingress: - enabled: true - hostname: minio-console.127.0.0.1.nip.io - servicePort: 9001 - annotations: - nginx.ingress.kubernetes.io/proxy-body-size: "0" - kubernetes.io/ingress.class: nginx - extraVolumes: - - name: mkcert - secret: - secretName: mkcert - extraVolumeMounts: - - mountPath: /certs/CAs/ - name: mkcert - - - name: redis - installed: {{ regexMatch "^dev.*" .Environment.Name | toYaml }} - missingFileHandler: Warn - namespace: {{ .Namespace }} - chart: bitnami/redis - version: 18.19.2 - values: - - auth: - password: pass - architecture: standalone - - name: extra installed: {{ regexMatch "^dev.*" .Environment.Name | toYaml }} missingFileHandler: Warn @@ -129,6 +30,8 @@ releases: enablePermanentRedirect: {{ .Values | get "enablePermanentRedirect" "False"}} oldDomain: {{ .Values | get "oldDomain" "demo.com" }} newDomain: {{ .Values | get "newDomain" "demo.com" }} + - realm: | +{{ readFile "../../docker/auth/realm.json" | replace "http://localhost:3200" "https://meet.127.0.0.1.nip.io" | indent 8 }} - name: meet version: {{ .Values.version }}