DeployHQ를 사용하여 React Watchlist Tracker 앱을 프로덕션에 배포

Susan Sarandon
풀어 주다: 2024-11-02 16:28:29
원래의
377명이 탐색했습니다.

오늘의 튜토리얼에서는 서버를 자체 호스팅하고 설정하는 방법을 알아보겠습니다. 이를 통해 모든 웹 애플리케이션을 온라인으로 배포할 수 있습니다. 온라인으로 애플리케이션을 배포하는 방법에는 몇 가지가 있습니다. 두 가지 전략에는 VPS, Virtual Private Server 및 Vercel, Netlify, WordPress, GoDaddy 등과 같은 공유 관리형 호스팅 플랫폼을 사용하는 것이 포함됩니다.

VPS는 관리형 호스팅 플랫폼과 어떻게 비교됩니까?

VPS는 다른 사용자와 물리적으로 공유되는 서버에서 전용 서버 리소스를 제공하는 가상 머신입니다. 이는 실제로 웹사이트 및 애플리케이션을 위한 중간 계층 호스팅으로, 공유 호스팅에 비해 더 많은 제어 및 사용자 정의 기능을 제공합니다. 일부 VPS 호스팅 플랫폼의 예로는 Hetzner, Akamai, Vultr, Cloudcone 등이 있습니다.

반면에 관리형 호스팅 플랫폼을 사용하면 웹사이트를 호스팅하는 것이 더 쉽습니다. 이러한 플랫폼은 웹 애플리케이션 구축 및 배포를 위한 도구, 작업 흐름 및 인프라를 제공합니다. 이러한 플랫폼은 자체적으로 로드 밸런싱과 캐싱을 수행합니다. 추가 구성 없이 신속하게 웹 애플리케이션을 구축하고 배포하려는 모든 개발자에게 적합합니다.

언제나 그렇듯이 각 전략을 사용하는 데에는 장단점이 있습니다. 가장 중요한 차이점 중 하나는 VPS를 사용할 때 전체 서버와 함께 제공되는 모든 것을 제어할 수 있으므로 완전한 사용자 정의가 가능하다는 것입니다. 이는 개발 환경, 방화벽 규칙, 호스팅 등을 설정하는 것을 의미합니다. 이러한 사용자 정의는 복잡성을 가중시키고 모든 작업을 직접 수행하므로 더 많은 기술 지원이 필요합니다. 관리형 호스팅 플랫폼은 대부분의 도구가 사전 설정되어 있고 지원 및 문서를 제공하므로 초보자에게 매우 친숙하다는 점을 알아야 합니다. 이미 설정 및 관리되기 때문에 VPS에서 얻을 수 있는 높은 수준의 사용자 정의를 얻을 수 없습니다.

또한 가격 차이도 고려해야 합니다. 대부분의 VPS는 유료이지만 서버를 완전히 사용자 정의하여 필요에 따라 가볍거나 강력하게 만들 수 있습니다. 성능 측면에서 이는 관리형 호스팅 플랫폼보다 한 단계 더 뛰어납니다. 후자에는 무료 요금제가 있으므로 차이점을 살펴봐야 합니다. 일반 소비자는 무료이기 때문에 관리형 호스팅 플랫폼을 원할 것입니다. 그러나 더 많은 기능을 원하고 하나의 애플리케이션 내에서 고급 애플리케이션을 호스팅하고 싶다면 VPS를 선택하세요.

Watchlist Tracker 앱의 기능 개요

저희 Watchlist Tracker 애플리케이션은 영화 관심 목록을 추적하는 데 사용되는 간단하지만 강력한 풀 스택 CRUD 애플리케이션입니다. 또한 이 애플리케이션을 통해 사용자는 보고 싶은 영화나 시리즈를 쉽게 추가하고, 영화 제목이나 등급을 업데이트하고, 이미 봤거나 더 이상 추적하고 싶지 않은 영화를 제거할 수 있습니다. 이 앱은 사용자가 관심 있는 영화를 정리하고 따라갈 수 있는 간단한 인터페이스에 대한 액세스를 제공하므로 관심 목록을 항상 확인하고 싶은 영화 매니아에게 적합한 도구입니다.

아래에서 앱이 어떻게 보이는지 확인할 수 있습니다.

홈페이지

Deploying a React Watchlist Tracker App to Production Using DeployHQ
영화/시리즈 항목 페이지

Deploying a React Watchlist Tracker App to Production Using DeployHQ

새 항목 추가 페이지

Deploying a React Watchlist Tracker App to Production Using DeployHQ

Vite Watchlist Tracker 앱 설정

전제 조건

애플리케이션 구축을 시작하기 전에 개발 환경을 설정하고 작동시키는 것이 중요합니다. 컴퓨터에 다음이 설치되어 있는지 확인하세요.

  • VS Code - 코드 편집기
  • Node.js 및 npm - 크로스 플랫폼, 오픈 소스 JavaScript 런타임 환경
  • GIT - 분산 버전 관리 시스템
  • Bun - JavaScript 런타임, 패키지 관리자, 테스트 실행기 및 번들러
  • Vite -  현대적인 JavaScript 빌드 도구
  • SQLite - 휴대용 데이터베이스
  • PM2 - JavaScript 런타임 Node.js용 프로세스 관리자입니다.
  • Postman, Thunder Client 또는 대안과 같은 API 테스트 도구

명령줄 사용과 함께 도움이 될 수 있는 뛰어난 VS Code용 무료 SQLite 뷰어 확장이 있습니다. 데이터베이스 내부의 데이터를 빠르게 보는 데 좋습니다.

기술 스택

저희 Watchlist Tracker 앱은 뛰어난 개발 경험을 제공하는 매우 현대적이고 미래 지향적인 기술 스택을 사용하여 구축되었습니다. Bun, Hono, Vite, TanStack, Hetzner 및 DeployHQ와 같은 도구를 사용하기로 선택한 이유는 모두 개발자에게 최신 빌드 환경을 제공하기 때문입니다.

이 프로젝트에서 사용할 기술을 살펴보겠습니다.

