Hoang  Ha

Hoang Ha

1639840532

Triển khai ứng dụng Next.js lên VPS với Github Action và Docker

Gần đây, tôi đã phải triển khai một dự án tới giọt DigitalOcean. Một trong những tính năng mà tôi thực sự muốn cho dự án cụ thể này là đường ống Phân phối liên tục.

Trang web phân phối liên tục định nghĩa đây là khả năng nhận các thay đổi thuộc mọi loại — bao gồm các tính năng mới, thay đổi cấu hình, sửa lỗi và thử nghiệm — vào sản xuất hoặc đến tay người dùng một cách an toàn và nhanh chóng theo cách bền vững.

Mục tiêu là thực hiện triển khai — cho dù là một hệ thống phân tán quy mô lớn, một môi trường sản xuất phức tạp, một hệ thống nhúng hay một ứng dụng — các công việc thường xuyên có thể dự đoán được có thể được thực hiện theo yêu cầu.

Đối với trường hợp của tôi, tôi muốn ứng dụng web tự động triển khai tới VPS bất cứ khi nào tôi đẩy các thay đổi lên chi nhánh Github chính. Do đó, điều này sẽ tiết kiệm rất nhiều thời gian phát triển trong quá trình này.

Các giải pháp thay thế

Có các giải pháp thay thế và không hối hả cho vấn đề này, chẳng hạn như nền tảng ứng dụng VercelDigitalOcean . Tuy nhiên, một người có thể đi theo con đường của tôi nếu:

  1. Bạn muốn hiểu rõ hơn về các hành động trên Github
  2. Tìm hiểu thêm về docker
  3. Đối với trường hợp của Vercel, khách hàng hoặc tổ chức của bạn có thể muốn giữ các ứng dụng của họ trong một nền tảng trung tâm để quản lý dễ dàng hơn.

Điều kiện tiên quyết

Xin lưu ý rằng một số liên kết dưới đây là liên kết liên kết và bạn không phải trả thêm phí. Biết rằng tôi chỉ giới thiệu các sản phẩm, công cụ và dịch vụ học tập mà cá nhân tôi đã sử dụng và tin rằng thực sự hữu ích. Trên hết, tôi sẽ không bao giờ ủng hộ việc mua thứ gì đó mà bạn không đủ khả năng chi trả hoặc bạn chưa sẵn sàng thực hiện.

  1. Một tài khoản Github
  2. Một máy chủ riêng ảo. Tôi đã sử dụng giọt DigitalOcean chạy Ubuntu 20.04 LTS. Đăng ký bằng liên kết giới thiệu của tôi và nhận $ 100 tín dụng có giá trị trong 60 ngày.

Tạo ứng dụng next.js

Chúng tôi sẽ sử dụng npx để tạo ứng dụng next.js tiêu chuẩn

npx create-next-app meta-news && cd meta-news

Khi chúng ta đang ở trong thư mục dự án, chúng ta sẽ cài đặt một số phụ thuộc cho mục đích trình diễn

yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4 axios

Chúng tôi cũng sẽ khai báo các biến môi trường bên trong .env.localtệp. Sau đó, chúng tôi có thể tham chiếu các biến này từ ứng dụng của chúng tôi như vậyprocess.env.NEXT_PUBLIC_VARIABLE_NAME

NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api
NEXT_PUBLIC_META_API_KEY=your_api_key

Các biến này chỉ dành cho mục đích trình diễn. Vì vậy, chúng tôi sẽ không thực sự tham chiếu chúng trong ứng dụng của mình. Ví dụ về địa điểm bạn sẽ gọi chúng là khi khởi tạo phiên bản axios hoặc đặt id google analytics và bạn không muốn cam kết điều đó với hệ thống kiểm soát phiên bản.

Hãy chạy thử nhanh. Ứng dụng sẽ được chạy localhost:3000nếu mọi thứ được thiết lập đúng cách.

yarn start

Tài liệu hóa ứng dụng

Docker là một công cụ mã nguồn mở tự động hóa việc triển khai ứng dụng bên trong vùng chứa phần mềm. giống như máy ảo, chỉ di động hơn, thân thiện với tài nguyên hơn và phụ thuộc nhiều hơn vào hệ điều hành máy chủ. 

