인프라 입문기 - docker

kim unknown·2025년 1월 3일
0

Infra

목록 보기
1/2
post-thumbnail

글을 시작하기에 앞서,
나는 3년차 프론트엔드 개발자로, 그 동안 회사에서 프론트 개발 위주의 업무만 했었다.
당장 프론트만 해도 기술 트렌드가 금방금방 바뀌다보니 그거 따라잡기 바빴었다. (react 했다가 vue 했다가.. 다시 react+next하고 난리법석)
그러다가 이번에 이직을 하게 되었는데, 주니어로만 구성되어있던 전 직장과 달리 감사하게도 나 빼고 다 시니어 개발자분들로 개발팀이 구성되어 있었고 이번에 주니어로 내가 합류하게 되면서 많은 가르침을 받고 있다.
프론트엔드 개발자도 인프라에 대해 어느정도 알아두면 좋다며 docker, kubernetes, aws 등등 공부해보자 하셨고, 프로젝트가 잠시 여유있는 기간 동안 인프라에 대해 공부해보게 되었다. (즉 이 글은 인프라에 매우 무지한 프론트 개발자가 찍먹한 인프라를 기록용으로 쓰는 글이라는 점...ㅎㅎ)


1. 컨테이너와 도커, 쿠버네티스 개념 정리

컨테이너는 실행 환경까지 포함하여 독립적으로 프로그램을 실행할 수 있도록 도와주는 기술이다. 컨테이너 환경을 묶어서 배포한 컨테이너 이미지를 내려받아 구동하면 각종 설정 과정을 줄일 수 있다. 이러한 컨테이너를 사용할 때 필요한 도구가 컨테이너 런타임이며, 그 중 유명한 것이 도커이다.

*용어 정리
컨테이너 : 앱이 구동되는 환경까지 감싸서 실행할 수 있도록 하는 격리 기술
도커 : 컨테이너를 다루는 도구 (컨테이너 런타임)
쿠버네티스 : 컨테이너 런타임을 통해 컨테이너를 오케스트레이션하는 도구
오케스트레이션 : 여러 서버에 걸친 컨테이너 및 사용하는 환경 설정을 관리하는 행위


2. Docker 실습

Docker는 컨테이너를 사용해 애플리케이션을 실행하기 위한 플랫폼이다. 컨테이너는 애플리케이션과 필요한 모든 라이브러리, 의존성을 하나의 패키지로 묶어 운영체제에 독립적인 환경을 제공한다. 즉, 어떤 환경에서든 프로그램이 동일하게 운영되게 도와준다.

Docker Image는 컨테이너를 실행하기 위한 불변의 템플릿이다. 애플리케이션 코드, 라이브러리, 환경설정 파일 등을 하나의 이미지로 저장하는 것이다.


2-1. Dockerfile 작성

프로젝트 루트 위치에 Dockerfile 생성

> Dockerfile

# 베이스 이미지 선택
FROM node:22

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

# 패키지 파일 복사
COPY package*.json ./

# 의존성 설치
RUN npm install

# 애플리케이션 코드 복사
COPY . .

# 애플리케이션 실행
CMD ["npm", "start"]

# 컨테이너가 사용할 포트
EXPOSE 3000

2-1-1. docker-compose.yml 작성

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:3000"
    volumes:
      - ./app:/app
    environment:
      NODE_ENV: production

2-2. 도커 이미지 빌드

docker build -t <이미지_이름>:<태그> <경로>

 > docker build -t my-web:1.0 .

my-web : 이름으로 이미지 태깅
1.0 : 태그 정보
. : 현재 디렉토리를 빌드 컨텍스트로 사용

2-2-1. docker-compose로 이미지 빌드

docker-compose build


2-3. 빌드된 이미지 리스트 확인

docker images

> docker images

> 결과물
> REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
> my-web     1.0       2d22502f7d55   30 seconds ago   3.21GB

REPOSITORY: 이미지 이름
TAG: 이미지 태그
IMAGE ID: 이미지의 고유 ID
SIZE: 이미지 크기


2-4. 도커 컨테이너 실행

docker run -p <호스트_포트>:<컨테이너_포트> <이미지_이름>:<태그>

> docker run -p 8080:3000 my-web:1.0

p 8080:3000: 호스트의 8080번 포트를 컨테이너의 3000번 포트와 연결
my-web:1.0: 사용할 이미지 이름과 태그

동작 방식
∙호스트 포트 : 도커 컨테이너 외부에서 접근 시 사용되는 포트
∙컨테이너 포트 : 도커 컨테이너 내에서 실행되는 포트

호스트 포트를 통해 브라우저나 다른 클라이언트가 컨테이너 내 프로젝트에 접근한다. → 컨테이너는 내부적으로 3000번 포트에서 프로젝트를 실행하고 있으며, 외부에서 직접 접근 불가능하다. → 8080번 포트로 접근 시 컨테이너의 300번 포트로 요청이 전달된다.