백엔드

  • Bun: Bun은 Node.js와 매우 유사한 고속 JavaScript 런타임 환경입니다. 그러나 개발자 경험과 전반적인 속도는 훨씬 더 빠릅니다. Bun을 사용하면 개발자가 코드를 빠르게 실행할 수 있으며 테스트 실행기 및 번들러와 같이 개발자가 기대하는 많은 기능에 대한 셀 수 없이 많은 내장 지원이 제공됩니다.
  • Hono: Hono는 Bun과 원활하게 작동하는 경량 웹 프레임워크이므로 빠른 API를 구축하려는 경우에 적합합니다. Hono의 간단한 접근 방식을 통해 개발자는 많은 시간과 높은 복잡성을 필요로 하지 않는 애플리케이션 로직을 만들 수 있습니다.
  • Prisma ORM: Prisma ORM은 데이터베이스 관리를 단순화하는 강력하고 현대적인 객체 관계형 매핑 도구입니다. 유형이 안전하므로 데이터베이스와 상호 작용하면 데이터 무결성이 보장되고 런타임 시 오류가 줄어듭니다.
  • SQLite: SQLite는 중소 규모 프로젝트에 탁월한 경량 파일 기반 데이터베이스입니다. 설정이 빠르며 속도가 필요하고 복잡성이 거의 없는 프로젝트 작업에 가장 적합합니다.

프런트엔드

  • Vite: Vite는 다양한 유형의 JavaScript 애플리케이션을 만드는 데 사용할 수 있는 차세대 프런트 엔드 빌드 도구입니다. 속도를 위해 설계되었으며 React, Vue 및 기타 JavaScript 프레임워크에서 프로젝트를 빌드하는 데 사용할 수 있습니다.
  • Tailwind CSS: Tailwind CSS는 개발자가 하위 수준 유틸리티 클래스를 사용하여 사용자 인터페이스를 빠르게 구축할 수 있도록 하는 유틸리티 우선 CSS 프레임워크입니다. 다양한 사용자 정의가 가능하며 반응형 웹사이트를 만드는 데 매우 좋습니다.
  • TanStack Router: TanStack Router는 React 애플리케이션을 위한 유연하고 강력한 라우팅 솔루션입니다. 중첩된 경로 및 페이지 전환과 같은 고급 기능을 지원하므로 단일 페이지 애플리케이션 내에서 라우팅을 설정하기 위한 탁월한 최신 옵션이 됩니다.

호스팅 및 배포

  • Hetzner: Hetzner는 우수한 성능과 저렴한 옵션으로 잘 알려진 인기 있고 안정적인 클라우드 호스팅 제공업체입니다. Hetzner의 인프라를 사용하면 전 세계 사용자가 액세스하는 앱의 성능을 유지하면서 액세스 가능한 상태를 유지할 수 있습니다.
  • DeployHQ: DeployHQ는 배포 프로세스를 단순화할 수 있는 플랫폼입니다. 이를 통해 개발자는 Git, SVN 및 Mercurial 저장소의 웹사이트를 자체 서버에 배포할 수 있습니다. 이 프로세스는 프로덕션 환경에서 앱의 코드가 항상 최신 상태를 유지하고 보안에 더 나은 안정적이고 자동화된 배포 프로세스가 있음을 보장합니다.

Watchlist Tracker 앱 구축

자, 이제 앱 구축을 시작하겠습니다! 이 섹션은 두 부분으로 나누어집니다. 먼저 백엔드를 만들고 그 다음 프런트엔드를 만듭니다.

백엔드 구축

watchlist-tracker-app이라는 프로젝트를 위해 컴퓨터에 새 폴더를 만든 다음 그 폴더에 CD를 넣어주세요. 이제 여기에 표시된 다음 명령을 사용하여 백엔드용 새 Bun 프로젝트를 만듭니다.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 프로젝트가 설정되었습니다. 종속성을 설치하고, 구성 작업을 하고, 서버 코드를 작성하기만 하면 됩니다. 코드 편집기에서 프로젝트를 엽니다.

이제 다음 명령을 사용하여 서버에 대한 종속성을 설치합니다.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

런타임 환경으로 Bun, API 서버로 Hono, 데이터베이스 ORM으로 Prisma를 추가했습니다.

이제 다음 명령을 사용하여 Prisma ORM 및 SQLite를 설정해 보겠습니다.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Prisma는 이제 우리 서버에서 작동하도록 구성되어야 하므로 다음 단계에서는 데이터베이스 스키마를 구성하겠습니다. 따라서 prisma/schema.prisma의 모든 코드를 다음 코드로 바꾸세요.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

데이터베이스 스키마가 설정되었으며 SQLite 데이터베이스 파일에 연결되었습니다.

이제 다음 마이그레이션 스크립트를 실행하여 SQLite 데이터베이스를 생성하세요.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

좋습니다. 이제 Prisma 마이그레이션이 완료되었으므로 API 파일 작업을 할 수 있습니다.

이제 Hono를 사용할 기본 API 파일을 만들어 보겠습니다. src/server.ts 내부의 서버 파일로 이동하여 다음 코드를 파일에 추가하세요.

import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { PrismaClient } from '@prisma/client';

const app = new Hono();

app.use(cors());

const prisma = new PrismaClient();

app.get('/watchlist', async (c) => {
  const items = await prisma.watchlistItem.findMany();
  return c.json(items);
});

app.get('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const item = await prisma.watchlistItem.findUnique({
    where: { id: Number(id) },
  });
  return item ? c.json(item) : c.json({ error: 'Item not found' }, 404);
});

app.post('/watchlist', async (c) => {
  const data = await c.req.json();
  const newItem = await prisma.watchlistItem.create({ data });
  return c.json(newItem);
});

app.put('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const data = await c.req.json();
  const updatedItem = await prisma.watchlistItem.update({
    where: { id: Number(id) },
    data,
  });
  return c.json(updatedItem);
});

app.delete('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  await prisma.watchlistItem.delete({ where: { id: Number(id) } });
  return c.json({ success: true });
});

Bun.serve({
  fetch: app.fetch,
  port: 8000,
});

console.log('Server is running on http://localhost:8000');

export default app;
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 파일을 사용하면 서버가 Bun과 Hono를 사용하고 포트 8000에서 실행됩니다. 또한 관심 목록 추적기에 대한 모든 CRUD(생성, 읽기, 업데이트, 삭제) 엔드포인트가 있습니다. 모든 데이터는 SQLite 데이터베이스에 저장됩니다.

남은 것은 서버용 실행 및 빌드 스크립트를 만드는 것뿐입니다. 그런 다음 엔드포인트를 테스트하여 예상대로 작동하는지 확인할 수 있습니다. package.json 파일에 다음 실행 스크립트를 추가하세요.

"scripts": {
    "start": "bun run src/server.ts",
    "build": "bun build src/server.ts --outdir ./dist --target node"
},
로그인 후 복사
로그인 후 복사
로그인 후 복사