Chúng tôi sẽ thêm một Dockerfile vào gốc dự án bằng cách chạy touch Dockerfiletrong CLI.

# Install dependencies only when needed
FROM node:alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update && apk add --no-cache libc6-compat && apk add git
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --immutable


# Rebuild the source code only when needed
FROM node:alpine AS builder
# add environment variables to client code
ARG NEXT_PUBLIC_BACKEND_URL
ARG NEXT_PUBLIC_META_API_KEY


ENV NEXT_PUBLIC_BACKEND_URL=$NEXT_PUBLIC_BACKEND_URL
ENV NEXT_PUBLIC_META_API_KEY=$NEXT_PUBLIC_META_API_KEY

WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
ARG NODE_ENV=production
RUN echo ${NODE_ENV}
RUN NODE_ENV=${NODE_ENV} yarn build

# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration. 
# Copy all necessary files used by nex.config as well otherwise the build will fail

COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/pages ./pages

USER nextjs

# Expose
EXPOSE 3000

# 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.
ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"]

Chúng tôi đang chạy một bản dựng nhiều giai đoạn cho việc triển khai này. Chú ý các từ khóa ARG và ENV? Đó là cách chúng tôi chuyển các biến môi trường của mình sang mã khách hàng vì chúng tôi sẽ không có quyền truy cập vào bất kỳ .envtệp nào trong vùng chứa. Thêm về điều này sau.

Sau đó, chúng tôi sẽ xây dựng và gắn thẻ hình ảnh của mình

docker build --build-arg NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api --build-arg NEXT_PUBLIC_META_API_KEY=your_api_key -t meta-news .

Quá trình này có thể mất một lúc tùy thuộc vào kết nối internet và thông số kỹ thuật phần cứng của bạn. Khi mọi thứ đã kiểm tra xong, hãy chạy vùng chứa

docker run -p 3000:3000 meta-news

Khởi chạy trình duyệt của bạn và ứng dụng của bạn sẽ có thể truy cập được tại ' http: // localhost: 3000 ' 🎉

Thiết lập các hành động trên Github

GitHub Actions là một nền tảng tích hợp liên tục và phân phối liên tục (CI / CD) cho phép bạn tự động hóa quy trình xây dựng, thử nghiệm và triển khai của mình. Bạn có thể tạo quy trình công việc xây dựng và kiểm tra mọi yêu cầu kéo đến kho lưu trữ của mình hoặc triển khai các yêu cầu kéo đã hợp nhất vào sản xuất.

Để biết thêm về nền tảng tuyệt vời này, hãy truy cập trang hướng dẫn chính thức của họ

Chúng tôi sẽ tạo quy trình làm việc đầu tiên của mình bằng cách chạy các lệnh sau trong CLI. Bạn có thể sử dụng GUI nếu bạn không cảm thấy thoải mái với dòng lệnh 🤗.

mkdir .github && mkdir ./github/workflow && touch ./github/workflows/deploy.yml && nano ./github/workflows/deploy.yml

Điền vào tệp deploy.yml với các giá trị sau.