2-5. 도커 컨테이너 로그 확인


2-6. 도커 볼륨

2-6-1. 볼륨 생성하기

docker volume create <볼륨 이름>

> docker volume create volumeTest

2-6-2. 생성된 볼륨 확인하기

// 볼륨 리스트 확인
> docker volume ls
> DRIVER    VOLUME NAME
> local     volumeTest

// 볼륨 정보 확인
> docker volume inspect volumeTest
> 
[
	{
		"CreatedAt": "2024-12-26T04:18:25Z",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/volumeTest/_data",
        "Name": "volumeTest",
        "Options": null,
        "Scope": "local"
	}
]

2-6-3. 컨테이너와 연결

> docker run -p 8080:3000 -v /Users/joy/log:/app/logs my-web:1.0

→ 확인

// 실행 중인 컨테이너 확인
> docker ps
> CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS                    NAMES
> 7cbce098572b   my-web:1.0   "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes   0.0.0.0:8080->3000/tcp   gifted_mclaren
    
> docker exec -it 7cbce098572b sh // 컨테이너 접속
> cd /app
> ls -l // 파일 리스트 확인
-rw-r--r--  1 root root    365 Dec 26 05:23 Dockerfile
-rw-r--r--  1 root root   1253 Dec 26 00:45 README.md
-rw-r--r--  1 root root    238 Dec 26 05:15 app.log
-rw-r--r--  1 root root    393 Dec 24 06:12 eslint.config.mjs
drwxr-xr-x  2 root root   4096 Dec 26 05:33 logs
-rw-r--r--  1 root root    228 Dec 24 06:17 next-env.d.ts
-rw-r--r--  1 root root    744 Dec 26 02:15 next.config.mjs
drwxr-xr-x  1 root root  16384 Dec 26 05:32 node_modules
-rw-r--r--  1 root root 298276 Dec 26 00:13 package-lock.json
-rw-r--r--  1 root root    807 Dec 26 00:13 package.json
-rw-r--r--  1 root root    135 Dec 24 06:12 postcss.config.mjs
drwxr-xr-x  2 root root   4096 Dec 24 06:12 public
drwxr-xr-x 12 root root   4096 Dec 24 06:22 src
-rw-r--r--  1 root root   4328 Dec 26 00:37 tailwind.config.ts
-rw-r--r--  1 root root    602 Dec 24 06:12 tsconfig.json
> exit
    
// 로그 파일 생성 확인
> ls /Users/joy/log

2-7. 도커 이미지 업로드 (docker hub / aws)

2-7-1. dockerhub에 이미지 업로드하기

(1). 도커 로그인

> docker login
> Authenticating with existing credentials...
> Login Succeeded

(2). 이미지 태그 지정

docker tag <로컬_이미지> <dockerhub_사용자명>/<리포지토리_이름>:<태그>

> docker tag my-web:1.0 joy/my-web:1.0

(3). 이미지 푸시

docker push <dockerhub_사용자명>/<리포지토리_이름>:<태그>

> docker push joy/my-web:1.0
   
>
The push refers to repository [docker.io/joy/my-web]
...
92b12b0dccf2: Pushed 
fd63102cac36: Pushed 
1.0: digest: sha256:209aff250058014a9c073d2a311ee9644ca2d98221105d6f741aa3a7b712b0e3 size: 856

(4). dockerhub 업로드 확인

2-7-2. aws erc 에 이미지 업로드하기

(1). aws configure 설정

> aws configure
> AWS Access Key ID [None]:
> AWS Secret Access Key [None]:
> Default region name [None]: ap-northeast-2
> Default output format [None]: 
    
// 작업 증명 활성화 홧인
> aws sts get-caller-identity
> 
{
    "UserId": "",
    "Account": "",
    "Arn": ""
}
    

(2). ecr 레포지토리 생성

(3). aws ecr 로그인

aws ecr create-repository --repository-name <리포지토리_이름> --region <리전_이름>

> aws ecr get-login-password --region ap-southeast-2 | docker login --username ~~~             
> Login Succeeded

(4). 이미지 태그 변경

docker tag <로컬_이미지_이름>:<태그> <AWS_Account_ID>.dkr.ecr.<리전_이름>.amazonaws.com/<리포지토리_이름>:<태그>

> docker tag my-web:1.0 ~~~

(5). 이미지 푸시

docker push <AWS_Account_ID>.dkr.ecr.<리전_이름>.amazonaws.com/<리포지토리_이름>:<태그>

> docker push ~~~
    
> The push refers to repository ~~~
...
3981e863d195: Pushed 
92b12b0dccf2: Pushed 
ff27b22d4715: Pushed 
7bd0f29b7dc7: Pushed 
1.0: digest: sha256:209aff250058014a9c073d2a311ee9644ca2d98221105d6f741aa3a7b712b0e3 size: 856

(6). 이미지 업로드 확인

profile
과거의 나에게 묻기 위한 기록

0개의 댓글