자, 이제 bun run start 명령을 실행하면 서버가 실행 중임을 확인하는 다음 내용이 터미널에 표시됩니다.

Server is running on http://localhost:8000
로그인 후 복사
로그인 후 복사

bun run build 명령을 실행하면 프로덕션 준비가 완료된 dist 폴더가 생성되어야 합니다. Hetzner나 다른 온라인 서버에 애플리케이션을 배포할 때 이 정보가 필요합니다.

알겠습니다. 백엔드 엔드포인트를 빠르게 테스트하여 예상대로 작동하는지 확인하겠습니다. 그런 다음 프런트 엔드 작업을 시작할 수 있습니다. 테스트할 엔드포인트는 5개(GET 2개, POST 1개, PUT 1개, DELETE 1개)입니다. API를 테스트하기 위해 Postman을 사용할 예정입니다.

관심 목록 앱 API POST 엔드포인트

방법: POST
엔드포인트: http://localhost:8000/watchlist

이것은 영화/시리즈 데이터가 포함된 JSON 개체를 데이터베이스로 보내는 데 사용되는 POST 엔드포인트입니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

관심 목록 앱 API 모든 엔드포인트 가져오기

방법: GET
엔드포인트: http://localhost:8000/watchlist

이것은 프런트 엔드에서 가져올 객체 배열을 반환하는 기본 GET 엔드포인트입니다. 데이터가 포함된 객체 배열을 반환하거나 아직 데이터베이스에 데이터를 게시하지 않은 경우 빈 배열을 반환합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

Watchlist App API GET By ID 엔드포인트

방법: GET
엔드포인트: http://localhost:8000/watchlist/3

이것은 ID로 항목을 가져오기 위한 GET 엔드포인트입니다. 해당 객체만 반환하고 항목이 없으면 오류를 표시합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

관심 목록 앱 API PUT 엔드포인트

방법: PUT
엔드포인트: http://localhost:8000/watchlist/3

이것은 ID를 사용하여 항목을 업데이트하기 위한 PUT 엔드포인트입니다. 해당 객체만 반환하고 항목이 없으면 오류를 표시합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

관심 목록 앱 API 삭제 엔드포인트

방법: 삭제
엔드포인트: http://localhost:8000/watchlist/3

ID를 사용하여 항목을 삭제하기 위한 DELETE 엔드포인트입니다. 성공 개체를 반환하고 항목이 없으면 오류를 표시합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

즉, API가 실행 중입니다. 이제 프런트엔드 코드를 시작할 수 있습니다.

프런트엔드 구축

watchlist-tracker-app의 루트 폴더 내에 있는지 확인한 후 아래 스크립트를 실행하여 모든 패키지 및 종속성과 함께 TypeScript용으로 설정된 Vite를 사용하여 React 프로젝트를 생성하세요.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 스크립트는 기본적으로 Bun 런타임 환경을 사용하여 프로젝트를 설치하고 설정합니다. 필요한 파일과 폴더는 모두 생성되었으므로 코드만 추가하면 됩니다. 우리는 스타일링을 위해 Tailwind CSS를 사용하도록 Vite 프로젝트를 설정했으며 데이터를 가져오기 위한 axios와 양식에서 날짜 변환을 수행하기 위한 dayjs를 사용하여 페이지 라우팅을 위한 TanStack Router를 사용했습니다.

이 빌드 스크립트 덕분에 이제 작업이 훨씬 간단해졌으므로 파일에 코드를 추가해 보겠습니다. 먼저 일부 구성 파일이 있습니다. tailwind.config.js 파일 내부의 모든 코드를 다음 코드로 바꿉니다.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 파일은 꽤 설명이 잘 되어 있습니다. Tailwind CSS가 프로젝트 전체에서 작동하려면 이 파일이 필요합니다.

이제 src/index.css 파일의 모든 코드를 이 코드로 대체합니다. CSS 파일에서 사용할 수 있도록 Tailwind 지시어를 추가해야 합니다.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이러한 지시문을 추가하면 모든 CSS 파일에서 Tailwind CSS 스타일에 액세스할 수 있습니다. 다음으로 더 이상 필요하지 않으므로 App.css 파일 내부의 CSS 코드를 모두 삭제하세요.

자, 이제 최종 구성 파일이 완성되었습니다. 그런 다음 페이지와 구성 요소 작업을 할 수 있습니다.

루트 폴더의 api.ts 파일에 다음 코드를 추가하세요.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 파일은 프런트엔드가 백엔드에 연결해야 하는 엔드포인트를 내보냅니다. 백엔드 API는 http://localhost:8000에 있다는 점을 기억하세요.

좋아요, App.tsx 파일의 모든 코드를 다음 새 코드로 바꾸겠습니다.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이것은 앱의 주요 진입점 구성 요소이며 이 구성 요소에는 모든 페이지에 대한 경로가 포함되어 있습니다.

다음으로 주요 구성 요소와 페이지 작업을 진행하겠습니다. 세 개의 구성 요소 파일과 세 개의 파일 페이지가 있습니다. 구성 요소부터 시작하여 이 코드를 구성 요소/AddItemForm.tsx:
의 파일에 추가합니다.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 구성요소는 데이터베이스에 항목을 추가하는 데 사용됩니다. 사용자는 이 양식 구성 요소를 사용하여 백엔드에 POST 요청을 보냅니다.

이제 구성 요소/FormField.tsx에 대한 코드를 추가해 보겠습니다.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이것은 우리 양식의 재사용 가능한 양식 필드 구성 요소입니다. 여러 필드에 동일한 구성요소를 사용할 수 있으므로 코드 베이스가 더 작아집니다.

마지막으로 Components/Header.tsx에 대한 코드를 추가해 보겠습니다.

import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { PrismaClient } from '@prisma/client';

const app = new Hono();

app.use(cors());

const prisma = new PrismaClient();

app.get('/watchlist', async (c) => {
  const items = await prisma.watchlistItem.findMany();
  return c.json(items);
});

app.get('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const item = await prisma.watchlistItem.findUnique({
    where: { id: Number(id) },
  });
  return item ? c.json(item) : c.json({ error: 'Item not found' }, 404);
});

app.post('/watchlist', async (c) => {
  const data = await c.req.json();
  const newItem = await prisma.watchlistItem.create({ data });
  return c.json(newItem);
});

app.put('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const data = await c.req.json();
  const updatedItem = await prisma.watchlistItem.update({
    where: { id: Number(id) },
    data,
  });
  return c.json(updatedItem);
});