name: Build and Deploy

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    container: node:14

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Build and Publish to Github Packages Registry
        uses: elgohr/Publish-Docker-Github-Action@master
        env:
          NEXT_PUBLIC_BACKEND_URL: ${{ secrets.APP_NEXT_PUBLIC_BACKEND_URL }}
          NEXT_PUBLIC_META_API_KEY: ${{ secrets.APP_NEXT_PUBLIC_META_API_KEY }}
        with:
          name: my_github_username/my_repository_name/my_image_name
          registry: ghcr.io
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets. GITHUB_TOKEN }}
          dockerfile: Dockerfile
          buildargs: NEXT_PUBLIC_BACKEND_URL,NEXT_PUBLIC_META_API_KEY
          tags: latest

      - name: Deploy package to digitalocean
        uses: appleboy/ssh-action@master
        env:
          GITHUB_USERNAME: ${{ secrets.USERNAME }}
          GITHUB_TOKEN: ${{ secrets. GITHUB_TOKEN }}
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          port: ${{ secrets.DEPLOY_PORT }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          envs: GITHUB_USERNAME, GITHUB_TOKEN
          script: |
            docker login ghcr.io -u $GITHUB_USERNAME -p $GITHUB_TOKEN
            docker pull ghcr.io/my_github_username/my_repository_name/my_image_name:latest
            docker stop containername
            docker system prune -f
            docker run --name containername -dit -p 3000:3000 ghcr.io/my_github_username/my_repository_name/my_image_name:latest

Bạn có thể nhận thấy hành động của chúng tôi rất bí mật 😂. Đừng lo lắng, điều này được thực hiện có chủ ý để bảo vệ thông tin nhạy cảm của bạn khỏi những con mắt tò mò. Chúng là các biến môi trường được mã hóa mà bạn (chủ sở hữu repo) tạo cho repo sử dụng các hành động Github.

Một điều cần lưu ý là GITHUB_TOKENbí mật được tạo tự động cho chúng ta khi chạy hành động.

Để tạo bí mật, hãy chuyển đến kho lưu trữ> cài đặt> thanh bên trái> bí mật secret_creation

Để có hướng dẫn chuyên sâu, hãy xem hướng dẫn này .

Những bí mật được mong đợi trên Github là

  APP_NEXT_PUBLIC_BACKEND_URL - live backend server url
  APP_NEXT_PUBLIC_META_API_KEY - prod api key to thirdparty integration
  DEPLOY_HOST - IP to Digital Ocean (DO) droplet
  DEPLOY_KEY - SSH secret (pbcopy < ~/.ssh/id_rsa) and the public key should be added to `.ssh/authorized_keys` in server
  DEPLOY_PORT - SSH port (22)
  DEPLOY_USER  - User on droplet
  USERNAME - Your Github username

Nhấc lên 🚀

Đẩy đến nhánh chính

git add -A
git commit -m "Initial commit"
git push origin main

Nếu mọi thứ chạy như mong đợi, bạn sẽ thấy dấu kiểm màu xanh lá cây trong kho lưu trữ của mình với các bước xây dựng đã hoàn tất.

Github_actions_deploy

Từ đó, bạn có thể thiết lập proxy ngược, chẳng hạn như nginx trong máy chủ của mình và trỏ máy chủ tới " http: // localhost: 3000" .

Yay! 🥳 chúng tôi đã tạo thành công một đường dẫn phân phối liên tục và hy vọng bây giờ bạn sẽ tập trung vào mã thay vì cơ sở hạ tầng.

Nguồn: https://lewiskori.com

#nextjs #next #github #githubaction #docker

What is GEEK

Buddha Community

Triển khai ứng dụng Next.js lên VPS với Github Action và Docker
Hoang  Ha

Hoang Ha

1639840532

Triển khai ứng dụng Next.js lên VPS với Github Action và Docker

Gần đây, tôi đã phải triển khai một dự án tới giọt DigitalOcean. Một trong những tính năng mà tôi thực sự muốn cho dự án cụ thể này là đường ống Phân phối liên tục.

Trang web phân phối liên tục định nghĩa đây là khả năng nhận các thay đổi thuộc mọi loại — bao gồm các tính năng mới, thay đổi cấu hình, sửa lỗi và thử nghiệm — vào sản xuất hoặc đến tay người dùng một cách an toàn và nhanh chóng theo cách bền vững.

Mục tiêu là thực hiện triển khai — cho dù là một hệ thống phân tán quy mô lớn, một môi trường sản xuất phức tạp, một hệ thống nhúng hay một ứng dụng — các công việc thường xuyên có thể dự đoán được có thể được thực hiện theo yêu cầu.

Đối với trường hợp của tôi, tôi muốn ứng dụng web tự động triển khai tới VPS bất cứ khi nào tôi đẩy các thay đổi lên chi nhánh Github chính. Do đó, điều này sẽ tiết kiệm rất nhiều thời gian phát triển trong quá trình này.

Các giải pháp thay thế

Có các giải pháp thay thế và không hối hả cho vấn đề này, chẳng hạn như nền tảng ứng dụng VercelDigitalOcean . Tuy nhiên, một người có thể đi theo con đường của tôi nếu:

  1. Bạn muốn hiểu rõ hơn về các hành động trên Github
  2. Tìm hiểu thêm về docker
  3. Đối với trường hợp của Vercel, khách hàng hoặc tổ chức của bạn có thể muốn giữ các ứng dụng của họ trong một nền tảng trung tâm để quản lý dễ dàng hơn.

Điều kiện tiên quyết

Xin lưu ý rằng một số liên kết dưới đây là liên kết liên kết và bạn không phải trả thêm phí. Biết rằng tôi chỉ giới thiệu các sản phẩm, công cụ và dịch vụ học tập mà cá nhân tôi đã sử dụng và tin rằng thực sự hữu ích. Trên hết, tôi sẽ không bao giờ ủng hộ việc mua thứ gì đó mà bạn không đủ khả năng chi trả hoặc bạn chưa sẵn sàng thực hiện.

  1. Một tài khoản Github
  2. Một máy chủ riêng ảo. Tôi đã sử dụng giọt DigitalOcean chạy Ubuntu 20.04 LTS. Đăng ký bằng liên kết giới thiệu của tôi và nhận $ 100 tín dụng có giá trị trong 60 ngày.

Tạo ứng dụng next.js

Chúng tôi sẽ sử dụng npx để tạo ứng dụng next.js tiêu chuẩn

npx create-next-app meta-news && cd meta-news

Khi chúng ta đang ở trong thư mục dự án, chúng ta sẽ cài đặt một số phụ thuộc cho mục đích trình diễn

yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4 axios

Chúng tôi cũng sẽ khai báo các biến môi trường bên trong .env.localtệp. Sau đó, chúng tôi có thể tham chiếu các biến này từ ứng dụng của chúng tôi như vậyprocess.env.NEXT_PUBLIC_VARIABLE_NAME

NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api
NEXT_PUBLIC_META_API_KEY=your_api_key

Các biến này chỉ dành cho mục đích trình diễn. Vì vậy, chúng tôi sẽ không thực sự tham chiếu chúng trong ứng dụng của mình. Ví dụ về địa điểm bạn sẽ gọi chúng là khi khởi tạo phiên bản axios hoặc đặt id google analytics và bạn không muốn cam kết điều đó với hệ thống kiểm soát phiên bản.

Hãy chạy thử nhanh. Ứng dụng sẽ được chạy localhost:3000nếu mọi thứ được thiết lập đúng cách.

yarn start

Tài liệu hóa ứng dụng

Docker là một công cụ mã nguồn mở tự động hóa việc triển khai ứng dụng bên trong vùng chứa phần mềm. giống như máy ảo, chỉ di động hơn, thân thiện với tài nguyên hơn và phụ thuộc nhiều hơn vào hệ điều hành máy chủ. 

Chúng tôi sẽ thêm một Dockerfile vào gốc dự án bằng cách chạy touch Dockerfiletrong CLI.

# Install dependencies only when needed
FROM node:alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update && apk add --no-cache libc6-compat && apk add git
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --immutable


# Rebuild the source code only when needed
FROM node:alpine AS builder
# add environment variables to client code
ARG NEXT_PUBLIC_BACKEND_URL
ARG NEXT_PUBLIC_META_API_KEY


ENV NEXT_PUBLIC_BACKEND_URL=$NEXT_PUBLIC_BACKEND_URL
ENV NEXT_PUBLIC_META_API_KEY=$NEXT_PUBLIC_META_API_KEY

WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
ARG NODE_ENV=production
RUN echo ${NODE_ENV}
RUN NODE_ENV=${NODE_ENV} yarn build

# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration. 
# Copy all necessary files used by nex.config as well otherwise the build will fail

COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/pages ./pages

USER nextjs

# Expose
EXPOSE 3000

# 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.
ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"]

Chúng tôi đang chạy một bản dựng nhiều giai đoạn cho việc triển khai này. Chú ý các từ khóa ARG và ENV? Đó là cách chúng tôi chuyển các biến môi trường của mình sang mã khách hàng vì chúng tôi sẽ không có quyền truy cập vào bất kỳ .envtệp nào trong vùng chứa. Thêm về điều này sau.

Sau đó, chúng tôi sẽ xây dựng và gắn thẻ hình ảnh của mình

docker build --build-arg NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api --build-arg NEXT_PUBLIC_META_API_KEY=your_api_key -t meta-news .

Quá trình này có thể mất một lúc tùy thuộc vào kết nối internet và thông số kỹ thuật phần cứng của bạn. Khi mọi thứ đã kiểm tra xong, hãy chạy vùng chứa

docker run -p 3000:3000 meta-news

Khởi chạy trình duyệt của bạn và ứng dụng của bạn sẽ có thể truy cập được tại ' http: // localhost: 3000 ' 🎉

Thiết lập các hành động trên Github

GitHub Actions là một nền tảng tích hợp liên tục và phân phối liên tục (CI / CD) cho phép bạn tự động hóa quy trình xây dựng, thử nghiệm và triển khai của mình. Bạn có thể tạo quy trình công việc xây dựng và kiểm tra mọi yêu cầu kéo đến kho lưu trữ của mình hoặc triển khai các yêu cầu kéo đã hợp nhất vào sản xuất.

Để biết thêm về nền tảng tuyệt vời này, hãy truy cập trang hướng dẫn chính thức của họ

Chúng tôi sẽ tạo quy trình làm việc đầu tiên của mình bằng cách chạy các lệnh sau trong CLI. Bạn có thể sử dụng GUI nếu bạn không cảm thấy thoải mái với dòng lệnh 🤗.

mkdir .github && mkdir ./github/workflow && touch ./github/workflows/deploy.yml && nano ./github/workflows/deploy.yml

Điền vào tệp deploy.yml với các giá trị sau.

name: Build and Deploy

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    container: node:14

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Build and Publish to Github Packages Registry
        uses: elgohr/Publish-Docker-Github-Action@master
        env:
          NEXT_PUBLIC_BACKEND_URL: ${{ secrets.APP_NEXT_PUBLIC_BACKEND_URL }}
          NEXT_PUBLIC_META_API_KEY: ${{ secrets.APP_NEXT_PUBLIC_META_API_KEY }}
        with:
          name: my_github_username/my_repository_name/my_image_name
          registry: ghcr.io
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets. GITHUB_TOKEN }}
          dockerfile: Dockerfile
          buildargs: NEXT_PUBLIC_BACKEND_URL,NEXT_PUBLIC_META_API_KEY
          tags: latest

      - name: Deploy package to digitalocean
        uses: appleboy/ssh-action@master
        env:
          GITHUB_USERNAME: ${{ secrets.USERNAME }}
          GITHUB_TOKEN: ${{ secrets. GITHUB_TOKEN }}
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          port: ${{ secrets.DEPLOY_PORT }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          envs: GITHUB_USERNAME, GITHUB_TOKEN
          script: |
            docker login ghcr.io -u $GITHUB_USERNAME -p $GITHUB_TOKEN
            docker pull ghcr.io/my_github_username/my_repository_name/my_image_name:latest
            docker stop containername
            docker system prune -f
            docker run --name containername -dit -p 3000:3000 ghcr.io/my_github_username/my_repository_name/my_image_name:latest

Bạn có thể nhận thấy hành động của chúng tôi rất bí mật 😂. Đừng lo lắng, điều này được thực hiện có chủ ý để bảo vệ thông tin nhạy cảm của bạn khỏi những con mắt tò mò. Chúng là các biến môi trường được mã hóa mà bạn (chủ sở hữu repo) tạo cho repo sử dụng các hành động Github.

Một điều cần lưu ý là GITHUB_TOKENbí mật được tạo tự động cho chúng ta khi chạy hành động.

Để tạo bí mật, hãy chuyển đến kho lưu trữ> cài đặt> thanh bên trái> bí mật secret_creation

Để có hướng dẫn chuyên sâu, hãy xem hướng dẫn này .

Những bí mật được mong đợi trên Github là

  APP_NEXT_PUBLIC_BACKEND_URL - live backend server url
  APP_NEXT_PUBLIC_META_API_KEY - prod api key to thirdparty integration
  DEPLOY_HOST - IP to Digital Ocean (DO) droplet
  DEPLOY_KEY - SSH secret (pbcopy < ~/.ssh/id_rsa) and the public key should be added to `.ssh/authorized_keys` in server
  DEPLOY_PORT - SSH port (22)
  DEPLOY_USER  - User on droplet
  USERNAME - Your Github username

Nhấc lên 🚀

Đẩy đến nhánh chính

git add -A
git commit -m "Initial commit"
git push origin main

Nếu mọi thứ chạy như mong đợi, bạn sẽ thấy dấu kiểm màu xanh lá cây trong kho lưu trữ của mình với các bước xây dựng đã hoàn tất.

Github_actions_deploy

Từ đó, bạn có thể thiết lập proxy ngược, chẳng hạn như nginx trong máy chủ của mình và trỏ máy chủ tới " http: // localhost: 3000" .

Yay! 🥳 chúng tôi đã tạo thành công một đường dẫn phân phối liên tục và hy vọng bây giờ bạn sẽ tập trung vào mã thay vì cơ sở hạ tầng.

Nguồn: https://lewiskori.com

#nextjs #next #github #githubaction #docker

NBB: Ad-hoc CLJS Scripting on Node.js

Nbb

Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.

Status

Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.

Requirements

Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).

