Skip to content

Commit 6babfca

Browse files
committed
docs: Docker 문서에서 Next.js standalone 빌드 방식으로 Docker 이미지를 빌드하는 예제로 변경
1 parent dc22fba commit 6babfca

File tree

6 files changed

+77
-89
lines changed

6 files changed

+77
-89
lines changed

_posts/2024-11-06-docker.md

Lines changed: 77 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -362,25 +362,42 @@ docker compose logs
362362

363363
Docker 이미지를 빌드하기 위해선 먼저 `Dockerfile`을 작성해야 합니다. 저는 제가 현재 진행하고 있는 Next.js 애플리케이션을 기준으로 Docker 이미지를 생성하겠습니다.
364364

365+
### Next.js standalone
366+
367+
`Next.js` 애플리케이션에서 어떠한 설정을 하지 않고 Docker 이미지를 빌드하는 경우 다음과 같이 Docker 이미지 용량이 매우 커집니다.
368+
369+
<img src="/assets/img/raspberry-pi/docker/pic12.avif" alt="pic12" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); border-radius: 0.5rem"/>
370+
371+
`Next.js`에서는 프로덕션 배포에 필요한 파일만 포함해 Docker를 활용한 배포에 유용한 빌드 방식인 `standalone`을 지원합니다. 다음 사진과 같이 `next.config.mjs` 파일에서 `output: "standalone"`을 설정합니다.
372+
373+
<img src="/assets/img/raspberry-pi/docker/pic11.avif" alt="pic11" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); border-radius: 0.5rem"/>
374+
365375
### .dockerignore 생성하기
366376

367377
`.dockerignore` 파일은 Docker가 이미지를 빌드할 때 복사하지 말아야 할 파일이나 디렉토리를 지정하는 파일입니다. 이 파일은 Docker Context 내에 불필요한 파일들이 빌드 이미지에 포함되는 것을 방지하여, 빌드 속도를 높이고 이미지 크기를 줄이는 데 중요한 역할을 합니다.
368378

369379
`Dockerfile`을 작성하기 전에 프로젝트 최상단 디렉토리에서 `.dockerignore` 파일을 생성하고 다음과 같이 작성합니다.
370380

371381
```bash
372-
# Node.js 환경
382+
# 의존성 파일
373383
node_modules
374384

375385
# Git 관련 파일
376386
.git
377387
.gitignore
378-
379-
# 환경 설정 파일
380-
.env
388+
.github
381389

382390
# Next.js 빌드 결과물
383391
.next
392+
393+
# 기타
394+
.eslintrc.json
395+
.prettierrc.json
396+
LICENSE
397+
README.md
398+
build.sh
399+
Dockerfile
400+
.dockerignore
384401
```
385402

386403
위의 내용을 설명하자면 다음과 같습니다.
@@ -389,18 +406,18 @@ node_modules
389406

390407
Node.js의 의존성 파일이 저장된 디렉토리로, 보통 컨테이너 안에서 생성하므로 복사할 필요가 없습니다.
391408

392-
- `.git` `.gitignore`
409+
- `.github`, `.git`, `.gitignore`
393410

394411
Git 관련 파일을 컨테이너 안에 포함할 필요가 없습니다.
395412

396-
- `.env`
397-
398-
환경 변수 정보는 보통 보안 상의 이유로 컨테이너 이미지에 포함하지 않는 것이 좋습니다.
399-
400413
- `빌드 결과물`
401414

402415
빌드 후 생성되는 파일이 저장된 디렉토리로, 보통 컨테이너 안에서 빌드 과정이 필요한 경우 컨테이너 안에서 생성하므로 복사할 필요가 없습니다.
403416

417+
- `기타`
418+
419+
애플리케이션 실행에 필요하지 않은 파일을 제외합니다.
420+
404421
`.dockerignore` 파일을 사용했을 때의 장점은 다음과 같습니다.
405422

406423
- `속도 향상`
@@ -424,6 +441,12 @@ Docker 이미지를 생성하기 위해선 먼저 `Dockerfile`을 작성해야
424441
이후 프로젝트 최상단 디렉토리에서 `Dockerfile` 파일을 생성합니다. 다음은 Next.js 애플리케이션을 빌드하고 실행하는 Dockerfile 예시입니다.
425442