app.delete('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  await prisma.watchlistItem.delete({ where: { id: Number(id) } });
  return c.json({ success: true });
});

Bun.serve({
  fetch: app.fetch,
  port: 8000,
});

console.log('Server is running on http://localhost:8000');

export default app;
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 헤더 구성요소로 인해 각 페이지에는 기본 탐색 기능이 있는 헤더가 있습니다.

세 페이지만 남았고 앱이 완성되었습니다. 따라서 다음 코드를 페이지/AddItem.tsx에 추가하세요.

"scripts": {
    "start": "bun run src/server.ts",
    "build": "bun build src/server.ts --outdir ./dist --target node"
},
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 페이지는 기본적으로 양식 구성 요소가 포함된 데이터베이스에 항목을 추가하는 페이지입니다.

맞습니다. 다음으로 페이지/Home.tsx에 대한 코드를 추가해 보겠습니다.

Server is running on http://localhost:8000
로그인 후 복사
로그인 후 복사

상상할 수 있듯이 이는 백엔드로 GET 요청을 보낸 다음 데이터베이스의 모든 항목에 대한 객체 배열을 검색하는 홈페이지가 될 것입니다.

마지막으로 페이지/ItemDetail.tsx에 대한 코드를 추가합니다:

bun create vite client --template react-ts
cd client
bunx tailwindcss init -p
bun install -D tailwindcss postcss autoprefixer tailwindcss -p
bun install @tanstack/react-router axios dayjs
cd src
mkdir components pages
touch api.ts
touch components/{AddItemForm,FormField,Header}.tsx pages/{AddItem,Home,ItemDetail}.tsx
cd ..
로그인 후 복사

이 페이지에는 ID별로 개별 항목 페이지가 표시됩니다. 데이터베이스의 항목을 편집하고 삭제하는 양식도 있습니다.

그렇습니다. 우리의 애플리케이션을 사용할 준비가 되었습니다. 백엔드 서버와 클라이언트 서버가 모두 실행되고 있는지 확인하세요. 여기 브라우저에서 앱이 실행되는 것을 볼 수 있습니다: http://localhost:5173/.

폴더 내에서 다음 명령을 사용하여 두 서버를 모두 실행하세요.

module.exports = {
  content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
};
로그인 후 복사

네, 잘했어요. 우리의 신청이 완료되었습니다! 이제 GitHub에 배포해 보겠습니다!

GitHub에 앱 배포

GitHub에 애플리케이션을 배포하는 것은 매우 간단합니다. 먼저 watchlist-tracker-app의 루트 폴더 안에 .gitignore 파일을 넣으세요. 백엔드 또는 클라이언트 폴더에서 .gitignore 파일을 복사하여 붙여넣기만 하면 됩니다. 이제 GitHub로 이동하여(계정이 없는 경우 계정 생성) watchlist-tracker-app에 대한 저장소를 생성하세요.

watchlist-tracker-app의 루트 폴더 내에서 명령줄을 사용하여 코드베이스를 업로드하세요. 이 예제 코드를 보고 자신의 저장소에 맞게 조정하세요.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

마지막으로 알아두어야 할 매우 중요한 사항이 하나 있습니다. 코드를 Hetzner에 업로드하면 더 이상 localhost를 통해 백엔드에 액세스할 수 없으므로 API 경로를 업데이트해야 합니다. const API_URL = 'http://localhost:8000'이라는 변수가 있습니다. 그 상단에 두 개의 파일이 있습니다. 파일은 api.ts 및 Components/AddItemForm.tsx입니다. 변수 API URL을 아래 URL로 바꾼 후 코드베이스를 GitHub에 다시 업로드하세요.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

그게 전부입니다. 이제 귀하의 코드베이스가 GitHub에서 온라인 상태가 되어 Hetzner에 배포할 수 있습니다.

Hetzner에서 계정 만들기

관심 목록 추적기 앱이 완성되었으므로 이제 애플리케이션을 Hetzner VPS 플랫폼에 배포할 시간입니다. Hetzner는 유료 플랫폼이지만 제공하는 다양성은 타의 추종을 불허합니다. 가장 저렴한 요금제는 한 달에 약 €4.51/$4.88/£3.76입니다. 개발자로서 학습, 연습, 프로덕션 배포 등을 위해 사용할 수 있으므로 자체 호스팅 온라인 서버를 갖는 것은 가치가 있습니다. 언제든지 서버 구독을 취소하고 필요할 때 다시 받을 수 있습니다.

대부분의 VPS는 모두 Linux와 같은 다양한 운영 체제를 실행할 수 있는 서버이기 때문에 본질적으로 동일합니다. VPS 제공업체마다 인터페이스와 설정이 다르지만 기본 구조는 거의 동일합니다. Hetzner에서 애플리케이션을 자체 호스팅하는 방법을 배우면 동일한 기술과 지식을 쉽게 재사용하여 다른 VPS 플랫폼에 애플리케이션을 배포할 수 있습니다.

VPS의 일부 사용 사례는 다음과 같습니다.

  • 웹호스팅
  • 앱 호스팅
  • 게임 서버
  • VPN 또는 프록시 서버
  • 이메일 서버
  • 데이터베이스 호스팅
  • 자동화 및 개발 업무
  • 미디어 스트리밍 및 파일 호스팅
  • 데이터 분석 및 머신러닝
  • 학습과 실험

Hetzner의 현재 가격은 여기에서 확인하실 수 있습니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

헤츠너 홈페이지에 접속해 페이지 중앙에 있는 빨간색 회원가입 버튼을 클릭하세요. 또는 오른쪽 상단에 있는 로그인 버튼을 클릭할 수도 있습니다. Cloud, Robot, konsoleH 및 DNS 옵션이 포함된 메뉴가 표시됩니다. 그 중 하나를 클릭하면 로그인 및 등록 양식 페이지로 이동합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

Deploying a React Watchlist Tracker App to Production Using DeployHQ

이제 로그인 및 등록 양식 페이지가 표시됩니다. 등록 버튼을 클릭하여 계정을 만들고 가입 절차를 완료하세요. PayPal 계정을 사용하거나 여권을 준비하여 인증 단계를 통과해야 할 수도 있습니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

이제 계정에 로그인하여 서버를 생성하고 구매할 수 있습니다. 가까운 위치를 선택한 다음 Ubuntu를 이미지로 선택합니다. 이 예시를 참조하세요.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