Usage

Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'
6

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs

Macros

Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)
                                        body))))
            body
            binding-pairs)))

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "https://clojure.org")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "https://clojure.org")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.

Dependencies

NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.

Classpath

To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [foo.bar :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"

Reagent

Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink

ink-demo.cljs:

(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))

Promesa

Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
  (js/Promise.
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
  []
  (p/do!
   (println "Doing stuff which takes a while")
   (sleep 1000)
   1))

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3

Also see API docs.

Js-interop

Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.

Examples

See the examples directory for small examples.

Also check out these projects built with nbb:

API

See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.

Build

Prequisites:

  • babashka >= 0.4.0
  • Clojure CLI >= 1.10.3.933
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb 
License: EPL-1.0

#node #javascript

Implementar app Next.js en un VPS usando acciones de Github y Docker

Recientemente, tuve que implementar un proyecto en una gota de DigitalOcean. Una de las características que realmente quería para este proyecto en particular era una canalización de entrega continua.

El sitio web de entrega continua define esto como la capacidad de conseguir cambios de todo tipo, incluidas nuevas funciones, cambios de configuración, corrección de errores y experimentos, en producción o en manos de los usuarios, de forma segura y rápida de forma sostenible.

El objetivo es realizar implementaciones, ya sea de un sistema distribuido a gran escala, un entorno de producción complejo, un sistema integrado o una aplicación, asuntos de rutina predecibles que se pueden realizar a pedido.

