From 97711f26cbc984ee4fc61bcaf8cffa3ad0e728ad Mon Sep 17 00:00:00 2001 From: Denis Shatskiy Date: Tue, 8 Jul 2025 23:44:11 +0700 Subject: [PATCH] chore: Optimize Dockerfile for improved build performance and update Gitea workflows with Docker Buildx support --- .dockerignore | 69 ++++++++++++++ .gitea/workflows/docker-publish-fast.yml | 50 +++++++++++ .gitea/workflows/docker-publish-tabler.yml | 12 ++- .gitea/workflows/docker-publish.yml | 12 ++- CI_TROUBLESHOOTING.md | 100 +++++++++++++++++++++ Dockerfile | 33 +++++-- Dockerfile.fast | 45 ++++++++++ 7 files changed, 310 insertions(+), 11 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/docker-publish-fast.yml create mode 100644 CI_TROUBLESHOOTING.md create mode 100644 Dockerfile.fast diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e277b99 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,69 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Production builds +frontend/dist +frontend/build + +# Environment files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE files +.vscode +.idea +*.swp +*.swo + +# OS files +.DS_Store +Thumbs.db + +# Git +.git +.gitignore + +# Documentation +README.md +CHANGELOG.md +DOCKER.md + +# CI/CD +.gitea + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Dependency directories +jspm_packages/ + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity \ No newline at end of file diff --git a/.gitea/workflows/docker-publish-fast.yml b/.gitea/workflows/docker-publish-fast.yml new file mode 100644 index 0000000..1feff49 --- /dev/null +++ b/.gitea/workflows/docker-publish-fast.yml @@ -0,0 +1,50 @@ +name: Publish Fast Tabler Docker image + +on: + push: + branches: + - tabler + +jobs: + build-and-push-fast: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: | + image=moby/buildkit:v0.12.0 + network=host + + - name: Log in to Gitea Registry + uses: docker/login-action@v3 + with: + registry: git.shts.su + username: ${{ gitea.actor }} + password: ${{ secrets.ACTIONS_PAT }} + + - name: Build and push Fast Tabler Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.fast + push: true + platforms: linux/amd64 + cache-from: type=gha + cache-to: type=gha,mode=max + tags: | + git.shts.su/${{ gitea.repository }}:tabler-fast + git.shts.su/${{ gitea.repository }}:tabler-fast-${{ gitea.sha }} + labels: | + org.opencontainers.image.title=S3 Lists Manager with Tabler UI (Fast Build) + org.opencontainers.image.description=Modern S3 Lists Manager with Tabler UI design - Fast Alpine build + org.opencontainers.image.version=tabler-fast + org.opencontainers.image.revision=${{ gitea.sha }} + org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} + build-args: | + BUILDKIT_INLINE_CACHE=1 + BUILDKIT_PROGRESS=plain \ No newline at end of file diff --git a/.gitea/workflows/docker-publish-tabler.yml b/.gitea/workflows/docker-publish-tabler.yml index 3482dc8..7b2c614 100644 --- a/.gitea/workflows/docker-publish-tabler.yml +++ b/.gitea/workflows/docker-publish-tabler.yml @@ -12,6 +12,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: | + image=moby/buildkit:v0.12.0 + - name: Log in to Gitea Registry uses: docker/login-action@v3 with: @@ -26,6 +32,8 @@ jobs: file: ./Dockerfile push: true platforms: linux/amd64 + cache-from: type=gha + cache-to: type=gha,mode=max tags: | git.shts.su/${{ gitea.repository }}:tabler git.shts.su/${{ gitea.repository }}:tabler-${{ gitea.sha }} @@ -34,4 +42,6 @@ jobs: org.opencontainers.image.description=Modern S3 Lists Manager with Tabler UI design org.opencontainers.image.version=tabler org.opencontainers.image.revision=${{ gitea.sha }} - org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} \ No newline at end of file + org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} + build-args: | + BUILDKIT_INLINE_CACHE=1 \ No newline at end of file diff --git a/.gitea/workflows/docker-publish.yml b/.gitea/workflows/docker-publish.yml index c9074e7..fdc10bf 100644 --- a/.gitea/workflows/docker-publish.yml +++ b/.gitea/workflows/docker-publish.yml @@ -12,6 +12,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: | + image=moby/buildkit:v0.12.0 + - name: Log in to Gitea Registry uses: docker/login-action@v3 with: @@ -26,6 +32,8 @@ jobs: file: ./Dockerfile push: true platforms: linux/amd64 + cache-from: type=gha + cache-to: type=gha,mode=max tags: | git.shts.su/${{ gitea.repository }}:latest git.shts.su/${{ gitea.repository }}:${{ gitea.sha }} @@ -34,4 +42,6 @@ jobs: org.opencontainers.image.description=S3 Lists Manager for domains and AS management org.opencontainers.image.version=latest org.opencontainers.image.revision=${{ gitea.sha }} - org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} \ No newline at end of file + org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} + build-args: | + BUILDKIT_INLINE_CACHE=1 \ No newline at end of file diff --git a/CI_TROUBLESHOOTING.md b/CI_TROUBLESHOOTING.md new file mode 100644 index 0000000..d71bc68 --- /dev/null +++ b/CI_TROUBLESHOOTING.md @@ -0,0 +1,100 @@ +# CI/CD Troubleshooting Guide + +## Проблемы со сборкой Docker + +### 1. Сборка зависает на npm install + +**Симптомы:** +- CI зависает на этапе `RUN npm install` +- Время сборки превышает 20 минут +- Ошибки сетевого подключения + +**Решения:** + +#### A. Использовать оптимизированный Dockerfile +```bash +# Основной оптимизированный +docker build -f Dockerfile . + +# Быстрый с Yarn +docker build -f Dockerfile.fast . +``` + +#### B. Проверить сетевые настройки +```bash +# В CI добавить таймауты +npm config set fetch-timeout 300000 +npm config set fetch-retry-mintimeout 20000 +npm config set fetch-retry-maxtimeout 120000 +``` + +#### C. Использовать кэширование +```yaml +# В CI/CD файле +cache-from: type=gha +cache-to: type=gha,mode=max +``` + +### 2. Проблемы с Node.js версиями + +**Симптомы:** +- `EBADENGINE Unsupported engine` +- Ошибки совместимости пакетов + +**Решения:** +- Обновить Dockerfile до Node.js 20 +- Проверить совместимость всех зависимостей + +### 3. Проблемы с размером образа + +**Симптомы:** +- Слишком большой размер Docker образа +- Медленная загрузка + +**Решения:** +- Использовать Alpine Linux (`node:20-alpine`) +- Добавить `.dockerignore` +- Использовать multi-stage builds + +## Быстрые решения + +### Вариант 1: Основной оптимизированный +```bash +# Использует обновленный Dockerfile с кэшированием +git push origin tabler +``` + +### Вариант 2: Быстрый с Yarn +```bash +# Переименовать Dockerfile.fast в Dockerfile +mv Dockerfile.fast Dockerfile +git add Dockerfile +git commit -m "Switch to fast Dockerfile" +git push origin tabler +``` + +### Вариант 3: Локальная сборка для тестирования +```bash +# Собрать локально для проверки +docker build -t test-image . +docker run -p 3001:3001 test-image +``` + +## Мониторинг CI/CD + +### Проверить статус сборки +1. Зайти в Gitea → Repository → Actions +2. Найти последний workflow +3. Проверить логи на каждом этапе + +### Типичные времена сборки +- **Оптимизированный Dockerfile**: 5-10 минут +- **Быстрый Dockerfile**: 3-7 минут +- **С кэшированием**: 2-5 минут (повторные сборки) + +## Контакты для поддержки + +Если проблемы продолжаются: +1. Проверить логи CI/CD +2. Попробовать локальную сборку +3. Создать issue с логами ошибок \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c786a5d..d5dc0d5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,24 +2,39 @@ FROM node:20-slim AS frontend-builder WORKDIR /app/frontend -# Copy package.json ONLY and install dependencies from scratch -# This avoids issues with lock files generated on different OS (e.g. Windows -> Linux) -COPY frontend/package.json ./ -RUN npm install +# Set npm config for better performance +RUN npm config set registry https://registry.npmjs.org/ +RUN npm config set fetch-timeout 300000 +RUN npm config set fetch-retry-mintimeout 20000 +RUN npm config set fetch-retry-maxtimeout 120000 -# Copy rest of the frontend code and build +# Copy package files first for better caching +COPY frontend/package*.json ./ + +# Install dependencies with specific flags +RUN npm ci --only=production --no-audit --no-fund --prefer-offline + +# Copy source code COPY frontend/ . + +# Build the application RUN npm run build # Stage 2: Setup Node.js backend and serve everything FROM node:20-slim WORKDIR /app -# Copy package.json ONLY and install production dependencies from scratch -COPY backend/package.json ./ -RUN npm install --omit=dev +# Set npm config for better performance +RUN npm config set registry https://registry.npmjs.org/ +RUN npm config set fetch-timeout 300000 -# Copy rest of the backend code +# Copy package files first for better caching +COPY backend/package*.json ./ + +# Install production dependencies only +RUN npm ci --only=production --no-audit --no-fund --prefer-offline + +# Copy backend source code COPY backend/ . # Copy built frontend assets from the previous stage diff --git a/Dockerfile.fast b/Dockerfile.fast new file mode 100644 index 0000000..45f7981 --- /dev/null +++ b/Dockerfile.fast @@ -0,0 +1,45 @@ +# Stage 1: Build React frontend +FROM node:20-alpine AS frontend-builder +WORKDIR /app/frontend + +# Install yarn for faster package management +RUN npm install -g yarn + +# Copy package files +COPY frontend/package*.json ./ +COPY frontend/yarn.lock* ./ + +# Install dependencies with yarn (faster than npm) +RUN yarn install --frozen-lockfile --network-timeout 300000 + +# Copy source code +COPY frontend/ . + +# Build the application +RUN yarn build + +# Stage 2: Setup Node.js backend and serve everything +FROM node:20-alpine +WORKDIR /app + +# Install yarn for faster package management +RUN npm install -g yarn + +# Copy package files +COPY backend/package*.json ./ +COPY backend/yarn.lock* ./ + +# Install production dependencies only +RUN yarn install --frozen-lockfile --production --network-timeout 300000 + +# Copy backend source code +COPY backend/ . + +# Copy built frontend assets from the previous stage +COPY --from=frontend-builder /app/frontend/dist ./public + +# The port the backend runs on +EXPOSE 3001 + +# Start the server +CMD ["node", "server.js"] \ No newline at end of file