유형에서 공유 vCPU를 선택한 다음 서버 구성을 선택합니다. 우리는 몇 가지 리소스만 필요한 간단한 애플리케이션을 배포하고 있습니다. 원한다면 더 나은 서버를 선택하세요. 선택은 귀하에게 달려 있습니다. 전용 vCPU는 성능이 더 뛰어나지만 비용이 더 많이 듭니다. x86(Intel/AMD) 및 Arm64(Ampere) 프로세서 중에서 선택할 수도 있습니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

기본 구성을 사용할 수 있습니다. 아래 예를 참조하세요. 하지만 보안상의 이유로 SSH 키를 추가하는 것이 중요합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

SSH 키는 기존 비밀번호보다 서버에 인증하는 더 안전한 방법을 제공합니다. 키는 OpenSSH 형식이어야 하며 서버에 대한 높은 수준의 보안을 보장해야 합니다. 운영 체제에 따라 Google에서 "Mac에서 SSH 키 생성" 또는 "Windows에서 SSH 키 생성"을 검색할 수 있습니다. Mac에서 SSH 키를 생성하는 방법을 빠르게 안내해드리겠습니다.

먼저 터미널 애플리케이션을 열고 "your_email@example.com"을 실제 이메일 주소로 바꿔 다음 명령을 입력하세요.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

-b 4096 부분은 보안 강화를 위해 키가 4096비트임을 보장합니다. 그런 다음 메시지가 표시되면 키를 저장합니다. 기본 위치를 수락하거나 사용자 정의 위치를 ​​선택할 수 있습니다.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

암호 설정은 선택 사항이므로 이 단계를 건너뛸 수 있습니다. 이제 다음 명령을 실행하여 SSH 키를 SSH 에이전트에 로드하세요.

먼저 에이전트를 시작합니다.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

그런 다음 SSH 키를 추가하세요.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

SSH 공개 키를 클립보드에 복사하려면 다음을 실행하세요.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이렇게 하면 공개 키가 복사되어 Hetzner 또는 SSH 키가 필요한 다른 서비스에 추가할 수 있습니다. SSH 키를 이 양식 상자에 붙여넣고 추가하세요.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

볼륨, 배치 그룹, 라벨, 클라우드 구성은 이 프로젝트 범위를 벗어나므로 걱정할 필요가 없습니다. 백업은 도움이 될 수 있지만 비용이 추가되므로 이 프로젝트에서는 선택 사항입니다. 방화벽은 나중에 할 예정이니 지금은 걱정하지 않으셔도 됩니다. 서버 이름을 선택한 다음 현재 설정으로 서버를 생성하고 구매하면 Hetzner 계정이 준비됩니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

알겠습니다. 이제 Hetzner에 계정이 생겼습니다. 다음 섹션에서는 방화벽을 설정하고, Linux 운영 체제를 구성하고, 애플리케이션을 온라인으로 전환하는 방법을 설명합니다.

Hetzner에 Watchlist Tracker 앱 배포

헤츠너 방화벽 만들기

Linux OS에 SSH로 연결하기 전에 먼저 방화벽 규칙을 설정해 보겠습니다. SSH를 사용하려면 포트 22를 열어야 하며, 포트 80은 HTTP(Hypertext Transfer Protocol)를 사용하는 웹 서버의 기본 네트워크 포트인 TCP 포트이므로 포트 80을 열어야 합니다. 웹 브라우저와 서버 간 통신, 웹 콘텐츠 전달 및 수신에 사용됩니다. 이것이 바로 애플리케이션이 온라인에서 작동하도록 하는 방법입니다.

기본 메뉴에서 방화벽으로 이동한 다음 아래 표시된 인바운드 규칙을 사용하여 방화벽을 만듭니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

Deploying a React Watchlist Tracker App to Production Using DeployHQ

이제 방화벽이 작동하므로 Linux 환경을 설정하고 애플리케이션을 배포할 수 있으므로 다음 단계로 진행하겠습니다.

Linux 환경 설정

로그인용 SSH 키를 생성했기 때문에 원격 Hetzner 서버에 연결하는 것은 매우 간단합니다. 터미널을 사용하거나 VS Code와 같은 코드 편집기를 사용하여 연결할 수 있습니다. 명령줄을 사용하지 않고도 파일을 훨씬 더 쉽게 만들 수 있습니다. Visual Studio Code Remote - SSH 확장을 사용하려는 경우 그렇게 할 수 있습니다. 이번 프로젝트에서는 터미널을 고수하겠습니다.

터미널을 열고 이 SSH 명령을 입력하여 원격 서버에 로그인하세요. 주소 11.11.111.111을 서버 섹션에서 찾을 수 있는 실제 Hetzner IP 주소로 바꾸세요:

Deploying a React Watchlist Tracker App to Production Using DeployHQ

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 서버에 로그인하면 시작 화면과 IP 주소와 같은 기타 개인 정보가 표시됩니다. 여기서는 화면의 환영 부분을 보여드리겠습니다.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

알겠습니다. 좋습니다. 이제 마침내 애플리케이션을 온라인에 올리기 전에 개발 환경을 설정하는 몇 가지 명령을 실행할 수 있습니다. 그런데 서버에 대한 SSH 연결을 종료하고 닫으려면 종료를 입력한 후 Enter 버튼을 클릭하거나 키보드 단축키 Ctrl D를 사용하면 됩니다.

가장 먼저 해야 할 일은 Linux 시스템에서 패키지를 업데이트하고 업그레이드하는 것입니다. 하나의 명령으로 이를 수행할 수 있으므로 터미널에 다음 명령을 입력하고 Enter 키를 누르십시오.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 나머지 개발 패키지와 종속성을 설치해야 합니다. 첫 번째는 Node.js와 npm이므로 다음 명령을 사용하여 설치하세요.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

다음은 역방향 프록시로 사용해야 하는 Nginx입니다. 역방향 프록시는 클라이언트와 백엔드 서버 사이에 위치하여 클라이언트 요청을 적절한 백엔드 서버로 전달한 다음 서버의 응답을 클라이언트에 반환하는 서버입니다. 성능, 보안 및 확장성을 향상시키기 위해 들어오는 요청을 관리하고 라우팅하는 중개자 역할을 합니다. 따라서 다음 명령을 사용하여 설치하세요.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Git이 필요하며 이를 위해서는 GitHub에서 코드를 가져와 원격 서버에 업로드해야 합니다. 따라서 다음 명령을 사용하여 설치하세요.

import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { PrismaClient } from '@prisma/client';

const app = new Hono();

app.use(cors());

const prisma = new PrismaClient();