En mi caso, quería que la aplicación web se implementara automáticamente en el VPS cada vez que enviaba cambios a la rama principal de Github. En consecuencia, esto ahorraría mucho tiempo de desarrollo en el proceso.

Soluciones alternativas

Existen soluciones alternativas y sencillas para esto, como la plataforma de aplicaciones Vercel y DigitalOcean . Sin embargo, uno puede tomar mi ruta si:

  1. Quieres comprender mejor las acciones de Github
  2. Más información sobre Docker
  3. En el caso de Vercel, es posible que su cliente u organización desee mantener sus aplicaciones en una plataforma central para facilitar la administración.

Prerrequisitos

Tenga en cuenta que algunos de los enlaces a continuación son enlaces de afiliados y sin costo adicional para usted. Sepa que solo recomiendo productos, herramientas y servicios de aprendizaje que he usado personalmente y creo que son realmente útiles. Sobre todo, nunca abogaría por comprar algo que no pueda pagar o que no esté listo para implementar.

  1. Una cuenta de Github
  2. Un servidor privado virtual. Usé una gota de DigitalOcean con Ubuntu 20.04 LTS. Regístrese con mi enlace de referencia y obtenga $ 100 en crédito válido por 60 días.

Crear la aplicación next.js

Usaremos npx para crear una aplicación next.js estándar

