본문 바로가기
강의 실습/비전공자도 이해할 수 있는 Docker 입문 실전

[실습] 웹 프론트엔드 프로젝트(Next.js)를 Docker로 배포하기

by jint 2026. 5. 20.

1. 웹 프론트엔드 프로젝트(Next.js)를 Docker로 배포하기
1) Next.js 프로젝트 생성
- Windows PowerShell

PS C:\Users\admin> npx create-next-app@latest
Need to install the following packages:
create-next-app@16.2.6
Ok to proceed? (y) y
√ What is your project named? ... docker-next-server
√ Would you like to use the recommended Next.js defaults? » Yes, use recommended defaults
Creating a new Next.js app in C:\Users\admin\docker-next-server.

Using npm.

Initializing project with template: app-tw


Installing dependencies:
- next
- react
- react-dom

Installing devDependencies:
- @tailwindcss/postcss
- @types/node
- @types/react
- @types/react-dom
- eslint
- eslint-config-next
- tailwindcss
- typescript

npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'eslint-visitor-keys@5.0.1',
npm WARN EBADENGINE   required: { node: '^20.19.0 || ^22.13.0 || >=24' },
npm WARN EBADENGINE   current: { node: 'v20.10.0', npm: '10.2.3' }
npm WARN EBADENGINE }

added 359 packages, and audited 360 packages in 22s

142 packages are looking for funding
  run `npm fund` for details

2 moderate severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Generating route types...
✓ Types generated successfully

Initialized a git repository.

Success! Created docker-next-server at C:\Users\admin\docker-next-server

PS C:\Users\admin> cd docker-next-server
PS C:\Users\admin\docker-next-server> ls


    디렉터리: C:\Users\admin\docker-next-server


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----      2026-05-20  오후 10:48                .next
d-----      2026-05-20  오후 10:47                app
d-----      2026-05-20  오후 10:48                node_modules
d-----      2026-05-20  오후 10:47                public
-a----      2026-05-20  오후 10:47            480 .gitignore
-a----      2026-05-20  오후 10:48            327 AGENTS.md
-a----      2026-05-20  오후 10:48             11 CLAUDE.md
-a----      2026-05-20  오후 10:47            465 eslint.config.mjs
-a----      2026-05-20  오후 10:47            247 next-env.d.ts
-a----      2026-05-20  오후 10:47            133 next.config.ts
-a----      2026-05-20  오후 10:48         219497 package-lock.json
-a----      2026-05-20  오후 10:47            541 package.json
-a----      2026-05-20  오후 10:47             94 postcss.config.mjs
-a----      2026-05-20  오후 10:47           1450 README.md
-a----      2026-05-20  오후 10:47            666 tsconfig.json


PS C:\Users\admin\docker-next-server> npm run dev

> docker-next-server@0.1.0 dev
> next dev

▲ Next.js 16.2.6 (Turbopack)
- Local:         http://localhost:3000
- Network:       http://172.31.16.1:3000
✓ Ready in 496ms

 GET / 200 in 1606ms (next.js: 1479ms, application-code: 127ms)
[browser] Image with src "http://localhost:3000/vercel.svg" has either width or height modified, but not the other. If you use CSS to change the size of your image, also include the styles 'width: "auto"' or 'height: "auto"' to maintain the aspect ratio.

# Ctrl + c
일괄 작업을 끝내시겠습니까 (Y/N)? Y


2) Dockerfile 작성
- docker-next-server/Dockerfile

# 베이스 이미지 node
FROM node:20-alpine

# 작업 디렉토리 지정
WORKDIR /app

# 호스트 컴퓨터 파일을 컨테이너로 복사
COPY . .

# 라이브러리 설치
RUN npm install

# 빌드
RUN npm run build

# 3000번 포트 사용 명시
EXPOSE 3000

# 빌드된 next.js 프로젝트 실행
ENTRYPOINT ["npm", "run", "start"]


* 심화
Docker 이미지 생성 시 캐시를 활용한 최적화 방법
Docker Layer와 Cache : https://medium.com/@hee98.09.14/docker-layer%EC%99%80-cache-574c12a1e9f7

 

Docker Layer와 Cache

Docker Layer

medium.com


· alpine : 불필요한 프로그램을 포함하지 않고 이미지 크기를 최소화한 버전 (최적화된 버전)
실제 배포시, alpine 버전 사용 권장 (현업 Production(운영) 환경에서 많이 씀)

3) .dockerignore 작성
- docker-next-server/.dockerignore

node_modules


이미지 생성시, npm install 을 통해 필요한 의존성만 설치하기 때문에, 호스트 컴퓨터의 node_modules 는 컨테이너로 복사할 필요가 없다.