426443
```docker
444+
###############################################################################################################
445+
# #
446+
# Notice: 해당 Dockerfile을 사용하기 위해선 먼저 next.config.mjs 파일에서 output이 "standalone"으로 설정되어야 합니다. #
447+
# #
448+
###############################################################################################################
449+
427450
# 1. 빌드 단계
428451
# 생성할 Docker 이미지의 베이스가 되는 이미지를 지정합니다.
429452
FROM node:20-alpine AS build
@@ -438,26 +461,22 @@ COPY package.json package-lock.json ./
438461
439462
# 1-3. 의존성 설치
440463
# 컨테이너 안에서 명령어를 실행하고 이미지를 빌드합니다.
441-
RUN npm install --force
464+
RUN npm install
442465
443466
# 1-4. 애플리케이션 코드 복사
444467
# 현재 디렉토리의 모든 파일을 /app 디렉토리로 복사합니다.
445468
COPY . .
446469
447-
# 1-5. 환경 변수 설정
448-
ENV NEXT_PUBLIC_BACKEND_URL=https://mafiacamp.p-e.kr
449-
450-
# 1-6. 애플리케이션 빌드
470+
# 1-5. 애플리케이션 빌드
451471
RUN npm run build
452472
453473
# 2. 런타임 단계
454474
FROM node:20-alpine
455475
456476
# 2-1. 빌드 결과물과 필요한 파일만 복사
457477
WORKDIR /app
458-
COPY --from=build /app/.next ./.next
459-
COPY --from=build /app/node_modules ./node_modules
460-
COPY --from=build /app/package.json ./package.json
478+
COPY --from=build /app/.next/standalone ./
479+
COPY --from=build /app/.next/static ./.next/static
461480
COPY --from=build /app/public ./public
462481
463482
# 2-2. 포트 설정
@@ -467,13 +486,13 @@ EXPOSE 3000
467486
# 2-3. 애플리케이션 실행
468487
# 컨테이너가 시작될 때 실행할 기본 명령어를 지정합니다.
469488
# CMD는 Dockerfile에서 한 번만 사용할 수 있습니다.
470-
CMD [ "npm", "run", "start" ]
489+
CMD [ "node", "server.js" ]
471490
```
472491

473492
`Dockerfile`을 작성한 후 다음 명령어를 입력하여 Docker 이미지를 빌드합니다.
474493

475494
```bash
476-
docker build -t mafiacamp-fe .
495+
docker build -t solitour-frontend:v1.1.0 .
477496
```
478497

479498
각 단계를 자세히 설명하자면 다음과 같습니다.
@@ -523,13 +542,11 @@ COPY package.json package-lock.json ./
523542
```docker
524543
# 1-3. 의존성 설치
525544
# 컨테이너 안에서 명령어를 실행하고 이미지를 빌드합니다.
526-
RUN npm install --force
545+
RUN npm install
527546
```
528547

529548
`RUN`은 컨테이너 안에서 명령어를 실행할 때 사용하는 명령어입니다. 위의 예시에서는 `npm install` 명령어로 `package.json`에 지정된 의존성을 설치합니다.
530549

531-
참고로 `--force` 옵션을 사용한 이유는 `Next.js v15.0.2`를 기준으로 `React 19 RC`를 사용하고 있기 때문에 라이브러리 설치가 안되는 문제를 방지하기 위해 추가하였습니다. 불필요한 경우 `--force` 옵션을 제외하면 됩니다.
532-
533550
<br />
534551

535552
**1-4. 애플리케이션 코드 복사**
@@ -544,21 +561,10 @@ COPY . .
544561

545562
<br />
546563

