From 9be0ba48f88fcb7be214328918c2b2c8424da2f0 Mon Sep 17 00:00:00 2001 From: AlexBelyan Date: Sat, 23 May 2026 13:07:49 +0300 Subject: [PATCH] added k8s manifests, removed webhook server --- .gitea/workflows/deploy.yaml | 26 +--- .gitignore | 4 +- infra/{ => docker}/docker-compose.yml | 17 --- infra/k8s/app.yaml | 62 ++++++++ infra/k8s/configmap.yaml | 14 ++ infra/k8s/ingress.yaml | 19 +++ infra/k8s/namespace.yaml | 4 + infra/k8s/postgres.yaml | 62 ++++++++ .../postgres-pg-cron => postgres}/Dockerfile | 0 .../init/001-create-pg-cron-extension.sql | 0 infra/webhook/Dockerfile | 12 -- infra/webhook/go.mod | 3 - infra/webhook/go.sum | 0 infra/webhook/main.go | 134 ------------------ 14 files changed, 171 insertions(+), 186 deletions(-) rename infra/{ => docker}/docker-compose.yml (73%) create mode 100644 infra/k8s/app.yaml create mode 100644 infra/k8s/configmap.yaml create mode 100644 infra/k8s/ingress.yaml create mode 100644 infra/k8s/namespace.yaml create mode 100644 infra/k8s/postgres.yaml rename infra/{docker/postgres-pg-cron => postgres}/Dockerfile (100%) rename infra/{docker/postgres-pg-cron => postgres}/init/001-create-pg-cron-extension.sql (100%) delete mode 100644 infra/webhook/Dockerfile delete mode 100644 infra/webhook/go.mod delete mode 100644 infra/webhook/go.sum delete mode 100644 infra/webhook/main.go diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 695635a..e69a443 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -25,30 +25,18 @@ jobs: - name: Build and push postgres image uses: docker/build-push-action@v5 -# if: | -# contains(github.event.commits[0].modified, 'infra/docker/postgres-pg-cron') || -# contains(github.event.commits[0].added, 'infra/docker/postgres-pg-cron') + if: | + contains(github.event.commits[0].modified, 'infra/postgres-pg-cron') || + contains(github.event.commits[0].added, 'infra/postgres-pg-cron') with: context: . - file: infra/docker/postgres-pg-cron/Dockerfile + file: infra/postgres/Dockerfile push: true tags: | ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub-postgres:latest - ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub:${{ github.sha }} - cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub:cache - cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub:cache,mode=max - -# - name: Build and push webhook image -# uses: docker/build-push-action@v5 -# with: -# context: . -# file: infra/webhook/Dockerfile -# push: true -# tags: | -# ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub-webhook:latest -# ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub:${{ github.sha }} -# cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub:cache -# cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub:cache,mode=max + ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub-postgres:${{ github.sha }} + cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub-postgres:cache + cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/familyhub-postgres:cache,mode=max - name: Build and push app image uses: docker/build-push-action@v5 diff --git a/.gitignore b/.gitignore index f4f75a7..2904e9f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ data archive volumes *.dtmp -*.gocache \ No newline at end of file +*.gocache +infra/k8s/secrets.yaml +infra/k8s/google-creds.yaml \ No newline at end of file diff --git a/infra/docker-compose.yml b/infra/docker/docker-compose.yml similarity index 73% rename from infra/docker-compose.yml rename to infra/docker/docker-compose.yml index 57c030d..8a564eb 100644 --- a/infra/docker-compose.yml +++ b/infra/docker/docker-compose.yml @@ -48,23 +48,6 @@ services: networks: - family-hub-net - webhook: - image: git.myhomecloud.tech/admin/familyhub-webhook:latest - container_name: webhook - restart: unless-stopped - pull_policy: always - ports: - - "9001:9001" - environment: - - WEBHOOK_SECRET=${WEBHOOK_SECRET} - # - COMPOSE_FILE=/compose/docker-compose.yml - - COMPOSE_PROJECT=familyhub - volumes: - - /var/run/docker.sock:/var/run/docker.sock - # - ./docker-compose.yml:/compose/docker-compose.yml:ro - networks: - - family-hub-net - networks: family-hub-net: diff --git a/infra/k8s/app.yaml b/infra/k8s/app.yaml new file mode 100644 index 0000000..0679988 --- /dev/null +++ b/infra/k8s/app.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: application + namespace: family-hub +spec: + replicas: 1 + selector: + matchLabels: + app: family-hub + template: + metadata: + labels: + app: application + spec: + containers: + - name: application + image: git.myhomecloud.tech/admin/familyhub:latest + ports: + - containerPort: 8000 + envFrom: + - configMapRef: + name: family-hub-config + - secretRef: + name: family-hub-secrets + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /secrets/credentials.json + volumeMounts: + - name: google-credentials + mountPath: /secrets + readOnly: true +# livenessProbe: +# httpGet: +# path: /api/v1/health +# port: 8000 +# initialDelaySeconds: 10 +# periodSeconds: 30 +# readinessProbe: +# httpGet: +# path: /api/v1/health +# port: 8000 +# initialDelaySeconds: 5 +# periodSeconds: 10 + volumes: + - name: google-credentials + secret: + secretName: google-credentials + imagePullSecrets: + - name: gitea-registry +--- +apiVersion: v1 +kind: Service +metadata: + name: application + namespace: family-hub +spec: + selector: + app: application + ports: + - port: 9876 + targetPort: 8000 \ No newline at end of file diff --git a/infra/k8s/configmap.yaml b/infra/k8s/configmap.yaml new file mode 100644 index 0000000..38f4233 --- /dev/null +++ b/infra/k8s/configmap.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: family-hub-config + namespace: family-hub +data: + DB_HOST: postgres + DB_PORT: "6432" + DB_NAME: familyHubDB + DB_USER: familyUser + API_PORT: "8000" + RUN_MODE: standalone + OPEN_API_ENABLED: true + DEBUG_MODE: false \ No newline at end of file diff --git a/infra/k8s/ingress.yaml b/infra/k8s/ingress.yaml new file mode 100644 index 0000000..c8fe17a --- /dev/null +++ b/infra/k8s/ingress.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: family-hub + namespace: family-hub + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web +spec: + rules: + - host: family-hub.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: family-hub + port: + number: 9876 \ No newline at end of file diff --git a/infra/k8s/namespace.yaml b/infra/k8s/namespace.yaml new file mode 100644 index 0000000..fc85d73 --- /dev/null +++ b/infra/k8s/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: family-hub \ No newline at end of file diff --git a/infra/k8s/postgres.yaml b/infra/k8s/postgres.yaml new file mode 100644 index 0000000..b6e9313 --- /dev/null +++ b/infra/k8s/postgres.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres + namespace: family-hub +spec: + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: git.myhomecloud.tech/admin/familyhub-postgres:latest + env: + - name: POSTGRES_USER + value: familyUser + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: family-hub-secrets + key: DB_PASSWORD + - name: POSTGRES_DB + value: familyHubDB + ports: + - containerPort: 5432 + volumeMounts: + - name: postgres-data + mountPath: /var/lib/postgresql/data + imagePullSecrets: + - name: gitea-registry + volumes: + - name: postgres-data + persistentVolumeClaim: + claimName: postgres-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: family-hub +spec: + selector: + app: postgres + ports: + - port: 5432 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pvc + namespace: family-hub +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi \ No newline at end of file diff --git a/infra/docker/postgres-pg-cron/Dockerfile b/infra/postgres/Dockerfile similarity index 100% rename from infra/docker/postgres-pg-cron/Dockerfile rename to infra/postgres/Dockerfile diff --git a/infra/docker/postgres-pg-cron/init/001-create-pg-cron-extension.sql b/infra/postgres/init/001-create-pg-cron-extension.sql similarity index 100% rename from infra/docker/postgres-pg-cron/init/001-create-pg-cron-extension.sql rename to infra/postgres/init/001-create-pg-cron-extension.sql diff --git a/infra/webhook/Dockerfile b/infra/webhook/Dockerfile deleted file mode 100644 index dbcc560..0000000 --- a/infra/webhook/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM golang:1.26-bookworm AS builder - -WORKDIR /app -COPY infra/webhook/ . -RUN go mod download && \ - CGO_ENABLED=0 GOOS=linux go build -o webhook . - -FROM scratch -COPY --from=builder /app/webhook /webhook -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -EXPOSE 9001 -ENTRYPOINT ["/webhook"] \ No newline at end of file diff --git a/infra/webhook/go.mod b/infra/webhook/go.mod deleted file mode 100644 index e4ca30e..0000000 --- a/infra/webhook/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module webhook - -go 1.25.0 diff --git a/infra/webhook/go.sum b/infra/webhook/go.sum deleted file mode 100644 index e69de29..0000000 diff --git a/infra/webhook/main.go b/infra/webhook/main.go deleted file mode 100644 index 4734ddb..0000000 --- a/infra/webhook/main.go +++ /dev/null @@ -1,134 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "fmt" - "io" - "log" - "net" - "net/http" - "net/url" - "os" -) - -func newDockerClient() *http.Client { - return &http.Client{ - Transport: &http.Transport{ - DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", "/var/run/docker.sock") - }, - }, - } -} - -func getImageName(containerName string) (string, error) { - client := newDockerClient() - resp, err := client.Get("http://localhost/containers/" + containerName + "/json") - if err != nil { - return "", err - } - defer resp.Body.Close() - - var result struct { - Config struct { - Image string `json:"Image"` - } `json:"Config"` - } - if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { - return "", err - } - return result.Config.Image, nil -} - -func pullImage(imageName string) error { - client := newDockerClient() - resp, err := client.Post( - "http://localhost/images/create?fromImage="+url.QueryEscape(imageName), - "application/json", - nil, - ) - if err != nil { - return err - } - defer resp.Body.Close() - // читаем до конца чтобы pull завершился полностью - io.Copy(io.Discard, resp.Body) - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("pull failed with status: %d", resp.StatusCode) - } - return nil -} - -func restartContainer(containerName string) error { - client := newDockerClient() - resp, err := client.Post( - "http://localhost/containers/"+containerName+"/restart", - "application/json", - nil, - ) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusNoContent { - return fmt.Errorf("restart failed with status: %d", resp.StatusCode) - } - return nil -} - -func main() { - secret := os.Getenv("WEBHOOK_SECRET") - - http.HandleFunc("/deploy", func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - http.Error(w, "method not allowed", http.StatusMethodNotAllowed) - return - } - if r.Header.Get("X-Webhook-Secret") != secret { - http.Error(w, "unauthorized", http.StatusUnauthorized) - return - } - - containerName := r.URL.Query().Get("container") - if containerName == "" { - http.Error(w, "container parameter is required", http.StatusBadRequest) - return - } - - imageName, err := getImageName(containerName) - if err != nil { - log.Printf("failed to inspect container %s: %v", containerName, err) - http.Error(w, "container not found", http.StatusNotFound) - return - } - log.Printf("Container: %s, Image: %s", containerName, imageName) - - log.Printf("Pulling image %s...", imageName) - if err := pullImage(imageName); err != nil { - log.Printf("pull failed: %v", err) - http.Error(w, "pull failed", http.StatusInternalServerError) - return - } - - log.Printf("Restarting container %s...", containerName) - if err := restartContainer(containerName); err != nil { - log.Printf("restart failed: %v", err) - http.Error(w, "restart failed", http.StatusInternalServerError) - return - } - - log.Printf("Deploy of %s completed", containerName) - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]string{ - "status": "ok", - "container": containerName, - "image": imageName, - }) - }) - - log.Println("Webhook server listening on :9001") - log.Fatal(http.ListenAndServe(":9001", nil)) -}