diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..546e95f --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,66 @@ +name: Build & Deploy + +on: + push + +env: + REGISTRY: git.aggtaa.com + IMAGE_PREFIX: ${{ gitea.repository }} + +jobs: + # ── BUILD SERVER ────────────────────────────────────────────────────────────── + build-app: + runs-on: docker1 + defaults: + run: + shell: sh + working-directory: /workspace + steps: + - name: Checkout + working-directory: / + run: | + mkdir -p /workspace + if [ -d /workspace/.git ]; then + cd /workspace && git fetch origin && git reset --hard origin/${{ gitea.ref_name }} + else + git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git /workspace + fi + + - name: Build & push app + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | \ + docker login ${{ env.REGISTRY }} -u ${{ secrets.REGISTRY_USER }} --password-stdin + + /data/tools/docker-buildx build \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/app:cache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/app:cache,mode=max \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/app:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/app:${{ gitea.sha }} \ + --file Dockerfile \ + --push \ + . + + # ── DEPLOY ──────────────────────────────────────────────────────────────────── + deploy: + runs-on: docker1 + needs: [build-app] + if: always() && !failure() && !cancelled() + defaults: + run: + shell: sh + steps: + - name: Deploy + run: | + mkdir -p "/app-cache/${{ gitea.repository }}" + cd "/app-cache/${{ gitea.repository }}" + if [ ! -d .git ]; then + git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git . + else + git pull origin main + fi + printf 'REGISTRY=%s\nIMAGE_PREFIX=%s\n' \ + '${{ env.REGISTRY }}' \ + '${{ env.IMAGE_PREFIX }}' > .env + docker compose pull + docker compose up -d --remove-orphans + docker image prune -f diff --git a/.gitignore b/.gitignore index 3c3629e..9c97bbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules +dist +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..530c92a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +# syntax=docker/dockerfile:1 +FROM node:22.22.3-alpine AS base +RUN corepack enable && corepack prepare pnpm@latest --activate + +# ── deps ────────────────────────────────────────────────────────────────────── +FROM base AS deps +WORKDIR /app + +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +# ── build ───────────────────────────────────────────────────────────────────── +FROM deps AS builder +WORKDIR /app + +COPY tsconfig.json ./ +COPY src ./src + +RUN pnpm build + +# ── runtime ─────────────────────────────────────────────────────────────────── +FROM node:22.22.3-alpine AS runner +RUN corepack enable && corepack prepare pnpm@latest --activate +WORKDIR /app + +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --prod + +COPY --from=builder /app/dist ./dist + +EXPOSE 3000 + +CMD ["node", "dist/index.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a422608 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +services: + server: + image: ${CI_REGISTRY_IMAGE:-claudemcp}/app:${CI_COMMIT_SHA:-latest} + container_name: ${CI_REGISTRY_IMAGE:-claudemcp} + restart: unless-stopped + ports: + - "${APP_PORT:-3000}:3000" + networks: + - local + +networks: + local: + driver: bridge \ No newline at end of file