diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1ae8878..6a75526 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Deploy to VPS +name: Build & Deploy App on: push: @@ -6,25 +6,53 @@ on: - master jobs: - deploy: + build-and-push: + name: Build and Push Docker Image runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - - name: Set up SSH - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: ${{ secrets.VPS_SSH_KEY }} + - name: Login to Docker Hub + run: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin - - name: Deploy via SSH - env: - USER: ${{ secrets.VPS_USER }} - HOST: ${{ secrets.VPS_HOST }} + - name: Build Docker image run: | - ssh -o StrictHostKeyChecking=no $USER@$HOST << 'EOF' - cd ~/portfolio/ - git pull origin master - docker compose up --build -d - EOF + docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/portfolio:latest . + + - name: Push image to Docker Hub + run: | + docker push ${{ secrets.DOCKERHUB_USERNAME }}/portfolio:latest + + deploy: + name: Deploy to VPS + needs: build-and-push + runs-on: ubuntu-latest + + steps: + - name: Setup SSH key + run: | + mkdir -p ~/.ssh + echo "${{ secrets.VPS_SSH_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts + + - name: Copy docker-compose.yml to VPS + uses: appleboy/scp-action@master + with: + host: ${{ secrets.VPS_HOST }} + username: ${{ secrets.VPS_USER }} + key: ${{ secrets.VPS_SSH_KEY }} + port: 22 + source: 'docker-compose.yml' + target: '/home/${{ secrets.VPS_USER }}/portfolio/' + + - name: Deploy on VPS + run: | + ssh ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} " + cd /home/${{ secrets.VPS_USER }}/portfolio && \ + docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} && \ + docker compose pull && \ + docker compose up -d + " diff --git a/Dockerfile b/Dockerfile index e1eb45a..8066f4d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,66 +1,49 @@ -# syntax=docker.io/docker/dockerfile:1 +# syntax=docker/dockerfile:1.4 -FROM node:18-alpine AS base +# Указываем версию Node.js +ARG NODE_VERSION=22 +FROM node:${NODE_VERSION}-alpine AS base -# Install dependencies only when needed +# Устанавливаем необходимые пакеты +RUN apk add --no-cache libc6-compat openssl + +# Настройка PNPM +ENV PNPM_HOME="/pnpm" +ENV PATH="${PNPM_HOME}:${PATH}" +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Установка зависимостей FROM base AS deps -# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. -RUN apk add --no-cache libc6-compat WORKDIR /app +COPY package.json pnpm-lock.yaml ./ +RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ + pnpm install --frozen-lockfile -# Install dependencies based on the preferred package manager -COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./ -RUN \ - if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ - elif [ -f package-lock.json ]; then npm ci; \ - elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ - else echo "Lockfile not found." && exit 1; \ - fi - - -# Rebuild the source code only when needed +# Сборка проекта FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -# ENV NEXT_TELEMETRY_DISABLED=1 +RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ + pnpm run build -RUN \ - if [ -f yarn.lock ]; then yarn run build; \ - elif [ -f package-lock.json ]; then npm run build; \ - elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ - else echo "Lockfile not found." && exit 1; \ - fi - -# Production image, copy all the files and run next +# Production-слой FROM base AS runner WORKDIR /app ENV NODE_ENV=production -# Uncomment the following line in case you want to disable telemetry during runtime. -# ENV NEXT_TELEMETRY_DISABLED=1 +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs +# Создание пользователя +RUN addgroup --system --gid 1001 nodejs \ + && adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public - -# Automatically leverage output traces to reduce image size -# https://nextjs.org/docs/advanced-features/output-file-tracing COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static USER nextjs - EXPOSE 3000 - -ENV PORT=3000 - -# server.js is created by next build from the standalone output -# https://nextjs.org/docs/pages/api-reference/next-config-js/output -ENV HOSTNAME="0.0.0.0" -CMD ["node", "server.js"] \ No newline at end of file +CMD ["node", "server.js"] diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..5d2bb6d --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,5 @@ +services: + app: + ports: + - 3000:3000 + build: ./ diff --git a/docker-compose.yml b/docker-compose.yml index 3563e32..e77f3b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,6 @@ services: - app: - build: . -# ports: -# - '3000:3000' - labels: - - 'traefik.http.routers.portfolio.rule=Host(`vchikalkin.dev`)' - - 'traefik.http.routers.portfolio.entrypoints=websecure' - - 'traefik.http.routers.portfolio.tls=true' - - 'traefik.http.routers.portfolio.tls.certresolver=myresolver' + portfolio: + image: vchikalkin/portfolio:latest networks: - web