547-
**1-5. 환경 변수 설정**
548-
549-
```docker
550-
# 1-5. 환경 변수 설정
551-
ENV NEXT_PUBLIC_BACKEND_URL=https://mafiacamp.p-e.kr
552-
```
553-
554-
`ENV`는 환경 변수를 설정하는 명령어입니다. [위에서 생성한 .dockerignore 파일](#dockerignore-생성하기)에는 `.env` 파일을 제외하도록 설정하였기 때문에 애플리케이션 빌드 전에 필요한 환경 변수를 설정해야 합니다.
555-
556-
<br />
557-
558-
**1-6. 애플리케이션 빌드**
564+
**1-5. 애플리케이션 빌드**
559565

560566
```docker
561-
# 1-6. 애플리케이션 빌드
567+
# 1-5. 애플리케이션 빌드
562568
RUN npm run build
563569
```
564570

@@ -582,9 +588,8 @@ FROM node:20-alpine
582588
```docker
583589
# 2-1. 빌드 결과물과 필요한 파일만 복사
584590
WORKDIR /app
585-
COPY --from=build /app/.next ./.next
586-
COPY --from=build /app/node_modules ./node_modules
587-
COPY --from=build /app/package.json ./package.json
591+
COPY --from=build /app/.next/standalone ./
592+
COPY --from=build /app/.next/static ./.next/static
588593
COPY --from=build /app/public ./public
589594
```
590595

@@ -610,10 +615,10 @@ EXPOSE 3000
610615
# 2-3. 애플리케이션 실행
611616
# 컨테이너가 시작될 때 실행할 기본 명령어를 지정합니다.
612617
# CMD는 Dockerfile에서 한 번만 사용할 수 있습니다.
613-
CMD [ "npm", "run", "start" ]
618+
CMD [ "node", "server.js" ]
614619
```
615620

616-
`CMD`는 컨테이너가 시작될 때 실행할 명령어를 지정하는 명령어입니다. `CMD`는 하나의 Dockerfile 안에서 한 번만 사용할 수 있습니다. 위의 예시에서는 `npm run start` 명령어를 실행하여 Next.js 애플리케이션을 실행합니다.
621+
`CMD`는 컨테이너가 시작될 때 실행할 명령어를 지정하는 명령어입니다. `CMD`는 하나의 Dockerfile 안에서 한 번만 사용할 수 있습니다. 위의 예시에서는 `node server.js` 명령어를 실행하여 Next.js 애플리케이션을 실행합니다.
617622

618623
<br />
619624

@@ -622,53 +627,54 @@ CMD [ "npm", "run", "start" ]
622627
Dockerfile이 있는 디렉토리에서 터미널을 열고 다음 명령어를 입력하여 Docker 이미지를 빌드합니다.
623628

624629
```bash
625-
docker build -t mafiacamp-fe .
630+
docker build -t solitour-frontend:v1.1.0 .
626631
```
627632

628633
아래 결과는 위의 `Dockerfile`을 기반으로 Docker 이미지를 빌드한 결과 예시입니다.
629634

630635
```bash
631-
PS C:\Users\user\문\vscode\web12-MafiaCamp\FE> docker build -t mafiacamp-fe .
632-
[+] Building 140.9s (15/15) FINISHED docker:desktop-linux
633-
=> [internal] load build definition from Dockerfile 0.0s
634-
=> => transferring dockerfile: 1.93kB 0.0s
635-
=> [internal] load metadata for docker.io/library/node:20-alpine 1.8s
636-
=> [internal] load .dockerignore 0.0s
637-
=> => transferring context: 174B 0.0s
638-
=> [build 1/6] FROM docker.io/library/node:20-alpine@sha256:c13b26e7e602ef2f1074aef304ce6e9b7dd284c419b35d89fcf3cc8e44a8def9 0.0s
639-
=> => resolve docker.io/library/node:20-alpine@sha256:c13b26e7e602ef2f1074aef304ce6e9b7dd284c419b35d89fcf3cc8e44a8def9 0.0s
640-
=> [internal] load build context 0.0s
641-
=> => transferring context: 6.29kB 0.0s
642-
=> CACHED [build 2/6] WORKDIR /app 0.0s
643-
=> CACHED [build 3/6] COPY package.json package-lock.json ./ 0.0s
644-
=> CACHED [build 4/6] RUN npm install --force 0.0s
645-
=> [build 5/6] COPY . . 0.2s
646-
=> [build 6/6] RUN npm run build 77.1s
647-
=> [stage-1 3/6] COPY --from=build /app/.next ./.next 1.2s
648-
=> [stage-1 4/6] COPY --from=build /app/node_modules ./node_modules 4.5s
649-
=> [stage-1 5/6] COPY --from=build /app/package.json ./package.json 0.2s
650-
=> [stage-1 6/6] COPY --from=build /app/public ./public 0.1s
651-
=> exporting to image 45.0s
652-
=> => exporting layers 33.8s
653-
=> => exporting manifest sha256:1cbf4b5bee24744bfe02047906dab35edfd26e2d7e859d2d48126d5976948c26 0.0s
654-
=> => exporting config sha256:d667149ae2af3795ca5b414568d640435664cb894727eb73af12f28b220ae24e 0.0s
655-
=> => exporting attestation manifest sha256:a445a77eb5e50e332d06b5145d3437746bcb35a2f7f3596b9b277c089bab4dad 0.0s
656-
=> => exporting manifest list sha256:d3e238644af5f4a6d2a27b9fc4051e83d1fb8f133120608debaebc30f9f8c0a2 0.0s
657-
=> => naming to docker.io/library/mafiacamp-fe:latest 0.0s
658-
=> => unpacking to docker.io/library/mafiacamp-fe:latest 11.0s
636+
PS C:\Users\user\vscode\solitour-frontend> docker build -t solitour-frontend:v1.1.0 .
637+
[+] Building 130.2s (14/14) FINISHED docker:desktop-linux
638+
=> [internal] load build definition from Dockerfile 0.1s
639+
=> => transferring dockerfile: 2.07kB 0.0s
640+
=> [internal] load metadata for docker.io/library/node:20-alpine 2.0s
641+
=> [internal] load .dockerignore 0.0s
642+
=> => transferring context: 256B 0.0s
643+
=> [internal] load build context 0.2s
644+
=> => transferring context: 37.71kB 0.2s
645+
=> [build 1/6] FROM docker.io/library/node:20-alpine@sha256:053c1d99e608fe9fa0db6821edd84276277c0a663cd181f4a3e59ee20f5f07ea 0.0s
646+
=> => resolve docker.io/library/node:20-alpine@sha256:053c1d99e608fe9fa0db6821edd84276277c0a663cd181f4a3e59ee20f5f07ea 0.0s
647+
=> CACHED [build 2/6] WORKDIR /app 0.0s
648+
=> CACHED [build 3/6] COPY package.json package-lock.json ./ 0.0s
649+
=> CACHED [build 4/6] RUN npm install 0.0s
650+
=> [build 5/6] COPY . . 1.5s
651+
=> [build 6/6] RUN npm run build 114.9s
652+
=> [stage-1 3/5] COPY --from=build /app/.next/standalone ./ 0.8s
653+
=> [stage-1 4/5] COPY --from=build /app/.next/static ./.next/static 0.2s
654+
=> [stage-1 5/5] COPY --from=build /app/public ./public 0.2s
655+
=> exporting to image 5.4s
656+
=> => exporting layers 3.5s
657+
=> => exporting manifest sha256:343b66796797d47af85f9439352ac3970a45f0ab0c09061ee1884c6b0be46ed0 0.0s
658+
=> => exporting config sha256:0fba297b2ce1a37d4b3752a1f0d08eec1421da635cc1a4e73c486ca2a763eef6 0.0s
659+
=> => exporting attestation manifest sha256:2b1c02b349dc52fecd6a415c50aa0fb34d9fa3dc61291cc46631e479fe7cf225 0.0s
660+
=> => exporting manifest list sha256:fdb0336a57551b95032c4dc8cc4485e33d0369b4fa8c7ec9b6d5ca81b5f323f3 0.0s
661+
=> => naming to docker.io/library/solitour-frontend:v1.1.0 0.0s
662+
=> => unpacking to docker.io/library/solitour-frontend:v1.1.0 1.7s
659663
```
660664

665+
<img src="/assets/img/raspberry-pi/docker/pic7.avif" alt="pic7" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); border-radius: 0.5rem"/>
666+
661667
## Step 6 - 컨테이너 실행하기
662668

663669
Docker 이미지가 빌드된 후 다음 명령어를 입력하여 컨테이너를 실행합니다.
664670

665671
```bash
666-
docker run -p 3000:3000 --rm mafiacamp-fe
672+
docker run -p 3000:3000 --rm solitour-frontend:v1.1.0
667673
```
668674

669675
컨테이너를 실행한 결과는 다음과 같습니다.
670676

671-
<img src="/assets/img/raspberry-pi/docker/pic7.avif" alt="pic7" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); border-radius: 0.5rem"/>
677+
<img src="/assets/img/raspberry-pi/docker/pic10.avif" alt="pic10" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); border-radius: 0.5rem"/>
672678

673679
## 참고 자료
674680

_posts/2025-02-07-typescript.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ TypeScript</p></blockquote>
1919

2020
`타입스크립트(TypeScript)`에 대해 정리한 페이지입니다.
2121

22-
<b>타입스크립트 개념이 방대하므로 지속적으로 업데이트하는 중입니다.</b>
23-
2422
## 타입스크립트란?
2523

2624
`타입스크립트(TypeScript)`란 자바스크립트에 타입을 추가한 언어입니다. 타입스크립트는 타입을 지정하지 않고 인터프리터가 타입을 유추하는 `동적 타입` 언어인 자바스크립트와 달리, 타입이 같지 않다면 컴파일 에러를 내는 `강 타입` 언어입니다. 확장자로는 `.ts`를 사용하며, 자바스크립트로 컴파일(트랜스파일)되는 언어입니다.
@@ -771,22 +769,6 @@ const person: Readonly<Person> = {
771769
person.name = "HyunJin"; // Error: Cannot assign to 'name' because it is a read-only property.ts(2540)
772770
```
773771

774-
### 데코레이터
775-
776-
// TODO
777-
778-
### satisfies
779-
780-
// TODO
781-
782-
### enum
783-
784-
// TODO
785-
786-
### 타입 추론
787-
788-
// TODO
789-
790772
## 참고 자료
791773

792774
- <a href="https://velog.io/@jee/%EA%B0%95%ED%83%80%EC%9E%85%EA%B3%BC-%EC%95%BD%ED%83%80%EC%9E%85-%ED%98%B9%EC%9D%80-%EC%A0%95%EC%A0%81%ED%83%80%EC%9E%85%EA%B3%BC-%EB%8F%99%EC%A0%81%ED%83%80%EC%9E%85" target="_blank">강타입과 약타입 혹은 정적타입과 동적타입</a>
90.8 KB
Binary file not shown.
28.2 KB
Binary file not shown.
8.2 KB
Binary file not shown.
-12.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)