npx create-next-app meta-news && cd meta-news

Una vez que estemos dentro del directorio del proyecto, instalaremos algunas dependencias con fines de demostración.

yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4 axios

También declararemos variables de entorno dentro del .env.localarchivo. Luego podemos hacer referencia a estas variables desde nuestra aplicación asíprocess.env.NEXT_PUBLIC_VARIABLE_NAME

NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api
NEXT_PUBLIC_META_API_KEY=your_api_key

Estas variables son solo para fines de demostración. Por lo tanto, realmente no los haremos referencia dentro de nuestra aplicación. Un ejemplo de un lugar al que los llamaría es cuando crea una instancia de axios o establece una identificación de Google Analytics y no desea comprometer eso con el sistema de control de versiones.

Hagamos una prueba rápida. La aplicación debería estar ejecutándose localhost:3000si todo está configurado correctamente.

yarn start

Dockerizar la aplicación

Docker es una herramienta de código abierto que automatiza la implementación de una aplicación dentro de un contenedor de software. que son como máquinas virtuales, solo que más portátiles, más fáciles de usar y más dependientes del sistema operativo host. Para obtener información detallada sobre el funcionamiento de Docker, recomiendo leer este artículo y para aquellos que no se sientan cómodos leyendo publicaciones largas, esta serie de tutoriales en YouTube fue especialmente útil para presentarme los conceptos de Docker.

