Nasazení aplikací Next.js na VPS pomocí akcí Github a Docker

Nedávno jsem musel nasadit projekt do kapky DigitalOcean. Jednou z funkcí, kterou jsem pro tento konkrétní projekt opravdu chtěl, byl kanál průběžného doručování.

Web s nepřetržitým doručováním to definuje jako

Cílem je zajistit, aby nasazení – ať už rozsáhlého distribuovaného systému, složitého produkčního prostředí, vestavěného systému nebo aplikace – bylo předvídatelné, rutinní záležitosti, které lze provádět na vyžádání.

V mém případě jsem chtěl, aby se webová aplikace automaticky nasadila na VPS, kdykoli jsem posunul změny do hlavní větve Github. To by následně ušetřilo mnoho času na vývoj v procesu.

Alternativní řešení

Existují alternativní a bezproblémová řešení, jako je platforma aplikací Vercel a DigitalOcean. Nicméně jeden může použít mou trasu, pokud:

  1. Chcete lépe porozumět akcím Github
  2. Další informace o ukotvitelném panelu
  3. V případě Vercelu může váš klient nebo organizace chtít ponechat své aplikace na centrální platformě pro snadnější správu.

Předpoklady

Vezměte prosím na vědomí, že některé z níže uvedených odkazů jsou affiliate odkazy a nejsou pro vás žádné další náklady. Vězte, že doporučuji pouze produkty, nástroje a výukové služby, které jsem osobně použil a věřím, že jsou skutečně užitečné. Především bych nikdy neobhajoval nákup něčeho, co si nemůžete dovolit nebo co nejste připraveni implementovat.

  1. Účet Github
  2. Virtuální soukromý server. Použil jsem droplet DigitalOcean se systémem Ubuntu 20.04 LTS. Zaregistrujte se pomocí mého doporučujícího odkazu a získejte kredit 100 $ platný po dobu 60 dnů.

Vytvořte aplikaci next.js

npx použijeme k vytvoření standardní aplikace next.js

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

Jakmile jsme v adresáři projektu, nainstalujeme několik závislostí pro demonstrační účely

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

V .env.local také deklarujeme proměnné prostředí soubor. Na tyto proměnné pak můžeme odkazovat z naší aplikace jako process.env.NEXT_PUBLIC_VARIABLE_NAME

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

Tyto proměnné slouží pouze pro demonstrační účely. V naší aplikaci na ně tedy ve skutečnosti nebudeme odkazovat. Příkladem místa, které byste je nazvali, je vytváření instance instance axios nebo nastavení ID služby Google Analytics, které nechcete zadávat systému správy verzí.

Udělejme rychlý zkušební provoz. Aplikace by měla běžet na localhost:3000 pokud je vše správně nastaveno.

yarn start

Ukotvení aplikace

Docker je open-source nástroj, který automatizuje nasazení aplikace v softwarovém kontejneru. které jsou jako virtuální stroje, pouze jsou přenosnější, šetrnější ke zdrojům a více závislé na hostitelském operačním systému. Chcete-li získat podrobné informace o fungování dockeru, doporučuji přečíst si tento článek a těm, kteří se nebaví číst dlouhé příspěvky, byla tato série tutoriálů na youtube obzvláště užitečná, když mě seznámila s koncepty dockeru.

Spuštěním přidáme Dockerfile do kořenového adresáře projektu
touch Dockerfile v rámci 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"]

Pro toto nasazení spouštíme vícefázové sestavení.
Všimli jste si klíčových slov ARG a ENV? Takto předáváme naše proměnné prostředí do klientského kódu, protože nebudeme mít přístup k žádnému .env soubory v kontejneru. Více o tom později.

Poté vytvoříme a označíme náš obrázek

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 .

To může chvíli trvat v závislosti na vašem připojení k internetu a hardwarových specifikacích.
Jakmile se vše zkontroluje, spusťte kontejner

docker run -p 3000:3000 meta-news

Spusťte prohlížeč a vaše aplikace by měla být dostupná na adrese 'http://localhost:3000' 🎉

Nastavit akce Github

GitHub Actions je platforma pro nepřetržitou integraci a nepřetržité doručování (CI/CD), která vám umožňuje automatizovat vaše sestavování, testování a nasazování. Můžete vytvořit pracovní postupy, které vytvoří a otestují každý požadavek na stažení do vašeho úložiště, nebo nasadit sloučené požadavky na stažení do produkce.

Pro více informací o této úžasné platformě přejděte na jejich oficiální výukovou stránku

Náš první pracovní postup vytvoříme spuštěním následujících příkazů v CLI. Pokud vám nevyhovuje příkazový řádek, můžete použít GUI 🤗.

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

Naplňte soubor deploy.yml následujícími hodnotami.

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

Možná jste si všimli, že naše akce jsou velmi tajné 😂. Nebojte se, je to záměrně provedeno, aby byly vaše citlivé informace chráněny před zvědavýma očima. Jsou to zašifrované proměnné prostředí, které vy (vlastník úložiště) vytvoříte pro úložiště, které používá akce Github.

Chcete-li vytvořit tajemství, přejděte do svého úložiště> nastavení> levý postranní panel> tajemství

Podrobný návod naleznete v této příručce.

Očekávaná tajemství Github jsou

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

Zvedněte se 🚀

Zatlačte na hlavní větev

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

Pokud vše běží podle očekávání, měli byste ve svém úložišti vidět zelenou značku zaškrtnutí po dokončení kroků sestavení.

Odtud můžete na svém serveru nastavit reverzní proxy, jako je nginx, a nasměrovat hostitele na "http://localhost:3000".

Hurá!🥳 úspěšně jsme vytvořili kontinuální zásobovací kanál a doufejme, že se nyní budete soustředit na kód místo infrastruktury.

Pokud máte nějaké dotazy, neváhejte mě kontaktovat na Twitteru.
Pokud máte zpětnou vazbu nebo další vstup, napište komentář níže.

Nestydatá zástrčka

Potřebujete hodně dolovat data?

Scraper API je startup, který se specializuje na strategie, které vám uleví od zablokování vaší IP adresy při odstraňování webu. Využívají rotaci IP, takže se můžete vyhnout detekci. Může se pochlubit více než 20 miliony IP adres a neomezenou šířkou pásma.

Kromě toho vám poskytují práci s CAPTCHA a také umožňují bezhlavý prohlížeč, takže budete vypadat jako skutečný uživatel a nebudete detekováni jako webový škrabák. Má integraci pro populární platformy, jako je python, node.js, bash, PHP a ruby. Jediné, co musíte udělat, je zřetězit svou cílovou adresu URL s jejich koncovým bodem API v požadavku HTTP get a poté pokračovat jako normálně na jakémkoli webovém škrabáku. Nevíte, jak webscrape?
Nebojte se, toto téma jsem obsáhle probral v sérii webscraping. Vše zcela zdarma!

Pomocí mého odkazu na doporučení scraperapi a promo kódu lewis10 získáte 10% slevu na svůj první nákup!! Vždy můžete začít s jejich velkorysým bezplatným plánem a upgradovat, když to bude potřeba.