app.get('/watchlist', async (c) => {
  const items = await prisma.watchlistItem.findMany();
  return c.json(items);
});

app.get('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const item = await prisma.watchlistItem.findUnique({
    where: { id: Number(id) },
  });
  return item ? c.json(item) : c.json({ error: 'Item not found' }, 404);
});

app.post('/watchlist', async (c) => {
  const data = await c.req.json();
  const newItem = await prisma.watchlistItem.create({ data });
  return c.json(newItem);
});

app.put('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const data = await c.req.json();
  const updatedItem = await prisma.watchlistItem.update({
    where: { id: Number(id) },
    data,
  });
  return c.json(updatedItem);
});

app.delete('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  await prisma.watchlistItem.delete({ where: { id: Number(id) } });
  return c.json({ success: true });
});

Bun.serve({
  fetch: app.fetch,
  port: 8000,
});

console.log('Server is running on http://localhost:8000');

export default app;
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Bun 런타임은 애플리케이션을 실행하는 데 도움이 됩니다. 먼저 Bun을 설치하기 전에 필요에 따라 unzip 패키지를 설치해야 합니다. 그런 다음 Bun을 설치할 수 있습니다. 필요한 명령은 다음과 같습니다.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

동일한 Hetzner 서버에서 React 프론트엔드와 백엔드 서버를 모두 실행하려면 두 서비스를 동시에 관리해야 합니다. 여기에는 일반적으로 PM2와 같은 프로세스 관리자를 설정하여 백엔드 서버를 실행하고 Nginx를 역방향 프록시로 사용하여 프런트엔드와 백엔드 모두에 들어오는 요청을 처리하는 작업이 포함됩니다.

다음 명령을 사용하여 PM2를 설치하세요.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

맞습니다. Linux 환경 설정은 여기까지입니다. 다음 섹션에서는 GitHub에서 원격 서버로 코드베이스를 다운로드하고 Nginx 서버를 구성하여 앱이 온라인에서 작동하도록 하겠습니다.

Hetzner에서 온라인으로 애플리케이션 배포

명령줄 탐색 방법을 이미 알고 있다고 가정하겠습니다. 그렇지 않은 경우 Google에서 검색할 수 있습니다. 디렉토리를 변경하고 파일을 관리하겠습니다. 프로젝트로 GitHub 저장소를 복제하고 이를 원격 서버에 복사하는 것부터 시작하세요. 참고로 아래 명령을 사용하세요.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

웹 애플리케이션 파일은 /var/www에 저장됩니다. 파일 목록을 표시하는 데 사용되는 ls 명령과 작업 디렉터리를 인쇄하는 데 사용되는 pwd 명령을 사용하여 Linux OS의 모든 파일을 볼 수 있습니다. Linux 명령줄에 대해 자세히 알아보려면 초보자를 위한 Linux 명령줄 튜토리얼을 살펴보세요.

이제 원격 서버에 애플리케이션이 있으므로 백엔드와 프런트엔드의 프로덕션 빌드를 생성할 수 있습니다. 이렇게 하려면 watchlist-tracker-app 프로젝트 내부에 있는 폴더 백엔드 및 클라이언트의 루트로 CD를 입력하고 아래 표시된 명령을 실행하면 됩니다.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Bun을 런타임으로 사용하므로 설치 및 빌드 단계에 bun 명령을 사용하겠습니다.

좋아, 이제 Nginx 서버를 구성해 보겠습니다. nano 터미널 편집기를 사용하여 파일 내부에 코드를 작성하겠습니다. 관심 목록 추적기 앱용 Nginx 파일을 열려면 터미널에서 다음 명령을 실행하세요.

import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { PrismaClient } from '@prisma/client';

const app = new Hono();

app.use(cors());

const prisma = new PrismaClient();

app.get('/watchlist', async (c) => {
  const items = await prisma.watchlistItem.findMany();
  return c.json(items);
});

app.get('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const item = await prisma.watchlistItem.findUnique({
    where: { id: Number(id) },
  });
  return item ? c.json(item) : c.json({ error: 'Item not found' }, 404);
});

app.post('/watchlist', async (c) => {
  const data = await c.req.json();
  const newItem = await prisma.watchlistItem.create({ data });
  return c.json(newItem);
});

app.put('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const data = await c.req.json();
  const updatedItem = await prisma.watchlistItem.update({
    where: { id: Number(id) },
    data,
  });
  return c.json(updatedItem);
});

app.delete('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  await prisma.watchlistItem.delete({ where: { id: Number(id) } });
  return c.json({ success: true });
});

Bun.serve({
  fetch: app.fetch,
  port: 8000,
});

console.log('Server is running on http://localhost:8000');

export default app;
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

나노 코드 편집기에 익숙하지 않다면 이 치트 시트를 확인하세요.

이 구성을 복사하여 파일에 붙여넣고 저장하기만 하면 됩니다. server_name IP 주소를 자신의 Hetzner IP 주소로 바꾸십시오:

"scripts": {
    "start": "bun run src/server.ts",
    "build": "bun build src/server.ts --outdir ./dist --target node"
},
로그인 후 복사
로그인 후 복사
로그인 후 복사

Nginx는 리버스 프록시 서버 역할을 하는 데 매우 자주 사용됩니다. 역방향 프록시는 클라이언트(사용자의 브라우저)와 백엔드 서버 사이에 위치합니다. 클라이언트로부터 요청을 수신하여 하나 이상의 백엔드 서버로 전달합니다. 백엔드가 요청을 처리하면 역방향 프록시는 응답을 클라이언트에 다시 전달합니다. 이러한 설정에서 Nginx는 수신 트래픽의 진입점이 되며 요청을 Vite 프런트엔드 또는 API 백엔드와 같은 특정 서비스로 라우팅합니다.

Vite 프로덕션 프리뷰 빌드는 포트 4173에서 실행되며 백엔드 서버는 포트 8000에서 실행됩니다. 이러한 값을 변경하는 경우 이 Nginx 구성 파일에서도 업데이트해야 합니다. 그렇지 않으면 서버가 작동하지 않습니다.

Nginx 사이트가 아직 활성화되지 않은 경우 다음 명령을 사용하여 활성화하세요.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 Nginx 구성을 테스트하여 구문 오류가 없는지 확인하고 Nginx를 다시 시작하여 다음 명령으로 변경 사항을 적용합니다.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