Agregaremos un Dockerfile a la raíz del proyecto ejecutándolo touch Dockerfiledentro de la CLI.

# Install dependencies only when needed
FROM node:alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update && apk add --no-cache libc6-compat && apk add git
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --immutable


# Rebuild the source code only when needed
FROM node:alpine AS builder
# add environment variables to client code
ARG NEXT_PUBLIC_BACKEND_URL
ARG NEXT_PUBLIC_META_API_KEY


ENV NEXT_PUBLIC_BACKEND_URL=$NEXT_PUBLIC_BACKEND_URL
ENV NEXT_PUBLIC_META_API_KEY=$NEXT_PUBLIC_META_API_KEY

WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
ARG NODE_ENV=production
RUN echo ${NODE_ENV}
RUN NODE_ENV=${NODE_ENV} yarn build

# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration. 
# Copy all necessary files used by nex.config as well otherwise the build will fail

COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/pages ./pages

USER nextjs

# Expose
EXPOSE 3000

# 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.
ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"]

Estamos ejecutando una compilación de varias etapas para esta implementación. ¿Observa las palabras clave ARG y ENV? Así es como pasamos nuestras variables de entorno al código del cliente, ya que no tendremos acceso a ningún .envarchivo dentro del contenedor. Más sobre esto más adelante.

Luego, crearemos y etiquetaremos nuestra imagen.

docker build --build-arg NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api --build-arg NEXT_PUBLIC_META_API_KEY=your_api_key -t meta-news .

Esto puede llevar un tiempo dependiendo de su conexión a Internet y las especificaciones del hardware. Una vez que todo salga, ejecute el contenedor

docker run -p 3000:3000 meta-news

Inicie su navegador y su aplicación debería ser accesible en ' http: // localhost: 3000 ' 🎉

Configurar acciones de Github

GitHub Actions es una plataforma de integración continua y entrega continua (CI / CD) que le permite automatizar su canalización de compilación, prueba e implementación. Puede crear flujos de trabajo que compilen y prueben cada solicitud de extracción en su repositorio o implementar solicitudes de extracción combinadas en producción.

Para obtener más información sobre esta maravillosa plataforma, diríjase a su página oficial de tutoriales.

Crearemos nuestro primer flujo de trabajo ejecutando los siguientes comandos en la CLI. Puede usar la GUI si no se siente cómodo con la línea de comandos 🤗.

mkdir .github && mkdir ./github/workflow && touch ./github/workflows/deploy.yml && nano ./github/workflows/deploy.yml

Complete el archivo deploy.yml con los siguientes valores.