4) Dockerfile 바탕으로 이미지 빌드
- Windows PowerShell

PS C:\Users\admin\docker-next-server> docker build -t docker-next-server .
[+] Building 44.8s (11/11) FINISHED                                                                                                                                                         docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                                                        0.1s
 => => transferring dockerfile: 402B                                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/node:20-alpine                                                                                                                                           2.7s
 => [auth] library/node:pull token for registry-1.docker.io                                                                                                                                                 0.0s
 => [internal] load .dockerignore                                                                                                                                                                           0.1s
 => => transferring context: 52B                                                                                                                                                                            0.0s
 => [1/5] FROM docker.io/library/node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293                                                                                     3.6s
 => => resolve docker.io/library/node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293                                                                                     0.0s
 => => sha256:fff4e2c1b189bf87d63ad8bd07f7f4eb288d6f2b6a07a8bb44c60e8c075d2096 445B / 445B                                                                                                                  0.2s
 => => sha256:b2cbbfe903b0821005780971ddc5892edcc4ce74c5a48d82e1d2b382edac3122 1.26MB / 1.26MB                                                                                                              0.5s
 => => sha256:6a0ac1617861a677b045b7ff88545213ec31c0ff08763195a70a4a5adda577bb 3.86MB / 3.86MB                                                                                                              0.8s
 => => sha256:4feea04c154301db6f4a496efa397b3db96603b1c009c797cfdde77bea8b3287 43.23MB / 43.23MB                                                                                                            2.5s
 => => extracting sha256:6a0ac1617861a677b045b7ff88545213ec31c0ff08763195a70a4a5adda577bb                                                                                                                   0.1s
 => => extracting sha256:4feea04c154301db6f4a496efa397b3db96603b1c009c797cfdde77bea8b3287                                                                                                                   0.8s
 => => extracting sha256:b2cbbfe903b0821005780971ddc5892edcc4ce74c5a48d82e1d2b382edac3122                                                                                                                   0.1s
 => => extracting sha256:fff4e2c1b189bf87d63ad8bd07f7f4eb288d6f2b6a07a8bb44c60e8c075d2096                                                                                                                   0.0s
 => [internal] load build context                                                                                                                                                                           4.0s
 => => transferring context: 67.81MB                                                                                                                                                                        3.8s
 => [2/5] WORKDIR /app                                                                                                                                                                                      0.1s
 => [3/5] COPY . .                                                                                                                                                                                          0.2s
 => [4/5] RUN npm install                                                                                                                                                                                  10.8s
 => [5/5] RUN npm run build                                                                                                                                                                                 4.9s
 => exporting to image                                                                                                                                                                                     21.9s
 => => exporting layers                                                                                                                                                                                    17.3s
 => => exporting manifest sha256:944ff33ef0e4757c50cc56923f2ccd821d6047c290066f0fdd23779fe951f195                                                                                                           0.0s
 => => exporting config sha256:786ce7d86c29b333bdeea37e8b63b3f13c2ecad31b44c6f75955fcdf4dc8547b                                                                                                             0.0s
 => => exporting attestation manifest sha256:bf74d8b6aebd9b563f5d5451c7e630228fbe3399a4f2f71db188309c70d60152                                                                                               0.1s
 => => exporting manifest list sha256:0dbe70a9c349d500cf26ad5eeb226ca86d3e0002a2229fbde5d620c323609d47                                                                                                      0.0s
 => => naming to docker.io/library/docker-next-server:latest                                                                                                                                                0.0s
 => => unpacking to docker.io/library/docker-next-server:latest                                                                                                                                             4.4s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/knwg3p6p7y9t4ihupb03za8zt


5)  이미지 생성 확인
- Windows PowerShell

PS C:\Users\admin\docker-next-server> docker image ls
                                                                                                                                                                                             i Info →   U  In Use
IMAGE                       ID             DISK USAGE   CONTENT SIZE   EXTRA
docker-next-server:latest   0dbe70a9c349       1.52GB          442MB
my-jdk17-server:beta        18e650b59b52        682MB          212MB
my-jdk17-server:latest      09a2803e5d8e        682MB          212MB    U
my-node-server:latest       9a1e49574c81       1.77GB          442MB    U
my-server:latest            c8dad74bef6b        157MB         41.6MB    U


6) 생성한 이미지 컨테이너로 실행
호스트의 80번 포트로 매핑하는 이유는, URL 접속시 포트를 생략하기 위함

- Windows PowerShell

