SW 개발

Docker, Docker Compose 설치 및 사용법 정리

지단로보트 2023. 8. 3. 10:42

개요

  • 이번 글에서는 CentOS 7/8Amazon Linux 2023에서 docker, docker-compose를 설치하고 사용하는 방법을 정리했다.

Docker 설치

  • docker를 사용하면 운영체제와 독립적인 이미지를 인스턴스로 올려 컨테이너로 작동시킬 수 있다. 아키텍쳐의 구성 및 확정, 배포 방법이 비약적으로 간소화된다. CentOS 7/8Amazon Linux 2023에서의 설치 및 실행 방법은 아래와 같다.
# CentOS 7/8에서 Docker 설치
$ curl -fsSL https://get.docker.com/ | sh

# Amazon Linux 2023에서 Docker 설치
$ sudo dnf update
$ sudo dnf install docker -y

# Docker 서비스 시작
$ sudo systemctl start docker

# Docker 서비스 작동 상태 확인
$ sudo systemctl status docker

# Docker 서비스를 운영체제 부팅시 자동 시작하도록 설정
$ sudo systemctl enable docker

# docker 명령어를 sudo 없이 사용하기 위해 계정을 docker 그룹에 소속 (계정 재접속 필요)
$ sudo usermod -aG docker $USER
$ newgrp docker

# 설치된 Docker 버전 확인
$ docker --version
Docker version 20.10.25, build b82b9f3

# hello-world 컨테이너 실행 확인
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

Docker Compose 설치

  • docker의 단점은 애플리케이션마다 각각의 컨테이너로 독립적으로 실행된다는 것이다. 엔터프라이즈 레벨의 아키텍쳐에서는 여러 애플리케이션이 함께 실행되어 영향을 주고 받는 것이 흔하다. 이 것을 가능하게 하기 위해 docker-compose가 제공된다. 설치 방법은 아래와 같다.
# Docker Compose 설치
$ sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

# Docker Compose 실행 권한 부여
$ sudo chmod +x /usr/local/bin/docker-compose

# 설치된 Docker Compose 실행 확인
$ docker-compose --version
Docker Compose version v2.20.2

Docker 원격 저장소 로그인

  • 퍼블릭이 아닌 프라이빗 원격 저장소의 이미지를 풀링하고 푸시하려면 docker login 명령이 사전에 실행되어야 한다. [관련 링크]
# 기존 저장된 인증 정보를 삭제
$ rm ~/.docker/config.json

# 기존 로그인되어 있다면 로그아웃
$ docker logout

# [방법 1] DockerHub 사용자는 아래와 같이 로그인
$ docker login

# [방법 2] Amazon ECR 사용자는 아래와 같이 로그인 ({region}, {ecr-uri} 파라메터를 자신의 환경에 맞게 수정)
# Login Succeeded 가 출력되면 로그인 성공
$ docker login --username AWS -p $(aws ecr get-login-password --region {region}) {ecr-uri}/

Dockerfile 작성

  • 이미 제공되거나 만들어진 이미지를 그대로 사용하기도 하지만, 대부분의 배포 환경에서는 베이스 이미지를 기반으로 직접 Dockerfile을 작성하여 이미지를 빌드하고 컨테이너를 실행한다.
$ nano Dockerfile
FROM docker.io/jhipster/jhipster-registry:v7.1.0
EXPOSE 8761
USER root
RUN apt update -y
RUN apt install software-properties-common -y
RUN add-apt-repository ppa:deadsnakes/ppa -y
RUN apt install python3.9 -y
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["sh", "./entrypoint.sh"]
  • EXPOSE {port}는 해당 이미지가 리스닝해야할 포트를 사용자에게 알려주는 식별자 역할이다. 실제 물리적인 포트 개방에는 관여하지 않는다.
  • 마지막 줄은 반드시 CMD 또는 ENTRYPOINT가 작성되어야 한다. (RUNbuild 실행시 이미지에 반영되고, CMD, ENTRYPOINTrun 실행시 실행된다.)
  • entrypoint.sh는 반드시 리눅스 방식의 CR로 저장되어야 한다. 아닐 경우, dos2unix 명령어로 변환할 수 있다. [관련 링크]

이미지 빌드

# 이미지 빌드
$ docker build -t {image-name}:{tag-name} .

