diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..67f455701 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,37 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + packages: write + +jobs: + build-and-push: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 + + - name: Log in to ghcr.io + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 + with: + context: . + file: ./Dockerfile + push: true + tags: | + ghcr.io/${{ github.repository_owner }}/devops-intro/quicknotes:${{ github.ref_name }} + ghcr.io/${{ github.repository_owner }}/devops-intro/quicknotes:latest \ No newline at end of file diff --git a/Docker_SDK b/Docker_SDK new file mode 160000 index 000000000..b163bb92f --- /dev/null +++ b/Docker_SDK @@ -0,0 +1 @@ +Subproject commit b163bb92faf3716db8d9a9a388993d6b5cb1e2fc diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..15aca91d4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.24-alpine AS builder +WORKDIR /build +COPY app/go.mod ./ +RUN go mod download +COPY app/ . +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ + go build -ldflags="-s -w" -trimpath \ + -o /build/quicknotes . + +RUN mkdir -p /data && chown 65532:65532 /data + +FROM gcr.io/distroless/static:debug +WORKDIR /app +COPY --from=builder /build/quicknotes . +COPY --from=builder /data /data +COPY app/seed.json . +EXPOSE 8080 +USER 65532:65532 +ENTRYPOINT ["/app/quicknotes"] \ No newline at end of file diff --git a/quicknotes-lab10 b/quicknotes-lab10 new file mode 160000 index 000000000..fd6531e03 --- /dev/null +++ b/quicknotes-lab10 @@ -0,0 +1 @@ +Subproject commit fd6531e032b648eb86cb4602f598019092865864 diff --git a/submissions/image-1.png b/submissions/image-1.png new file mode 100644 index 000000000..cc5b7d095 Binary files /dev/null and b/submissions/image-1.png differ diff --git a/submissions/image-2.png b/submissions/image-2.png new file mode 100644 index 000000000..3feed8272 Binary files /dev/null and b/submissions/image-2.png differ diff --git a/submissions/image-3.png b/submissions/image-3.png new file mode 100644 index 000000000..c257f73af Binary files /dev/null and b/submissions/image-3.png differ diff --git a/submissions/image-4.png b/submissions/image-4.png new file mode 100644 index 000000000..5b7e6c185 Binary files /dev/null and b/submissions/image-4.png differ diff --git a/submissions/image-5.png b/submissions/image-5.png new file mode 100644 index 000000000..159980264 Binary files /dev/null and b/submissions/image-5.png differ diff --git a/submissions/image-6.png b/submissions/image-6.png new file mode 100644 index 000000000..e7e12ac21 Binary files /dev/null and b/submissions/image-6.png differ diff --git a/submissions/image-7.png b/submissions/image-7.png new file mode 100644 index 000000000..b2f8fc179 Binary files /dev/null and b/submissions/image-7.png differ diff --git a/submissions/image-8.png b/submissions/image-8.png new file mode 100644 index 000000000..1d63e487f Binary files /dev/null and b/submissions/image-8.png differ diff --git a/submissions/image.png b/submissions/image.png new file mode 100644 index 000000000..4787e3330 Binary files /dev/null and b/submissions/image.png differ diff --git a/submissions/lab10.md b/submissions/lab10.md new file mode 100644 index 000000000..59af51985 --- /dev/null +++ b/submissions/lab10.md @@ -0,0 +1,90 @@ +# Lab 10 + +Frolova AI - M25RO-01 + +a.frolova@innopolis.university + +Ссылка на PR: https://github.com/inno-devops-labs/DevOps-Intro/pull/1410 + +## Task1 + +## Task 1 — CI-Automated Push to `ghcr.io` (6 pts) + +### Release workflow + +Файл `.github/workflows/release.yml` создан и настроен на push по тегу `v*`. + +### Успешный CI + +![alt text](image.png) + +Такое название, потому что засабмитила не все файлы изначально. + +### Публичный образ + +![alt text](image-1.png) + +### Ответы на вопросы + +a) OIDC vs GITHUB_TOKEN — for pushing to ghcr.io from the same repo, GITHUB_TOKEN with packages: write is enough. When would you reach for OIDC instead, and what does it give you that GITHUB_TOKEN doesn't? + +`GITHUB_TOKEN` с правами `packages: write` достаточно для пуша в `ghcr.io` внутри того же репозитория. OIDC используют, когда нужно получить временный токен для доступа к внешним облакам (AWS, GCP, Azure) без хранения долгоживущих секретов. OIDC даёт **безопасный short-lived доступ** на основе JWT, который нельзя украсть и использовать повторно. + +--- + +b) :latest tag vs :v0.1.0 immutable tag — Lab 6 covered why :latest is mutable. So why do you still ship a :latest tag alongside the immutable one in production releases? + +`:latest` — мутабельный тег, его удобно использовать для разработки и CI (всегда можно сослаться на «свежий» образ). `:v0.1.0` — фиксированный, воспроизводимый тег для продакшена. `:latest` нужен, чтобы разработчики и CI могли всегда получить актуальную версию, не обновляя теги вручную, но при этом для продакшена используется конкретная версия. + +--- + +c) packages: write scope only — what's the principle, and what concrete attack does the narrow scope prevent vs write: all? + +Принцип **наименьших привилегий**. Ограничение `packages: write` не даёт злоумышленнику (или ошибке в CI) делать ничего, кроме пуша в registry. Если бы был `write: all`, атакующий мог бы изменять код, выдавать разрешения или удалять важные ресурсы. + +## Task2 + + + +![alt text](image-5.png) + +Hugging Face решил, что бесплатные лимиты потрачены... + +![alt text](image-3.png) + +Создан Space, склонирован: + + +![alt text](image-6.png) + +Успешный push: + +![alt text](image-7.png) + +И так как были потрачены лимиты (я делала несколько новых space чтобы успеть хоть что-то заскринить пока все не пропадет), не получается показать вывод команды `health` и выполнить другие требования к работе. + +![alt text](image-8.png) + +**Space URL:** `https://kicchhi-quicknotes-lab10.hf.space` + +Опять же, из-за лимитов, Space открывается только до момента, пока туда что-то не запушить. + +По этим же причинам не удается провести замеры warm latency, cold start. + +### Ответы на вопросы + +d) HF Spaces "sleep" vs Cloud Run "scale to zero" — same idea, different orders of magnitude. Why is HF's wake so much slower? What does the platform optimize for differently? + +По логике HF Space полностью останавливает контейнер при простое, поэтому холодный старт медленный. Cloud Run держит контейнер в «спящем» состоянии, что ускоряет пробуждение. + +--- + +e) Why does the Space need app_port: 8080? What's HF's default and why do they default to that? + +HF по умолчанию использует порт 7860. QuickNotes слушает 8080, поэтому нужно явно указать `app_port: 8080` в `README.md`. + +--- + +f) You pulled the image from ghcr.io into the Space. What's the trade-off vs building the Dockerfile inside the Space? (Hint: caching, reproducibility, debug-ability.) + +Пул готового образа из `ghcr.io` быстрее и надёжнее. Сборка внутри Space может упасть из-за ограничений ресурсов.