diff --git a/docker/Dockerfile b/docker/Dockerfile index 9fe3d6b75..831627ec8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -62,7 +62,7 @@ RUN set -eux; \ # Usuários/grupos (idempotente) RUN useradd --system --no-create-home --shell /usr/sbin/nologin sapl || true \ - && groupadd -r nginx || true \ + && groupadd -g 101 -r nginx || true \ && usermod -aG nginx www-data || true \ && usermod -aG nginx sapl || true diff --git a/docker/k8s/sapl-deploy.sh b/docker/k8s/sapl-deploy.sh new file mode 100755 index 000000000..0133704b8 --- /dev/null +++ b/docker/k8s/sapl-deploy.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +kubectl create namespace sapl +mkdir -p ./sapl-secret-data +kubectl -n sapl create secret generic sapl-secretkey --from-file=./sapl-secret-data/ +kubectl apply -f sapl-k8s.yaml + +kubectl rollout status deployment/sapl -n sapl + +POD=$(kubectl get pod -n sapl -l app=sapl -o jsonpath='{.items[0].metadata.name}') +kubectl exec -n sapl "$POD" -- ls -l /var/interlegis/sapl/data + diff --git a/docker/k8s/sapl-k8s.yaml b/docker/k8s/sapl-k8s.yaml new file mode 100644 index 000000000..8a45e015e --- /dev/null +++ b/docker/k8s/sapl-k8s.yaml @@ -0,0 +1,218 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: sapl +--- +apiVersion: v1 +kind: Service +metadata: + name: sapldb + namespace: sapl +spec: + selector: + app: sapldb + ports: + - name: postgres + port: 5432 + targetPort: 5432 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: sapldb-data + namespace: sapl +spec: + accessModes: ["ReadWriteOnce"] + storageClassName: local-path + resources: + requests: + storage: 5Gi # or 1Gi for solr-configsets +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: sapldb + namespace: sapl +spec: + serviceName: sapldb + replicas: 1 + selector: + matchLabels: + app: sapldb + template: + metadata: + labels: + app: sapldb + spec: + containers: + - name: postgres + image: postgres:10.5-alpine + env: + - name: POSTGRES_PASSWORD + value: "sapl" + - name: POSTGRES_USER + value: "sapl" + - name: POSTGRES_DB + value: "sapl" + - name: PGDATA + value: /var/lib/postgresql/data/ + - name: TZ + value: UTC + - name: PG_TZ + value: UTC + ports: + - containerPort: 5432 + volumeMounts: + - name: sapldb-data + mountPath: /var/lib/postgresql/data/ + volumes: + - name: sapldb-data + persistentVolumeClaim: + claimName: sapldb-data +--- +apiVersion: v1 +kind: Service +metadata: + name: saplsolr + namespace: sapl +spec: + selector: + app: saplsolr + ports: + - name: solr + port: 8983 + targetPort: 8983 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: solr-data + namespace: sapl +spec: + accessModes: ["ReadWriteOnce"] + storageClassName: local-path + resources: + requests: + storage: 5Gi # or 1Gi for solr-configsets +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: solr-configsets + namespace: sapl +spec: + accessModes: ["ReadWriteOnce"] + storageClassName: local-path + resources: + requests: + storage: 5Gi # or 1Gi for solr-configsets +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: saplsolr + namespace: sapl +spec: + serviceName: saplsolr + replicas: 1 + selector: + matchLabels: + app: saplsolr + template: + metadata: + labels: + app: saplsolr + spec: + containers: + - name: solr + image: solr:8.11 + command: ["bash","-lc","bin/solr start -c -f"] + ports: + - containerPort: 8983 + volumeMounts: + - name: solr-data + mountPath: /var/solr + - name: solr-configsets + mountPath: /opt/solr/server/solr/configsets + volumes: + - name: solr-data + persistentVolumeClaim: + claimName: solr-data + - name: solr-configsets + persistentVolumeClaim: + claimName: solr-configsets +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: sapl-media + namespace: sapl +spec: + accessModes: ["ReadWriteOnce"] + storageClassName: local-path + resources: + requests: + storage: 5Gi # or 1Gi for solr-configsets +--- +apiVersion: v1 +kind: Service +metadata: + name: sapl + namespace: sapl +spec: + selector: + app: sapl + type: NodePort + ports: + - name: http + port: 80 + targetPort: 80 + nodePort: 30080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sapl + namespace: sapl +spec: + replicas: 1 + selector: + matchLabels: + app: sapl + template: + metadata: + labels: + app: sapl + spec: + containers: + - name: sapl + image: eribeiro/sapl:debug-k8s-1 + ports: + - containerPort: 80 + volumeMounts: + - name: data + mountPath: /var/interlegis/sapl/data + readOnly: true # secrets are always mounted read-only + volumes: + - name: data + secret: + secretName: sapl-secretkey + defaultMode: 0440 # ensures read-only + env: + - name: ADMIN_PASSWORD + value: "interlegis" + - name: ADMIN_EMAIL + value: "email@dominio.net" + - name: DEBUG + value: "False" + - name: EMAIL_PORT + value: "587" + - name: EMAIL_USE_TLS + value: "False" + - name: EMAIL_HOST + value: "smtp.dominio.net" + - name: EMAIL_HOST_USER + value: "usuariosmtp" + - name: EMAIL_SEND_USER + + diff --git a/docker/startup_scripts/start.sh b/docker/startup_scripts/start.sh index b612532bc..316d73f8a 100755 --- a/docker/startup_scripts/start.sh +++ b/docker/startup_scripts/start.sh @@ -2,12 +2,21 @@ set -Eeuo pipefail IFS=$'\n\t' +APP_DIR="/var/interlegis/sapl" DATA_DIR="/var/interlegis/sapl/data" -APP_DIR="/var/interlegis/sapl/sapl" +MEDIA_DIR="/var/interlegis/sapl/media" +RUN_DIR="/var/interlegis/sapl/run" + ENV_FILE="$APP_DIR/.env" SECRET_FILE="$DATA_DIR/secret.key" -mkdir -p "$DATA_DIR" "$APP_DIR" +chown -R root:nginx "$RUN_DIR" || true +chown -R root:nginx "$MEDIA_DIR" || true +chmod -R g+rwX "$RUN_DIR" || true +chmod -R g+rwX "$MEDIA_DIR" || true + +# setgid bit on our writable trees (not data/) +find "$RUN_DIR" "$MEDIA_DIR" -type d -exec chmod g+s {} + 2>/dev/null || true log() { printf '[%s] %s\n' "$(date -Is)" "$*"; } err() { printf '[%s] ERROR: %s\n' "$(date -Is)" "$*" >&2; } @@ -76,7 +85,6 @@ create_secret() { SECRET_KEY="$(python3 genkey.py)" umask 177 printf '%s\n' "$SECRET_KEY" > "$SECRET_FILE" - chmod 600 "$SECRET_FILE" fi export SECRET_KEY } @@ -225,9 +233,7 @@ fix_logging_and_socket_perms() { # dirs mkdir -p "$APP_DIR/run" - chown -R root:nginx "$APP_DIR" - chmod 2775 "$APP_DIR" "$APP_DIR/run" - chmod -R g+rwX "$APP_DIR" + chmod 2775 "$APP_DIR/run" # new files/sockets → 660 umask 0007