거의 완료되었습니다. 이제 한 걸음 남았습니다. 지금 브라우저에서 헤츠너 IP 주소로 접속하시면 502 Bad Gateway와 같은 오류가 뜰 것입니다. 아직 실행 중인 서버가 없기 때문입니다. 먼저 PM2를 사용하여 두 서버를 동시에 실행해야 합니다. 따라서 애플리케이션이 항상 온라인 상태가 되도록 PM2가 시스템 부팅 시 시작되도록 설정해야 합니다. 터미널에서 다음 명령을 실행하여 이를 수행하세요.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 백엔드와 프런트엔드 서버를 실행해야 합니다. 폴더 루트 내부에서 다음 명령을 실행하세요.

백엔드 서버부터 시작해 보겠습니다. 터미널에서 다음 명령을 실행하세요.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

마지막으로 클라이언트 프런트엔드 서버를 실행해 보겠습니다. 터미널에서 다음 명령을 실행하세요.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

pm2 status 명령을 실행하면 아래와 같이 두 서버가 모두 온라인이고 실행 중인지 확인할 수 있습니다. 다른 모든 PM2 명령에 대해 알아보려면 PM2 프로세스 관리 빠른 시작 문서를 읽어보세요.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

터미널에서 이러한 컬 명령을 실행하여 서버에 연결할 수 있는지 테스트할 수 있습니다. 작동하는 경우 HTML 코드를 다시 받아야 합니다.

import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { PrismaClient } from '@prisma/client';

const app = new Hono();

app.use(cors());

const prisma = new PrismaClient();

app.get('/watchlist', async (c) => {
  const items = await prisma.watchlistItem.findMany();
  return c.json(items);
});

app.get('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const item = await prisma.watchlistItem.findUnique({
    where: { id: Number(id) },
  });
  return item ? c.json(item) : c.json({ error: 'Item not found' }, 404);
});

app.post('/watchlist', async (c) => {
  const data = await c.req.json();
  const newItem = await prisma.watchlistItem.create({ data });
  return c.json(newItem);
});

app.put('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const data = await c.req.json();
  const updatedItem = await prisma.watchlistItem.update({
    where: { id: Number(id) },
    data,
  });
  return c.json(updatedItem);
});

app.delete('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  await prisma.watchlistItem.delete({ where: { id: Number(id) } });
  return c.json({ success: true });
});

Bun.serve({
  fetch: app.fetch,
  port: 8000,
});

console.log('Server is running on http://localhost:8000');

export default app;
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Hetzner 서버의 IP 주소로 이동하세요. 모든 작업을 올바르게 수행했다면 앱이 배포되고 온라인 상태로 표시되어야 합니다! 웹사이트에는 일반적으로 도메인 이름이 있으며 IP 주소는 검색창에 숨겨져 있습니다. 개발자가 도메인을 구입한 다음 네임서버를 변경하여 이를 호스트 서버에 연결하는 것은 매우 일반적인 일입니다. 이는 이 튜토리얼의 범위를 벗어나지만 Google 검색을 통해 수행 방법을 쉽게 배울 수 있습니다. Namecheap은 제가 선호하는 도메인 등록입니다.

DeployHQ를 사용하여 배포 프로세스 간소화

맞습니다. 거의 완성 단계에 이르렀습니다. 이제 마지막 단계는 DeployHQ를 사용하여 배포 프로세스를 간소화하는 것입니다. DeployHQ를 사용하면 배포가 쉽고 보안 목적으로 훨씬 더 좋습니다. 온라인 서버에서 코드베이스를 업데이트하는 전통적인 방법은 git pull을 사용하여 GitHub 저장소에서 최신 변경 사항을 가져오는 것입니다. 그러나 git pull을 수행하면 git 폴더가 노출될 수 있고 웹사이트가 축소되거나 추악해지지 않을 가능성이 높기 때문에 좋은 습관이 아닙니다.

여기서 DeployHQ는 중요한 역할을 합니다. 구성된 폴더에 수정된 파일을 안전하게 복사하여 서버의 git 로그에 변경 사항이 표시되지 않도록 합니다. 이는 절충처럼 보일 수 있지만 배포의 안전성을 보장하는 보안 기능입니다. Vercel 또는 Netlify와 같은 플랫폼에 익숙하다면 이러한 자동 배포가 매우 유사하다는 것을 알게 될 것입니다. 이 경우 VPS의 모든 온라인 서버에서 작동할 수 있는 설정이 있습니다.

언급할 가치가 있는 한 가지 사실은 온라인 Linux 원격 서버에 대해 루트가 아닌 사용자를 생성하는 것이 중요하다는 것입니다. 루트 사용자로 로그인하는 것이 항상 최선의 방법은 아닙니다. 비슷한 권한을 가진 다른 사용자를 설정하는 것이 더 좋습니다. DeployHQ는 또한 로그인에 루트 사용자를 사용하는 것을 권장하지 않습니다. DeployHQ가 작동하려면 SSH를 사용하여 계정에 로그인해야 합니다. 온라인 Ubuntu 서버에 DeployHQ SSH 공개 키를 배치해야 하므로 DeployHQ 계정이 생긴 후에 이 작업을 수행하겠습니다.

DeployHQ를 사용하면 처음 가입할 때 아무런 의무 없이 10일 동안 모든 기능에 무료로 액세스할 수 있습니다. 그 후에는 귀하의 계정이 하루에 최대 5번까지 단일 프로젝트를 배포할 수 있는 무료 플랜으로 되돌아갑니다.

먼저 DeployHQ 웹사이트로 이동하여 아래에 보이는 버튼 중 하나를 클릭하여 계정을 만드세요.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

이제 Create a project 버튼이 있는 DeployHQ 환영 화면이 표시됩니다. 버튼을 클릭하면 여기에 표시된 것과 같은 프로젝트가 생성됩니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

다음 화면에서는 새 프로젝트를 만들어야 합니다. 이름을 지정하고 GitHub 저장소를 선택하세요. 또한 프로젝트 영역을 선택한 다음 프로젝트를 생성하세요.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

이제 아래와 같은 서버 화면이 나타납니다. 이는 이제 원격 서버에 대해 다른 Linux 사용자를 생성하여 루트 사용자에 의존할 필요가 없음을 의미합니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

루트 사용자로 서버에 로그인한 후 아래 명령을 사용하여 새 사용자를 생성하세요. new_username을 새 사용자에게 사용하려는 사용자 이름으로 바꾸세요.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

비밀번호를 설정하라는 메시지가 표시되고 이름, 방 번호 등의 세부정보를 입력하라는 메시지가 표시됩니다. 비밀번호만 설정하면 됩니다. 다른 프롬프트 단계를 건너뛰고 모두 사라질 때까지 Enter 키를 눌러 공백으로 남겨둘 수 있습니다.

