SSH키 발급받아서 SSH로 인스턴스 실행하기(그냥 인스턴스에 들어가서 연결해서도 실행가능)
# ssh키 파일인 pem이 위치한 경로에서 진행
$ ssh -i "[발급 받은 ssh.pem]" ubuntu[생성된 인스턴스 주소]
Docker 설치하기(Ubuntu 기반)
# ubuntu를 관리자 권한으로 실행
$ sudo -s
# docker 설치 전 업데이트 진행
$ sudo apt-get update
$ sudo apt-get upgrade
# docker 설치에 필요한 패키지 설치
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
# docker 공식 GPG키 추가
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# docker repository 생성
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# docker 엔진 설치
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli contianerd.io
# docker 서비스 시작
$ sudo systemctl start docker
# docker 서비스 상태 확인
$ sudo systemctl status docker
# docker 설치 확인
$ docker --version
$ which docker
💡 Docker 홈페이지에서 직접 Docker Desktop으로 설치해도 무방
$ brew install --cask docker
$ docker --version
# Docker version 20.10.24, build 297e128
# 위 메세지가 나온다면 정상적으로 설치 완료
# 혹은
$ which docker
# /usr/local/bin/docker
# 도커가 설치된 위치가 찍혀 나온다면 정상적으로 설치 완료
# 베이스 이미지를 지정한다.
# 해당 프로젝트는 node16 버젼에서 구동되는 것으로 셋팅
FROM node:16-alpine
# 작업 디렉토리를 지정한다.
# 작업 디렉토리를 지정하면 그 이후 모든 명령어는 해당 디렉토리를 기준으로 작동한다. cd 명령와 동일
WORKDIR /usr/app
# build명령 중간에 호스트의 파일 또는 폴더를 이미지에 가져오는 과정
# ADD 명령문도 역할은 같지만 좀 더 강력하게 사용가능한 명령문
COPY package.json .
COPY yarn.lock .
COPY tsconfig.json .
COPY . .
# 새로운 레이어에서 명령어를 실행하고 새로운 이미지를 생성한다.
RUN node --version
RUN yarn --version
RUN yarn install
RUN yarn build
# Dockerfile의 빌드로 생성된 이미지에서 열어줄 포트를 의미한다.
# 컨테이너 생성시 -p 옵션의 컨테이너 포트 값으로 EXPOSE의 값을 적어줘야한다.
EXPOSE 4000
# CMD와 ENTRYPOINT두가지로 나뉘는데 자세한 내용은 아래에서 후술하겠다.
CMD ["yarn", "start"]
Dockerfile에서 사용되는 주요 명령어
Dockerfile의 포맷은 INSTRUCTION arguments로 구성되어 있다.
INSTRUCTION은 대소문자 상관없으나 대문자로 쓰는것이 관례이다.
FROM
: 베이스 이미지MAINTAINER
: 이미지를 생성한 개발자의 정보(1.13.0 이후 사용 X)LABEL
: 이미지에 메타데이터를 추가(key-value 형태)RUN
: 새로운 레이어에서 명령어를 실행하고 새로운 이미지를 생성WORKDIR
: 작업 디렉토리를 지정한다. 해당 디렉토리가 없으면 새로 생성한다.EXPOSE
: Dockerfile의 빌드로 생성된 이미지에서 열어줄 포트를 의미한다.USER
: 이미지를 어떤 계정에서 실행하는지 지정COPY
/ ADD
: build 명령 중간에 호스트의 파일 또는 폴더를 이미지에 가져오는 것ADD
명령문은 좀 더 파워풀한 COPY
명령문으로 볼 수 있다.ADD
명령문은 일반 파일 분만 아니라 압축파일이나 네트워크 상의 파일도 사용할 수 있다.COPY
명령문을 사용하는 것이 권장된다.ENV
: 이미지에서 사용할 환경 변수 값을 지정한다.CMD
/ ENTRYPOINT
: 컨테이너를 생성 및 실행 할 때 실행할 명령어CMD
ENTRYPOINT
Dockerfile이 작성 됐다면 아래와 같은 명령어로 이미지를 빌드 할 수 있다.
$ docker build -t [이미지이름:버젼] [Dockerfile이 위치한 경로]
# 혹은
$ docker build -t [{제작자|조직이름}]/이미지이름:버젼] [Dockerfile이 위치한 경로]
# 이미지 이름 앞에 제작자나 개발자, 조직이름 등 누가 이미지를 만들었는지 명시하는 방법도 있음
# 이러한 방식을 활용하면 Docker Hub에서 쉽게 검색이 가능하다.
유의사항
💡 특히 Apple Silicon계열의 ARM기반 맥북에서는 빌드할 때 기본적으로 ARM64 아키텍쳐로 빌드가 되는데 이를 EC2에서는 작동되지 않는다.
AWS EC2는 기본적으로 AMD64를 지원하기 때문에 아키텍쳐를 별도로 맞춰서 빌드해야줘야 한다.
# AMD64로 빌드할 때 아래와 같이 빌드옵션에 --platform을 명시해준다.
$ docker build --platform linux/amd64 -t [이미지 이름:버젼] [Dockerfile이 위치한 경로]
# 참고 사항: 빌드된 이미지의 아키텍쳐 확인하기
$ docker inspect [imageID] | grep Architecture
# "Architecture": "arm64"
# AMD64로 빌드하고 위의 명령어로 아키텍쳐를 확인해보면 바뀌어서 나온다.
# "Architecture": "amd64",
3번의 과정을 통해서 빌드를 완료하게 되면 로컬에 이미지가 생성된다.
이 이미지를 개인적으로 활용한다고 하면 따로 Docker Hub에 올릴 필욘 없지만 EC2에 배포하기 위해선 Docker Hub에 올려야 한다.(Github Repository에 푸쉬하는 느낌)
# 로그인 하기
$ docker login
# Login with your Docker ID to push and pull images from Docker Hub.
# If you don't have a Docker, ID head over to https://hub.docker.com to create one.
# Username: [Docker Hub에 등록된 내 계정 이름]
# Password: [비밀번호 입력]
# Logging in with your password grants your terminal complete access to your account.
# 푸쉬할 때는 아래와 같이 해주면 끝
$ docker push [이미지이름:버젼]
Github처럼 Docker 이미지를 Hub에 푸쉬했다면 마찬가지로 Pull을 해서 다른 누군가가 내 이미지를 활용 할 수 있는데 이는 docker가 설치되어 있는 환경이라면 어디서나 내가 만든 이미지를 사용할 수 있다.
현재 EC2에서 내가 만든 서버 이미지를 가동 시킬 수 있도록 해보는것을 예시로 해보자
(EC2 인스턴스에 연결되어있고 로그인이 되어 있다는 가정 하에)
# pull도 마찬가지로 간단하게 가능
$ docker pull [이미지이름:버젼]
최종적으로 빌드된 이미지나 Pull 받은 이미지를 이제 실행시켜보자
# -p 옵션은 해당 이미지로 들어오는 요청의 port 번호를 내가 제작한 Dockerfile의 EXPOSE와 일치시켜준다.
# --name 옵션은 실행되는 컨테이너의 이름을 명시해준다.
$ docker run -p 80:4000 --name [컨테이너의 이름] [이미지이름:버젼]
# http의 기본 port는 80
# https의 기본 port는 443
컨테이너를 중단했다가 다시 실행할 때는 start명령어를 활용한다.
# start명령어를 실행할 때는 컨테이너의 ID를 기입한다.
$ docker start [containerID]
# ID를 확인하는 방법(실행중인 컨테이너)
$ docker ps
# ID를 확인하는 방법(실행/중단 된 모든 컨테이너)
$ docker ps -a
.dockerignore 파일은 .gitignore파일 같다.
.dockerignore에 파일들을 명시하면 말그대로 docker가 빌드할 때 해당 파일들은 같이 빌드 되지않고 빌드 컨텍스트에서 아예 제외가 되버린다.
ADD
와COPY
명령어에 영향을 받지 않는 파일로 이해하면 된다.
얕은 지식으로 글을 작성했습니다. 보완해야하거나 지적해주시는 부분은 항상 감사하게 받겠습니다.