컨테이너 실행

  • 빌드된 이미지를 기반으로 docekr run 명령으로 컨테이너를 실행할 수 있다. 아래와 같이 다양한 옵션을 사용할 수 있다.
# 이미지 이름으로 컨테이너 실행
# [1. 로컬 2. Docker Hub]의 순서로 컨테이너를 찾아 실행
$ docker run -d {image-name}:{tag-name}
{container-id}

# -p, 로컬 포트에 컨테이너 포트를 맵핑
$ docker run --rm -it -p {local-port}:{container-port} {image-name}:{tag-name}

# -v, 로컬 파일을 컨테이너 파일에 주입
$ docker run --rm -it -v {local-full-path}:{container-full-path} {image-name}:{tag-name}

# --entrypoint, 컨테이너 실행과 함께 bash 쉘 접속
$ docker run --rm -it --entrypoint bash {image-name}:{tag-name}

# --user, 컨테이너 실행과 함께 root 계정으로 bash 쉘 접속
$ docker run --rm -it --user root --entrypoint bash {image-name}:{tag-name}
  • -d 옵션은 컨테이너를 데몬으로 실행시킨다. 실행과 함께 실행된 컨테이너의 ID를 출력한다.

실행 중인 컨테이너 콘솔 접속

  • 현재 실행 중인 컨테이너의 쉘에 접속할 수 있다.
# 현재 실행 중인 컨테이너 ID 목록 조회
$ docker ps

# 현재 실행 중인 특정 컨테이너에 bash 쉘 접속
$ docker exec -it {container-id} bash

# whoami
root

# pwd
/

원격 리파지터리에서 이미지 푸시

  • 로컬에 생성된 이미지를 원격 리파지터리에 푸시하는 방법은 아래와 같다.
# 로컬에 존재하는 이미지에 대해 원격 리파지터리 푸시를 위한 태그 생성
$ docker tag foo/bar:latest xxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/foo/bar

# 원격 리파지터리에 이미지를 푸시
$ docker push xxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/foo/bar

로컬의 모든 이미지, 컨테이너 일괄 삭제

  • 로컬 환경에서 개발을 하다보면 더이상 사용하지 않는 이미지, 컨테이너가 계속해서 쌓이게 된다. 아래 명령을 실행하면 한 번에 일괄 삭제가 가능하다.
# 로컬에 생성 또는 실행 중인 모든 이미지, 컨테이너 제거
$ docker system prune -a

docker-compose.yml 작성

  • Docker Compose를 이용하면 복수개의 컨테이너를 하나의 단위로 오케스트레이션할 수 있다. 아래는 MySQLRedis를 하나로 묶은 예이다.
$ nano docker-compose.yml
version: '3'
services:
  mysql:
    image: "public.ecr.aws/ubuntu/mysql:latest"
    environment:
      - MYSQL_USER=username
      - MYSQL_PASSWORD=password
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes
      - MYSQL_DATABASE=database
      - TZ=UTC
    ports:
      - "3306:3306"
    cap_add:
      - SYS_ADMIN
    restart: always

  redis:
    image: "public.ecr.aws/ubuntu/redis:latest"
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
      - TZ=UTC
    ports:
      - "6379:6379"
    restart: always
  • services.{service-name}.cap_add 옵션으로 해당 컨테이너에 root 유저 권한을 선택적으로 부여할 수 있다. 일반적으로 대부분의 이미지는 root 유저 권한으로 실행하는 것을 지양하거나 엄격하게 금지하고 있다. 이 경우 위 옵션을 통해 필요한 권한을 제한적으로 부여하여 일반 유저 계정으로도 이미지를 실행할 수 있다.
  • services.{service-name}.restart: always 옵션은 물리적인 호스트 인스턴스가 재부팅한 후에도 자동으로 해당 서비스를 실행할 수 있게 보장한다. (전제 조건으로 sudo systemctl enable docker 명령으로 Docker 서비스가 실행 중에 있고, 현재 docker-compose up -d 명령으로 서비스가 실행 중이어야 한다.) [관련 링크]

Docker Compose 기동

# Docker Compose 실행
$ docker-compose down && docker-compose build --pull && docker-compose up -d

# Docker Compose 로그 조회
$ docker-compose logs -f

참고 글