Ssul's Blog

도커(Docker)에서 쿠버네티스(k8s)까지: #2. Dockerfile, Dockerhub 본문

AI & ML/학습하기

도커(Docker)에서 쿠버네티스(k8s)까지: #2. Dockerfile, Dockerhub

Ssul 2024. 5. 26. 22:27

지난 글을 통해서,

Docker 이미지만 있으면 쉽게 서비스를 실행할 수 있는 것을 알게 되었다.

docker run httpd

간단한 웹서비스 바로 사용 가능.

 

그렇다면 우리가 만든 서비스 역시

- 이미지로 만들고,

- 그 이미지를 docker run <이미지> 를 실행(이미지로 컨테이너 만드는 과정포함)하면

- 바로 서비스가 가능한 것이 docker의 매력이다.

 

그러면 지금부터는 내가만든 웹서비스(프론트앤드/백앤드)를

1. 이미지로 만들고,

2. 그 이미지를 관리(토커허브)하고,

3. 이미지를 가져와서, 컨테이너를 만들고

4. 서비스를 실행

까지 알아보도록 하겠다.

 

0. Docker이미지 생성하기

public에 올려진 이미지를 컨테이너로 만들어 사용할수 있지만,

내가 만든 백엔드/프론트엔드 서비스는 내가 이미지로 만들어야 한다.

그 방법을 알아보자.

 

1. Dockerfile 작성

파이썬 장고(Django)로 백앤드 서버를 제작했다. 그럼 manage.py 파일이 있는 폴더에, Dockerfile을 생성한다.

# 운영체제로 우분투를 설치합니다
FROM ubuntu:20.04

# 필요한 프로그램을 설치합니다(파이썬 등)
RUN apt-get update && apt-get install -y python3-pip libpq-dev && apt-get clean

# 폴더를 만들고,
WORKDIR /project
# 해당 폴더에 현재 디렉토리에 있는 파일/폴더를 복사합니다.
ADD . /project

# pip로 requirements에 있는 라이브러리를 설치합니다
RUN pip3 install -r requirements.txt

#환경변수를 설정합니다
ENV DATABASE_NAME=testdb
ENV PYTHONUNBUFFERED=1

# 서버를 실행하기 위한 포트를 열어줍니다.
EXPOSE 8000

# 컨테이너가 실행될 때 실행될 명령어를 지정합니다.
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]

 

react로 개발한 프론트도 동일하게 프로젝트 폴더에 들어가서 Dockerfile을 생성합니다.

# 이미지를 가져옵니다.
FROM ubuntu:20.04

# 필요한 소프트웨어를 설치합니다.
RUN apt-get update && \
    apt-get install -y curl

# Node.js 설치
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

# 어플리케이션 디렉토리를 생성합니다.
WORKDIR /usr/src/app

# 애플리케이션 의존성 설치
# package.json 과 package-lock.json 또는 yarn.lock을 복사합니다.
COPY package*.json ./

# 패키지를 설치합니다.
RUN npm install

# 환경 변수를 설정합니다.
ENV SERVER_SIDE_API_URL=http://ooo.net

# 애플리케이션 소스를 복사합니다. 또는 ADD
COPY . .

# 애플리케이션 빌드
RUN npm run build

# 서버를 실행하기 위한 포트를 열어줍니다.
EXPOSE 3000

# 컨테이너가 실행될 때 실행될 명령어를 지정합니다.
CMD [ "npm", "run", "start" ]

 

2. 도커 이미지 생성

docker build -t imagename:0.1 . #태그 생성하여 이미지 만들기

#m1과 같이, 실리콘 맥의 경우
docker buildx build --platform linux/amd64 -t imagename:0.1 . #m1에서 ubuntu용으로

이렇게 해야, 우분투로 만든 aws서버에서 도커이미지 가져와서, 컨테이너 만들어 서버 실행시 에러없음

 

 

3. 이미지로 컨테이너 만들어 서버실행

#imagename:0.1버전의 이미지로 컨테이너 만들고,
# publish: 9000포트로 받아서, 컨테이너 8000포트로 연결
# rm: 컨테이너 종료시 컨테이너 자동삭제(rm이 없으면 계속 컨테이너가 쌓이게 됨)
docker run --rm --publish 9000:8000 imagename:0.1

#컨테이너 안으로 들어가기, bin/bash도 가능
docker run --rm --publish 9000:8000 -it imagename:0.1 sh

# d: (detach) 백그라운드에서 실행
docker run -d --rm --publish 9000:8000 imagename:0.1

 

Dockerfile에 환경변수를 써 놓으면 보안상 위험한 정보들은, 컨테이너 실행시 써주면 된다.

-e 옵션을 사용하면 되며, 해당 환경변수는 Dockerfile의 환경변수보다 우선순위가 높다

docker run --rm --publish 9000:8000 \
	-e DATABASE_NAME=db \
	-e DATABASE_USERNAME=sdfdb \
	-e DATABASE_PASSWORD=sdf123 \
	-e DATABASE_HOST=xxxx.rds.amazonaws.com \
	-e DATABASE_PORT=5432 \
	-e OPENAI_API_KEY=xxxx \
	-e APP_ENV="production" \
imagename:0.1

 

4. 이미지 관리(도커허브)

Docker이미지는 깃허브처럼 버전관리를 할수 있다.

내가 로컬에서 만든 이미지를 도커허브(https://hub.docker.com/)에 올린다

#로컬의 도커이미지를 태그합니다
docker tag imagename:0.1 dockerhubid/imagename:0.1

#태그된 도커이미지를 허브에 올립니다.
docker push dockerhubid/imagename:0.1

 

5. Docker허브에서 이미지 가져와서 서버 실행하기

Docker허브에 업로드를 성공한 나의 이미지를 가져와서, EC2서버에서 서비스를 실행한다.

 

우선 EC2를 만들고, EC2(우분투)에 도커를 설치한다(검색하여 최신 정보로 할것)

$ sudo apt-get update
$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg
    
$ sudo mkdir -m 0755 -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

 

도커 설치를 마쳤으니, 도커허브에서 나의 이미지를 가져오자(pull)

sudo docker pull dockerhubid/imagename:0.1

 

이미지를 가져왔으니, 로컬에서 했던것처럼, 컨테이너를 만들어서 서비스를 실행하자

sudo docker run --rm --publish 80:3000 dockerhubid/imagename:0.1

 

 

6. docker 리소스 정리 명령어들

탐색/멈추기/삭제 등 명령어 정리

#실행되고 있는 컨테이너 조회
docker ps

#컨테이너가 출력한 로그 조회(접속이나, 서버상태 등)
docker logs 컨테이너명

# 컨테이너의 네트워크정보 포함된 정보 조회
docker inspect 컨테이너명

#컨테이너 이름 지정해서 실행하기
docker run -d --rm --name 컨테이너명 imagename:0.1

# 컨테이너 종료
docker stop 컨테이너명

# 컨테이너 삭제
docker rm 컨테이너명

# 이미지 삭제
docker rmi imagename:0.1

# 컨테이너 전체삭제
docker container prune

# 이미지 전체삭제
docker image prune -a

# 실행중인 컨테이너 검색
docker ps -a

# 다운받은 이미지 검색
docker images