name: Build and Deploy

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    container: node:14

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Build and Publish to Github Packages Registry
        uses: elgohr/Publish-Docker-Github-Action@master
        env:
          NEXT_PUBLIC_BACKEND_URL: ${{ secrets.APP_NEXT_PUBLIC_BACKEND_URL }}
          NEXT_PUBLIC_META_API_KEY: ${{ secrets.APP_NEXT_PUBLIC_META_API_KEY }}
        with:
          name: my_github_username/my_repository_name/my_image_name
          registry: ghcr.io
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets. GITHUB_TOKEN }}
          dockerfile: Dockerfile
          buildargs: NEXT_PUBLIC_BACKEND_URL,NEXT_PUBLIC_META_API_KEY
          tags: latest

      - name: Deploy package to digitalocean
        uses: appleboy/ssh-action@master
        env:
          GITHUB_USERNAME: ${{ secrets.USERNAME }}
          GITHUB_TOKEN: ${{ secrets. GITHUB_TOKEN }}
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          port: ${{ secrets.DEPLOY_PORT }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          envs: GITHUB_USERNAME, GITHUB_TOKEN
          script: |
            docker login ghcr.io -u $GITHUB_USERNAME -p $GITHUB_TOKEN
            docker pull ghcr.io/my_github_username/my_repository_name/my_image_name:latest
            docker stop containername
            docker system prune -f
            docker run --name containername -dit -p 3000:3000 ghcr.io/my_github_username/my_repository_name/my_image_name:latest

Puede que hayas notado que nuestras acciones son muy reservadas 😂. No se preocupe, esto se hace deliberadamente para proteger su información confidencial de miradas indiscretas. Son variables de entorno cifradas que usted (propietario del repositorio) crea para un repositorio que utiliza acciones de Github.

Una cosa a tener en cuenta es que el GITHUB_TOKENsecreto se crea automáticamente para nosotros cuando ejecutamos la acción.

Para crear secretos, vaya a su repositorio> configuración> barra lateral izquierda> secretos secrets_creation

Para obtener un tutorial detallado, consulte esta guía .

Los secretos esperados de Github son

  APP_NEXT_PUBLIC_BACKEND_URL - live backend server url
  APP_NEXT_PUBLIC_META_API_KEY - prod api key to thirdparty integration
  DEPLOY_HOST - IP to Digital Ocean (DO) droplet
  DEPLOY_KEY - SSH secret (pbcopy < ~/.ssh/id_rsa) and the public key should be added to `.ssh/authorized_keys` in server
  DEPLOY_PORT - SSH port (22)
  DEPLOY_USER  - User on droplet
  USERNAME - Your Github username

Levantar 🚀

Empuje a la rama principal

git add -A
git commit -m "Initial commit"
git push origin main

Si todo se ejecuta como se esperaba, debería ver una marca de verificación verde en su repositorio con los pasos de compilación completos.

Github_actions_deploy

Desde allí, puede configurar un proxy inverso como nginx dentro de su servidor y apuntar el host a " http: // localhost: 3000" .

¡Yay! 🥳 Hemos creado con éxito una canalización de entrega continua y, con suerte, ahora se concentrará en el código en lugar de la infraestructura.

#nextjs #next #github #docker 

Landen  Brown

Landen Brown

1626066480

Next.js CI / CD on AWS with GitHub Actions

In this video, I walk through how to set up a CI / CD pipeline on AWS for a Next.js app using GitHub Actions and the Serverless Framework.

Blog post: https://dev.to/dabit3/next-js-ci-cd-on-aws-with-github-actions-3502
Code: https://github.com/dabit3/next-serverless-github-actions

#github #aws #next.js #next #ci / cd

Eva  Murphy

Eva Murphy

1625674200

Google analytics Setup with Next JS, React JS using Router Events - 14

In this video, we are going to implement Google Analytics to our Next JS application. Tracking page views of an application is very important.

Google analytics will allow us to track analytics information.

Frontend: https://github.com/amitavroy/video-reviews
API: https://github.com/amitavdevzone/video-review-api
App link: https://video-reviews.vercel.app

You can find me on:
Twitter: https://twitter.com/amitavroy7​
Discord: https://discord.gg/Em4nuvQk

#next js #js #react js #react #next #google analytics