From c36994c36b78063068aff5fa509d1d26c522de51 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Tue, 12 May 2026 12:11:43 +0700 Subject: [PATCH] chore: update configuration and dependencies - Added .ci/docker/ to .gitignore to exclude Docker CI files. - Set Next.js output configuration to "standalone" for optimized deployment. - Updated package-lock.json to include new optional dependency for Windows SWC binaries. --- .dockerignore | 23 ++++++ .gitea/workflows/docker.yml | 137 ++++++++++++++++++++++++++++++++++++ .gitignore | 1 + Dockerfile.frontend | 34 +++++++++ backend/Dockerfile | 35 +++++++++ next.config.ts | 2 +- package-lock.json | 15 ++++ 7 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/docker.yml create mode 100644 Dockerfile.frontend create mode 100644 backend/Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..daf13a2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,23 @@ +.git +.github +.gitea +.ci +.cursor +.claude +node_modules +.next +out +dist +build +coverage +.turbo +.cache +*.log +.env +.env.* +tmp +temp +.vercel +backend +packages/contracts/dist +backend/dist diff --git a/.gitea/workflows/docker.yml b/.gitea/workflows/docker.yml new file mode 100644 index 0000000..0a1efdb --- /dev/null +++ b/.gitea/workflows/docker.yml @@ -0,0 +1,137 @@ +name: Docker images + +on: + push: + branches: + - main + workflow_dispatch: + +env: + REGISTRY: git.shts.su + +jobs: + backend-image: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare backend build context + shell: bash + run: | + set -euo pipefail + STAGING=".ci/docker/backend" + rm -rf "$STAGING" + mkdir -p "$STAGING/packages/contracts" "$STAGING/backend" + cp package.json package-lock.json "$STAGING/" + cp packages/contracts/package.json packages/contracts/tsconfig.json "$STAGING/packages/contracts/" + cp -R packages/contracts/src "$STAGING/packages/contracts/" + cp backend/package.json backend/tsconfig.json "$STAGING/backend/" + cp -R backend/src "$STAGING/backend/" + if [ -d backend/drizzle ]; then + cp -R backend/drizzle "$STAGING/backend/" + fi + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - 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 backend image + uses: docker/build-push-action@v5 + with: + context: .ci/docker/backend + file: backend/Dockerfile + platforms: linux/amd64 + push: true + tags: | + ${{ env.REGISTRY }}/${{ gitea.repository }}:backend-latest + ${{ env.REGISTRY }}/${{ gitea.repository }}:backend-${{ gitea.sha }} + cache-from: type=gha,scope=backend + cache-to: type=gha,mode=max,scope=backend + labels: | + org.opencontainers.image.title=mmapp-backend + org.opencontainers.image.description=MikroTik Manager backend (Fastify) + org.opencontainers.image.version=latest + org.opencontainers.image.revision=${{ gitea.sha }} + org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} + + frontend-image: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare frontend build context + shell: bash + run: | + set -euo pipefail + STAGING=".ci/docker/frontend" + rm -rf "$STAGING" + mkdir -p "$STAGING/packages/contracts" + cp package-lock.json next.config.ts tsconfig.json postcss.config.mjs eslint.config.mjs components.json "$STAGING/" + node <<'NODE' + const fs = require("node:fs") + const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")) + pkg.workspaces = ["packages/*"] + fs.writeFileSync(".ci/docker/frontend/package.json", `${JSON.stringify(pkg, null, 2)}\n`) + NODE + cp packages/contracts/package.json packages/contracts/tsconfig.json "$STAGING/packages/contracts/" + cp -R packages/contracts/src "$STAGING/packages/contracts/" + for dir in app components lib shared entities public hooks; do + if [ -d "$dir" ]; then + cp -R "$dir" "$STAGING/" + fi + done + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - 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 frontend image + uses: docker/build-push-action@v5 + with: + context: .ci/docker/frontend + file: Dockerfile.frontend + platforms: linux/amd64 + push: true + tags: | + ${{ env.REGISTRY }}/${{ gitea.repository }}:frontend-latest + ${{ env.REGISTRY }}/${{ gitea.repository }}:frontend-${{ gitea.sha }} + cache-from: type=gha,scope=frontend + cache-to: type=gha,mode=max,scope=frontend + labels: | + org.opencontainers.image.title=mmapp-frontend + org.opencontainers.image.description=MikroTik Manager frontend (Next.js) + org.opencontainers.image.version=latest + org.opencontainers.image.revision=${{ gitea.sha }} + org.opencontainers.image.created=${{ gitea.event.head_commit.timestamp }} + + notify-webhook: + if: ${{ secrets.DEPLOY_WEBHOOK_URL != '' }} + needs: + - backend-image + - frontend-image + runs-on: ubuntu-latest + steps: + - name: Notify deploy webhook + shell: bash + env: + WEBHOOK_URL: ${{ secrets.DEPLOY_WEBHOOK_URL }} + run: | + set -euo pipefail + curl --fail --silent --show-error --request POST \ + --header "Content-Type: application/json" \ + --data "{\"repository\":\"${{ gitea.repository }}\",\"sha\":\"${{ gitea.sha }}\",\"ref\":\"${{ gitea.ref }}\"}" \ + "$WEBHOOK_URL" diff --git a/.gitignore b/.gitignore index acb0034..0f41946 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ Thumbs.db .vercel/ tmp/ temp/ +.ci/docker/ diff --git a/Dockerfile.frontend b/Dockerfile.frontend new file mode 100644 index 0000000..5ba96ee --- /dev/null +++ b/Dockerfile.frontend @@ -0,0 +1,34 @@ +# syntax=docker/dockerfile:1 + +FROM node:22-bookworm-slim AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +COPY packages/contracts/package.json packages/contracts/ +RUN npm ci --workspace=@mmapp/contracts --include-workspace-root + +FROM deps AS build +COPY packages/contracts packages/contracts +COPY next.config.ts tsconfig.json postcss.config.mjs components.json ./ +COPY app app +COPY components components +COPY lib lib +COPY shared shared +COPY entities entities +COPY public public +COPY hooks hooks +ENV NEXT_TELEMETRY_DISABLED=1 +RUN npm run build -w @mmapp/contracts \ + && npm run build \ + && npm prune --omit=dev + +FROM node:22-bookworm-slim AS runner +WORKDIR /app +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 +ENV HOSTNAME=0.0.0.0 +ENV PORT=3000 +COPY --from=build /app/public ./public +COPY --from=build /app/.next/standalone ./ +COPY --from=build /app/.next/static ./.next/static +EXPOSE 3000 +CMD ["node", "server.js"] diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..2940dab --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,35 @@ +# syntax=docker/dockerfile:1 + +FROM node:22-bookworm-slim AS deps +RUN apt-get update \ + && apt-get install -y --no-install-recommends python3 make g++ \ + && rm -rf /var/lib/apt/lists/* +WORKDIR /app +COPY package.json package-lock.json ./ +COPY packages/contracts/package.json packages/contracts/ +COPY backend/package.json backend/ +RUN npm ci --workspace=@mmapp/contracts --workspace=mikrotik-manager-backend --include-workspace-root + +FROM deps AS build +COPY packages/contracts packages/contracts +COPY backend backend +RUN npm run build -w @mmapp/contracts \ + && npm run build -w mikrotik-manager-backend \ + && npm prune --omit=dev + +FROM node:22-bookworm-slim AS runner +RUN apt-get update \ + && apt-get install -y --no-install-recommends python3 make g++ \ + && rm -rf /var/lib/apt/lists/* +WORKDIR /app +ENV NODE_ENV=production +ENV PORT=8000 +ENV DATABASE_PATH=/app/data/mikrotik.db +COPY --from=build /app/package.json /app/package-lock.json ./ +COPY --from=build /app/node_modules ./node_modules +COPY --from=build /app/packages/contracts ./packages/contracts +COPY --from=build /app/backend/dist ./backend/dist +COPY --from=build /app/backend/package.json ./backend/package.json +RUN mkdir -p /app/data +EXPOSE 8000 +CMD ["node", "backend/dist/index.js"] diff --git a/next.config.ts b/next.config.ts index e9ffa30..68a6c64 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + output: "standalone", }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 456d7b4..eab5ec0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12684,6 +12684,21 @@ "dependencies": { "zod": "^4.4.1" } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.4.tgz", + "integrity": "sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } }