Skip to content

Docker-сборки

Эта страница описывает структуру, сборку и хранение Docker-образов для сервисов.

Реестр

Все образы хранятся в GitLab Container Registry по адресу:

gitlab.amzgit.com:5050

Полный путь к образу имеет следующую структуру:

gitlab.amzgit.com:5050/<group>/<project>/<service>:<tag>

Например:

gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4
gitlab.amzgit.com:5050/meduza/hub/frontend:a1b2c3d4
gitlab.amzgit.com:5050/meduza/auth/api:dev

Аутентификация в реестре

CI-задачи аутентифицируются автоматически через $CI_REGISTRY_USER и $CI_REGISTRY_PASSWORD. Для ручного получения образов (например, с KVM-хоста или локальной машины):

bash
docker login gitlab.amzgit.com:5050 -u <username> -p <access_token>

Personal Access Token

Используйте GitLab Personal Access Token с правом read_registry для получения образов. В CI-сборках GitLab предоставляет учётные данные автоматически — настройка не требуется.

Стратегия тегирования образов

Каждый образ получает два тега при сборке в CI:

ТегФорматНазначение
Commit SHAa1b2c3d4Неизменяемый идентификатор, привязанный к конкретному коду. Используется Nomad при деплое.
Окружениеprod / stage / devМутабельный указатель на последнюю сборку для данного окружения. Удобен для быстрого локального тестирования.

Тег commit SHA используется Nomad для деплоя. Тег окружения — это удобный алиас, который перезаписывается при каждом пуше в соответствующую ветку.

bash
# These point to the same image after a deploy from dev branch:
docker pull gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4
docker pull gitlab.amzgit.com:5050/meduza/hub/backend:dev

Мутабельные теги окружений

Теги dev, stage и prod перезаписываются при каждой сборке. Никогда не ссылайтесь на эти теги в Nomad-файлах или продакшн-инфраструктуре. Для деплоев всегда используйте commit SHA.

Паттерны Dockerfile

Сервисы обычно делятся на две категории: только бэкенд и полный стек с фронтендом. Оба используют многоэтапные сборки для минимизации размера итоговых образов.

Бэкенд-сервис (Python / Go)

dockerfile
# --- Build stage ---
FROM python:3.12-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

COPY . .

# --- Runtime stage ---
FROM python:3.12-slim

WORKDIR /app
COPY --from=builder /install /usr/local
COPY --from=builder /app .

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
dockerfile
# --- Build stage ---
FROM golang:1.22-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /bin/server .

# --- Runtime stage ---
FROM alpine:3.19

COPY --from=builder /bin/server /bin/server

EXPOSE 8080
ENTRYPOINT ["/bin/server"]

Фронтенд (Vite + Node)

Фронтенд-сборки компилируют статические ресурсы на этапе сборки и раздают их из легковесного образа.

dockerfile
# --- Build stage ---
FROM node:20-alpine AS builder

WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

COPY . .
ARG VITE_API_URL
ENV VITE_API_URL=${VITE_API_URL}
RUN pnpm build

# --- Runtime stage ---
FROM nginx:alpine

COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

Аргументы сборки для фронтенда

Специфичные для окружения значения, такие как VITE_API_URL, должны передаваться во время сборки, поскольку Vite вшивает их в статический JS-бандл. Передавайте их через BUILD_ARGS в CI-задаче:

yaml
BUILD_ARGS: "--build-arg VITE_API_URL=https://api.amzhub.ai"

Полный стек (бэкенд + фронтенд в одном репозитории)

Когда бэкенд и фронтенд находятся в одном репозитории, каждый получает отдельную задачу сборки с указанием своего SERVICE_DIR:

yaml
build:backend:
  extends: .docker_build
  variables:
    SERVICE_NAME: backend
    SERVICE_DIR: back

build:frontend:
  extends: .docker_build
  variables:
    SERVICE_NAME: frontend
    SERVICE_DIR: front
    BUILD_ARGS: "--build-arg VITE_API_URL=https://api.amzhub.ai"

В результате создаются два отдельных образа:

gitlab.amzgit.com:5050/meduza/hub/backend:a1b2c3d4
gitlab.amzgit.com:5050/meduza/hub/frontend:a1b2c3d4

Оба имеют одинаковый тег commit SHA, так как собраны из одного коммита.

Ограничение платформы

Все образы собираются с флагом --platform linux/amd64:

bash
docker build --platform linux/amd64 -t ... .

Это обеспечивается шаблоном .docker_build. KVM-хосты, на которых работает Nomad, используют архитектуру amd64, поэтому даже если CI-раннеры или машины разработчиков основаны на ARM (Apple Silicon), итоговые образы будут корректно работать на целевой инфраструктуре.

Локальное тестирование на ARM Mac

Если вы собираете локально на Mac с чипом M-серии без флага --platform linux/amd64, образ может работать на вашей машине, но упасть на KVM-хосте. Всегда указывайте флаг платформы при локальной сборке для тестирования деплоя:

bash
docker build --platform linux/amd64 -t my-service:test .

Контекст сборки и .dockerignore

Каждый SERVICE_DIR должен содержать собственный .dockerignore для уменьшения контекста сборки:

gitignore
node_modules
.git
.env
.env.*
*.md
dist
__pycache__
.venv

Компактный контекст сборки ускоряет этап docker build в CI, поскольку меньше данных передаётся демону Docker.

Документация по инфраструктуре