루트 사용자와 같은 관리 권한을 가질 수 있도록 새 사용자를 sudo 그룹에 추가하는 것도 좋은 생각입니다. 여기에 표시된 명령을 사용하여 이 작업을 수행하세요.

mkdir backend
cd backend
bun init -y
mkdir src
touch src/server.ts
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 새 사용자에게 서버에 대한 SSH 액세스가 필요합니다. 먼저 새 사용자로 전환한 후 다음 명령을 사용하여 해당 사용자를 위한 .ssh 디렉터리를 만듭니다.

bun add hono prisma @prisma/client
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 로컬 공개 키를 서버의 Authorized_keys에 추가해야 합니다. 그러면 로컬 컴퓨터에서 다음 명령을 사용하여 공개 키를 복사할 수 있습니다.

npx prisma init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 서버에서 authenticate_keys 파일을 열어 nano 편집기로 편집할 수 있습니다.

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model WatchlistItem {
  id          Int      @id @default(autoincrement())
  name        String
  image       String
  rating      Float
  description String
  releaseDate DateTime
  genre       String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

복사한 공개 키를 이 파일에 붙여넣으세요. 파일을 저장하기 전에 서버 페이지의 DeployHQ SSH 키를 복사하여 동일한 파일에 붙여넣으세요. 인증에 비밀번호 대신 SSH 키를 사용하시겠습니까? 확인란을 선택하면 SSH 키를 확인할 수 있습니다. 이제 파일을 저장하고 다음 명령을 사용하여 파일에 대한 올바른 권한을 설정하십시오.

npx prisma migrate dev --name init
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 새 사용자의 SSH 로그인을 테스트할 수 있습니다. 먼저 원격 서버에서 로그아웃한 다음 다시 로그인을 시도합니다. 이번에는 루트가 아닌 생성한 새 사용자를 사용합니다. 아래 예를 참조하세요.

import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { PrismaClient } from '@prisma/client';

const app = new Hono();

app.use(cors());

const prisma = new PrismaClient();

app.get('/watchlist', async (c) => {
  const items = await prisma.watchlistItem.findMany();
  return c.json(items);
});

app.get('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const item = await prisma.watchlistItem.findUnique({
    where: { id: Number(id) },
  });
  return item ? c.json(item) : c.json({ error: 'Item not found' }, 404);
});

app.post('/watchlist', async (c) => {
  const data = await c.req.json();
  const newItem = await prisma.watchlistItem.create({ data });
  return c.json(newItem);
});

app.put('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  const data = await c.req.json();
  const updatedItem = await prisma.watchlistItem.update({
    where: { id: Number(id) },
    data,
  });
  return c.json(updatedItem);
});

app.delete('/watchlist/:id', async (c) => {
  const id = c.req.param('id');
  await prisma.watchlistItem.delete({ where: { id: Number(id) } });
  return c.json({ success: true });
});

Bun.serve({
  fetch: app.fetch,
  port: 8000,
});

console.log('Server is running on http://localhost:8000');

export default app;
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

모든 작업을 올바르게 수행했다면 이제 새 사용자로 로그인할 수 있습니다.

이제 드디어 서버 양식을 완성할 수 있게 되었습니다. 아래 예를 참조하여 양식에 정보를 입력하세요.

이름: watchlist-tracker-app
프로토콜: SSH/SFTP
호스트 이름: 11.11.111.111
포트: 22
사용자 이름: new_username
인증에 비밀번호 대신 SSH 키를 사용하시겠습니까?: 선택됨
배포 경로: /var/www/watchlist-tracker-app

배포 경로는 GitHub 저장소가 있는 서버의 위치여야 합니다. 이제 서버를 생성할 수 있습니다. 문제가 발생하면 방화벽 설정 때문일 수 있으므로 방화벽을 통해 어떤 IP 주소를 허용해야 합니까? 문서를 읽어보세요.

이제 여기에 표시된 새 배포 화면이 표시됩니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

배포가 성공적으로 완료되면 다음 화면이 표시됩니다.

Deploying a React Watchlist Tracker App to Production Using DeployHQ

마지막 단계는 로컬 저장소에서 GitHub로 변경 사항을 푸시할 때 자동으로 원격 서버에 배포되도록 자동 배포를 설정하는 것입니다. DeployHQ 계정의 왼쪽 사이드바에 있는 자동 배포 페이지에서 이 작업을 수행할 수 있습니다. 여기의 예를 참조하세요:

Deploying a React Watchlist Tracker App to Production Using DeployHQ

모두 끝났습니다. 축하합니다. 전체 스택 React 애플리케이션을 구축하고, GitHub에 코드베이스를 배포하고, Linux Ubuntu를 실행하는 VPS에서 애플리케이션을 호스팅하고, DeployHQ를 사용하여 자동 배포를 설정하는 방법을 배웠습니다. 개발자 게임이 레벨업되었습니다!

결론

최신 도구와 기술을 사용하여 Watchlist Tracker와 같은 풀 스택 CRUD 앱을 구축하는 것은 효율적이고 즐겁습니다. 우리는 백엔드에 Bun, Hono, Prisma ORM 및 SQLite와 같은 매우 강력한 기술 스택을 사용했으며 프런트 엔드에 Vite, Tailwind CSS 및 TanStack Router를 사용하여 반응성과 기능을 향상시켰습니다. Hetzner는 사용자가 어디에 있든 앱이 안정적이고 우수한 성능을 발휘하도록 보장하겠습니다.

DeployHQ를 통한 배포를 사용하면 배포가 매우 쉬워집니다. Git 리포지토리에서 클라우드 서버로 바로 업데이트를 푸시하기만 하면 됩니다. 리포지토리의 모든 변경 사항은 자동으로 프로덕션 서버에 배포되어 최신 버전의 애플리케이션이 활성화됩니다. 자동화된 배포는 배포와 관련된 오류 수를 줄여주기 때문에 시간이 절약되므로 모든 형태의 개발 워크플로에 추가할 가치가 있습니다.

이 튜토리얼은 DeployHQ 덕분에 자동 git 배포와 함께 Hetzner와 같은 VPS를 사용하여 모든 종류의 애플리케이션을 프로덕션에 배포하는 데 도움이 됩니다.

위 내용은 DeployHQ를 사용하여 React Watchlist Tracker 앱을 프로덕션에 배포의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!