티스토리 뷰

반응형

Next.js + NestJS + Cloudflare 완전 통합 운영 아키텍처 구축

(프론트와 백엔드를 하나의 DevOps 파이프라인으로 묶기)


이제 우리는 백엔드 단에서
NestJS + Prisma + Docker + PM2 + GitHub Actions + AWS + Cloudflare
까지 완벽한 자동화 인프라를 구축했다.

이번 편은 그 위 단계,
👉 “Next.js 프론트엔드 + NestJS 백엔드를 하나의 서비스 체인으로 통합하고,
Cloudflare CDN과 Pages, R2 스토리지를 이용해 완전한 풀스택 DevOps 파이프라인을 만드는 과정”을 정리한다.

이 글은 ‘사이드 프로젝트 수준’을 넘어서
실제 스타트업 서비스 수준의 운영 구조를 완성하는 데 초점을 둔다.


🧭 이번 목표

영역 기술 목적

프론트엔드 Next.js 15 (App Router) CSR/SSR 혼합 렌더링
백엔드 NestJS + Prisma + Redis API, 인증, 캐싱
스토리지 Cloudflare R2 이미지, 첨부파일 관리
CDN Cloudflare Pages + Edge Cache 전 세계 엣지 배포
배포 GitHub Actions 풀스택 동시 배포
SSL/도메인 Cloudflare DNS HTTPS & Route 관리

1️⃣ 전체 아키텍처 개요

┌──────────────────────────────────────────────────────┐
│                    Cloudflare Edge                  │
│  (Pages CDN + R2 Storage + SSL + DNS)               │
│──────────────────────────────────────────────────────│
│   • Next.js Frontend (CSR/ISR)                      │
│   • Image CDN (R2)                                  │
│   • Reverse Proxy → Nest API                        │
└──────────────┬───────────────────────────────────────┘
               │
               ▼
       [AWS Load Balancer] ─► [EC2 Blue/Green Stack]
                     │
                     ├── NestJS App (PM2 Cluster)
                     ├── Redis Cache
                     └── MySQL DB (RDS)

2️⃣ Next.js 프로젝트 설정

① Next.js 앱 생성

npx create-next-app@latest web
cd web
npm install axios swr

② 환경변수 설정

.env.local

NEXT_PUBLIC_API_URL=https://api.yourdomain.com

③ API 호출 구조 (SWR 예시)

반응형
// app/posts/page.tsx
'use client';
import useSWR from 'swr';
import axios from 'axios';

const fetcher = (url: string) =>
  axios.get(url).then(res => res.data);

export default function PostsPage() {
  const { data, error } = useSWR(
    `${process.env.NEXT_PUBLIC_API_URL}/posts`,
    fetcher
  );

  if (error) return <div>❌ Failed to load</div>;
  if (!data) return <div>Loading...</div>;

  return (
    <div>
      <h1>게시글 목록</h1>
      {data.map((post: any) => (
        <div key={post.id}>
          <h3>{post.title}</h3>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  );
}

Next.js는 .env.local의 NEXT_PUBLIC_ 변수만 클라이언트에 노출된다.
NestJS API URL을 반드시 이 접두사로 지정하자.


3️⃣ Next.js와 NestJS 도메인 통합

Cloudflare DNS 예시

Type Name Value Proxy

A api AWS LoadBalancer IP ☁️ Proxied
CNAME www web.pages.dev ☁️ Proxied

Cloudflare가 SSL/TLS와 CDN을 관리하기 때문에
Next.js (프론트)와 NestJS (백엔드)는 하나의 도메인 네임스페이스 안에서 작동한다.

예:


4️⃣ Cloudflare Pages로 Next.js 자동 배포

  1. GitHub 저장소 연결
    → web/ 디렉토리 선택
  2. Framework: Next.js
  3. Build command:
  4. npm install && npm run build
  5. Output directory: .next
  6. Environment variables:

Cloudflare Pages는 전 세계 엣지에서 SSR을 수행하므로,
API 요청만 NestJS 서버로 백엔드 호출한다.


5️⃣ Cloudflare R2로 이미지 업로드

NestJS에서 S3 SDK를 그대로 사용 가능하다.

패키지 설치

npm install aws-sdk

환경변수 (.env)

R2_ACCESS_KEY_ID=your_access_key
R2_SECRET_ACCESS_KEY=your_secret_key
R2_BUCKET=nest-assets
R2_ENDPOINT=https://<accountid>.r2.cloudflarestorage.com

서비스 코드

// src/file/file.service.ts
import { Injectable } from '@nestjs/common';
import { S3 } from 'aws-sdk';
import * as mime from 'mime-types';

@Injectable()
export class FileService {
  private s3: S3;

  constructor() {
    this.s3 = new S3({
      endpoint: process.env.R2_ENDPOINT,
      accessKeyId: process.env.R2_ACCESS_KEY_ID,
      secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
      signatureVersion: 'v4',
    });
  }

  async upload(file: Express.Multer.File) {
    const key = `uploads/${Date.now()}-${file.originalname}`;
    await this.s3
      .putObject({
        Bucket: process.env.R2_BUCKET!,
        Key: key,
        Body: file.buffer,
        ContentType: mime.lookup(file.originalname) || 'application/octet-stream',
      })
      .promise();

    return `https://${process.env.R2_BUCKET}.${process.env.R2_ENDPOINT}/${key}`;
  }
}

6️⃣ GitHub Actions 통합 (Frontend + Backend)

.github/workflows/full-deploy.yml

name: Fullstack Deploy

on:
  push:
    branches: [ main ]

jobs:
  backend:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Deploy Backend (NestJS)
        uses: appleboy/ssh-action@v1.1.0
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            cd /srv/nest-app
            git pull origin main
            docker compose build
            docker compose run --rm migrate
            docker compose up -d
            sudo systemctl reload nginx

  frontend:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy Next.js to Cloudflare Pages
        uses: cloudflare/pages-action@v1
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          projectName: "next-frontend"
          directory: "./web"

이제 main 브랜치에 push 하면
백엔드는 AWS에, 프론트는 Cloudflare Pages에 자동 반영된다.


7️⃣ 최종 DevOps 구조

┌──────────────────────────────────────────────┐
│ GitHub Actions                              │
│ ├── Backend Job → SSH Deploy (AWS EC2)       │
│ └── Frontend Job → Cloudflare Pages Deploy   │
└──────────────────────────────────────────────┘
           │
           ▼
┌──────────────────────────────────────────────┐
│ Cloudflare Edge Network                      │
│ ├── Pages CDN (Next.js SSR)                  │
│ ├── R2 Storage (Images)                      │
│ └── Proxy → NestJS API (AWS EC2)             │
└──────────────────────────────────────────────┘

✅ 이번 편 요약

항목 상태

Next.js 프론트 구축
Cloudflare Pages 배포
R2 스토리지 연결
NestJS API 통합
GitHub Actions 전체 자동화

이제 진짜로 “개인 프로젝트 수준”이 아니라
SaaS 백엔드-프론트 완전 자동화 파이프라인이 완성됐다.


🔮 다음 시리즈 예고

이제 우리가 만든 구조를
👉 “IaC(코드형 인프라) + Terraform + GitOps (ArgoCD)” 로 옮긴다.

즉, 클릭 한 번 없이 모든 인프라를 코드로 관리하고 배포하는
완전한 DevOps 환경 구축편으로 들어간다.
여기서부터는 진짜 엔터프라이즈급 운영 자동화 단계다.


 

Next.js, NestJS, Cloudflare, R2, CDN, Pages, DevOps, 풀스택배포, GitHubActions, AWS, 백엔드프론트통합

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함
반응형