PS C:\Users\admin\docker-next-server> docker run -d -p 80:3000 docker-next-server
5cecbfae8b92d0ed937ef955137a5760a2544a78f860645eee2396ed91c65039


7) 컨테이너 실행 확인
- Windows PowerShell

PS C:\Users\admin\docker-next-server> docker ps
CONTAINER ID   IMAGE                COMMAND           CREATED          STATUS          PORTS                                     NAMES
5cecbfae8b92   docker-next-server   "npm run start"   18 seconds ago   Up 17 seconds   0.0.0.0:80->3000/tcp, [::]:80->3000/tcp   tender_morse


8) 브라우저에서 확인
브라우저에서 http://localhost:80/ 접속

 

Docker 로 Next.js 서버 실행 확인


9) 컨테이너 내부 파일 확인
- Windows PowerShell

PS C:\Users\admin\docker-next-server> docker exec -it 5cec bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH

What's next:
    Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug 5cec
    Learn more at https://docs.docker.com/go/debug-cli/
PS C:\Users\admin\docker-next-server> docker debug 5cec
Pulling image, this might take a moment...
0.0.47: Pulling from docker/desktop-docker-debug-service
86f3ab2d6aae: Pull complete
ab69d4748658: Download complete
199dfd03e550: Download complete
Digest: sha256:27cd5ec6108982b025f9f426b1aa3b5eb0a2cbbd677e73de337a4a41f0c4bce2
Status: Downloaded newer image for hubproxy.docker.internal:5555/docker/desktop-docker-debug-service:0.0.47
         ▄
     ▄ ▄ ▄  ▀▄▀
   ▄ ▄ ▄ ▄ ▄▇▀  █▀▄ █▀█ █▀▀ █▄▀ █▀▀ █▀█
  ▀████████▀    █▄▀ █▄█ █▄▄ █ █ ██▄ █▀▄
   ▀█████▀                        DEBUG

Builtin commands:
- install [tool1] [tool2] ...    Add Nix packages from: https://search.nixos.org/packages
- uninstall [tool1] [tool2] ...  Uninstall NixOS package(s).
- entrypoint                     Print/lint/run the entrypoint.
- builtins                       Show builtin commands.

Checks:
✓ distro:            Alpine Linux v3.23
✓ entrypoint linter: no errors (run 'entrypoint' for details)

This is an attach shell, i.e.:
- Any changes to the container filesystem are visible to the container directly.
- The /nix directory is invisible to the actual container.
                                                                                                                                                                                                  Version: 0.0.47
root@5cecbfae8b92 /app [tender_morse]
docker > ls
AGENTS.md  CLAUDE.md  Dockerfile  README.md  app  eslint.config.mjs  next-env.d.ts  next.config.ts  node_modules  package-lock.json  package.json  postcss.config.mjs  public  tsconfig.json
root@5cecbfae8b92 /app [tender_morse]
docker > cat Dockerfile
# 베이스 이미지 node
FROM node:20-alpine

# 작업 디렉토리 지정
WORKDIR /app

# 호스트 컴퓨터 파일을 컨테이너로 복사
COPY . .

# 라이브러리 설치
RUN npm install

# 빌드
RUN npm run build

# 3000번 포트 사용 명시
EXPOSE 3000

# 빌드된 next.js 프로젝트 실행
ENTRYPOINT ["npm", "run", "start"]root@5cecbfae8b92 /app [tender_morse]
docker > ls -al
total 296
drwxr-xr-x   1 root root   4096 May 20 14:01 .
drwxr-xr-x   4 root root     80 May 20 14:10 ..
-rwxr-xr-x   1 root root     12 May 20 13:59 .dockerignore
drwxr-xr-x   7 root root   4096 May 20 13:48 .git
-rwxr-xr-x   1 root root    480 May 20 13:47 .gitignore
drwxr-xr-x   1 root root   4096 May 20 14:01 .next
-rwxr-xr-x   1 root root    327 May 20 13:48 AGENTS.md
-rwxr-xr-x   1 root root     11 May 20 13:48 CLAUDE.md
-rwxr-xr-x   1 root root    363 May 20 13:58 Dockerfile
-rwxr-xr-x   1 root root   1450 May 20 13:47 README.md
drwxr-xr-x   2 root root   4096 May 20 13:47 app
-rwxr-xr-x   1 root root    465 May 20 13:47 eslint.config.mjs
-rwxr-xr-x   1 root root    247 May 20 14:01 next-env.d.ts
-rwxr-xr-x   1 root root    133 May 20 13:47 next.config.ts
drwxr-xr-x 293 root root  12288 May 20 14:01 node_modules
-rwxr-xr-x   1 root root 219545 May 20 14:01 package-lock.json
-rwxr-xr-x   1 root root    541 May 20 13:47 package.json
-rwxr-xr-x   1 root root     94 May 20 13:47 postcss.config.mjs
drwxr-xr-x   2 root root   4096 May 20 13:47 public
-rwxr-xr-x   1 root root    666 May 20 13:47 tsconfig.json
root@5cecbfae8b92 /app [tender_morse]
docker > cat .dockerignore
node_modulesroot@5cecbfae8b92 /app [tender_morse]
docker > exit
exit
PS C:\Users\admin\docker-next-server> docker exec -it 5cec ls
AGENTS.md           Dockerfile          app                 next-env.d.ts       node_modules        package.json        public
CLAUDE.md           README.md           eslint.config.mjs   next.config.ts      package-lock.json   postcss.config.mjs  tsconfig.json


docker debug 명령으로 컨테이너 및 이미지 디버깅 방법 : https://labex.io/ko/tutorials/docker-how-to-use-docker-debug-command-to-debug-containers-and-images-555138

 

Docker 컨테이너 및 이미지 디버깅: docker debug 명령 사용법 | LabEx

docker debug 명령을 사용하여 슬림 컨테이너, 파일 수정, 디버그 툴박스 관리 등 Docker 컨테이너 및 이미지를 효과적으로 디버깅하는 방법을 알아보세요.

labex.io


docker exec ... bash 명령어가 작동하지 않는 이유는, alpine 이미지는 bash 또는 sh 와 같은 셀을 포함하지 않기 때문이다.


docker debug : https://docs.docker.com/reference/cli/docker/debug/

 

docker debug

 

docs.docker.com


With docker debug you can get a debug shell into any container or image, even if they don't contain a shell.
-> docker debug 를 이용하면, 쉘이 없는 컨테이너 또는 이미지를 디버그 쉘로 접속할 수 있다.

10) 실행시킨 컨테이너 중지 후 삭제, 이미지 삭제
- Windows PowerShell

PS C:\Users\admin\docker-next-server> docker stop 5cec
5cec
PS C:\Users\admin\docker-next-server> docker rm 5cec
5cec
PS C:\Users\admin\docker-next-server> docker ps -a
CONTAINER ID   IMAGE             COMMAND                  CREATED      STATUS                  PORTS     NAMES
47c438563cdb   my-server         "/bin/bash -c 'sleep…"   3 days ago   Exited (0) 3 days ago             nice_matsumoto
10b3825e00f9   my-node-server    "/bin/bash -c 'sleep…"   7 days ago   Exited (0) 7 days ago             pensive_ride
e8f1ab86997c   my-jdk17-server   "/bin/bash -c 'sleep…"   7 days ago   Exited (0) 7 days ago             tender_ride
PS C:\Users\admin\docker-next-server> docker image ls
                                                                                                                                                                                             i Info →   U  In Use
IMAGE                       ID             DISK USAGE   CONTENT SIZE   EXTRA
docker-next-server:latest   0dbe70a9c349       1.52GB          442MB
my-jdk17-server:beta        18e650b59b52        682MB          212MB
my-jdk17-server:latest      09a2803e5d8e        682MB          212MB    U
my-node-server:latest       9a1e49574c81       1.77GB          442MB    U
my-server:latest            c8dad74bef6b        157MB         41.6MB    U
PS C:\Users\admin\docker-next-server> docker image rm 0dbe
Untagged: docker-next-server:latest
Deleted: sha256:0dbe70a9c349d500cf26ad5eeb226ca86d3e0002a2229fbde5d620c323609d47
PS C:\Users\admin\docker-next-server> docker image ls
                                                                                                                                                                                             i Info →   U  In Use
IMAGE                    ID             DISK USAGE   CONTENT SIZE   EXTRA
my-jdk17-server:beta     18e650b59b52        682MB          212MB
my-jdk17-server:latest   09a2803e5d8e        682MB          212MB    U
my-node-server:latest    9a1e49574c81       1.77GB          442MB    U
my-server:latest         c8dad74bef6b        157MB         41.6MB    U

 

그림으로 이해하기



참고링크 : https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84?cid=334085

 

비전공자도 이해할 수 있는 Docker 입문/실전| JSCODE 박재성 - 인프런 강의

현재 평점 4.9점 수강생 14,477명인 강의를 만나보세요. 비전공자 입장에서도 쉽게 이해할 수 있고, 실전에서 바로 적용 가능한 Docker 입문/실전 강의를 만들어봤습니다! Docker 기본 개념, Spring Boot를

www.inflearn.com

댓글