Docker의 개념과 사용 방법
Docker의 개념과 사용 방법에 대해 설명하는 페이지입니다.
Tags
Raspberry Pi, Linux, Docker
Environment
OS: Raspberry Pi OS (64 bit)
개요
이번 글에서는 Docker에 대해 설명하겠습니다.
Docker란?
Docker
란 컨테이너 기반의 가상화 기술로, 애플리케이션과 그 환경을 이미지(Image)
라는 단위로 패키지를 만들어 일관적으로 실행할 수 있도록 합니다. 이를 통해 개발자는 애플리케이션과 필요한 모든 종속성을 포함하는 패키지를 만들 수 있습니다. 이 패키지는 개발 환경, 테스트 환경, 배포 환경 어디서든 일관적으로 실행되므로 배포 환경과 개발 환경 간의 차이로 인한 문제를 줄일 수 있습니다.
Docker의 주요 개념
Docker의 주요 개념은 다음과 같습니다.
이미지(Image)
애플리케이션과 그 환경을 실행하기 위한 모든 설정, 라이브러리, 코드 등을 포함하는 일종의 템플릿입니다. 이미지는 불변(Immutable)하여 수정되지 않으며,
Dockerfile
이라는 설정 파일을 통해 정의됩니다. 이미지를 기반으로 컨테이너를 실행할 수 있습니다.컨테이너(Container)
이미지를 실행한 상태로, 애플리케이션이 동작하는 독립적인 환경입니다. 여러 컨테이너를 하나의 호스트에서 독립적으로 실행할 수 있으며, 서로 간섭 없이 작동합니다. 컨테이너는 가볍고 빠르게 생성 및 삭제할 수 있으며, 시스템 자원을 더 효율적으로 사용합니다.
Dockerfile
이미지를 만들기 위한 설정 파일로, 특정 환경에서 애플리케이션을 실행하는 데 필요한 명령어를 정의합니다. 이를 통해 개발자는 일관된 환경을 자동으로 구축할 수 있습니다.
Docker Hub
Docker 이미지를 저장하고 공유할 수 있는 Registry로, 공식 이미지나 다른 개발자들이 만들어 공유한 이미지들을 다운로드하거나 사용할 수 있습니다. 예를 들어
docker pull node
명령어를 입력하면Node.js
공식 이미지를 가져올 수 있습니다.
Docker의 장점
Docker의 장점은 다음과 같습니다.
일관성
개발, 테스트, 배포 환경에서 동일한 환경을 유지하여 호환성 문제를 줄일 수 있습니다.
빠른 배포와 확장성
컨테이너를 사용하면 애플리케이션을 쉽게 확장하고 빠르게 배포할 수 있으므로 DevOps와 CI/CD 파이프라인에서 유용합니다.
경량성
운영 체제 전체를 가상화하는
VM(Virtual Machine, 가상 머신)
과 다르게, Docker는 애플리케이션과 필요한 종속성만을 포함하는 가벼운 환경을 제공함으로써 VM보다 가볍고, 자원을 더 효율적으로 사용할 수 있어 성능이 우수합니다.유연성
Docker 이미지를 기반으로 여러 개의 컨테이너를 구동할 수 있으며, 각 컨테이너는 독립적으로 동작하므로 다양한 애플리케이션을 쉡게 분리하고 관리할 수 있습니다.
Docker Compose란?
Docker Compose
는 여러 Docker 컨테이너를 쉽게 정의하고 함께 관리할 수 있게 해주는 도구입니다. Docker Compose를 사용하면 여러 컨테이너가 필요한 애플리케이션 설정을 YAML 파일로 정의하고, 한 번의 명령으로 애플리케이션 전체를 실행할 수 있습니다.
Docker Compose를 사용하면 좋은 경우는 복수의 컨테이너를 실행해야 하는 경우입니다. 예를 들어, 웹 서버와 데이터베이스가 함께 필요한 애플리케이션에서 웹 서버와 데이터베이스 각각을 별도의 컨테이너로 구성하고 실행하는 경우, Docker Compose를 사용하지 않으면 두 컨테이너 간 통신을 위한 네트워크를 구축하고 각각의 이미지를 docker run
명령어로 실행해야 합니다. 반면에 Docker Compose를 사용하면 docker-compose.yml
파일에 서비스(컨테이너), 네트워크, 볼륨 등의 설정을 정의하고, docker compose up
명령어 하나로 필요한 모든 컨테이너를 한 번에 실행할 수 있습니다.
Docker Compose의 주요 개념
Docker Compose의 주요 개념은 다음과 같습니다.
서비스(Services)
각각의 컨테이너를 구성하는 부분을 의미합니다.
네트워크(Networks)
서비스들간의 통신을 정의하는 가상 네트워크를 의미합니다. 각 컨테이너는 기본적으로 서로 다른 네트워크에 있기 때문에, 명시적으로 네트워크를 설정하면 서로 쉽게 통신할 수 있습니다.
볼륨(Volumns)
데이터 영속성을 위해 호스트 시스템과 컨테이너 간의 파일 시스템을 공유하는 공간을 의미합니다. 볼륨을 설정하면 컨테이너가 중지되거나 삭제되더라도 데이터가 유지됩니다.
Docker 사용하기
Step 1 - Docker 설치하기
먼저 다음 명령어를 입력하여 Docker를 설치합니다.
1
curl -fsSL https://get.docker.com | sh
Docker가 잘 설치되었는지 다음 명렁어를 입력해서 Docker 버전을 확인합니다.
1
2
docker -v
sudo systemctl status docker
Step 2 - Docker 그룹에 사용자 추가하기
Docker 명령어는 항상 root 권한으로 실행해야 합니다. 따라서 일반 계정에서 Docker 명령어를 입력할 때 항상 sudo
를 사용해야 합니다.
sudo
를 입력하지 않고 Docker 명령어를 사용하려면 사용자 계정을 Docker 그룹에 추가해야 합니다. 다음 명령어를 입력하여 Docker 그룹에 사용자를 추가합니다.
1
sudo usermod -aG docker $USER
이후 Docker 그룹 변경 사항을 적용하기 위해 시스템을 재부팅합니다.
1
sudo reboot now
재부팅 이후 다음 명령어를 입력하여 Docker 그룹에 추가되었는지 확인합니다.
1
groups $USER
Step 3 - Docker Compose 설치하기
심볼릭 링크 생성하기
먼저 /usr/local/bin/docker-compose
가 시스템 경로에 있는지 확인합니다. 없는 경우 /usr/local/bin
디렉토리를 생성한 후 아래 명령어를 입력하여 심볼릭 링크를 생성합니다.
1
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Docker Compose 설치하기
다음 명령어를 입력하여 Docker Compose를 설치합니다.
1
sudo curl -SL "https://github.com/docker/compose/releases/download/latest/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
이후 Docker Compose 바이너리 파일에 실행 권한을 부여합니다.
1
sudo chmod +x /usr/local/bin/docker-compose
Docker Compose가 잘 설치되었는지 다음 명렁어를 입력해서 Docker Compose 버전을 확인합니다.
1
docker compose --version
Step 4 - Docker 명령어 사용하기
아래의 명령어는 모두 Step 2 - Docker 그룹에 사용자 추가하기 과정을 거쳤다고 가정한 상태로 작성되었습니다.
이미지 검색 - docker search
docker search
명령어를 입력하여 Docker Hub
에서 이미지를 검색할 수 있습니다. 아래 예시는 node 관련 이미지를 검색한 예시입니다.
1
docker search node
이미지 태그 지정 - docker tag
docker tag
명령어를 입력하여 로컬 이미지에 Docker Hub 사용자 네임스페이스를 포함한 태그를 추가할 수 있습니다.
1
docker tag solitour-frontend:v2.0.1 hyunjinno/solitour-frontend:v2.0.1
이미지 업로드 - docker push
docker push
명령어를 입력하여 Docker Hub
에 이미지를 업로드할 수 있습니다. 아래 예시는 제가 진행한 Next.js 프로젝트의 Docker 이미지를 업로드한 예시입니다.
1
docker push hyunjinno/solitour-frontend:v2.0.1
Caution
Docker 이미지를 업로드하기 전, Docker Hub에 Repository를 먼저 생성해야 합니다.
이미지 다운로드 - docker pull
docker pull [이미지 이름]
명령어를 입력하여 Docker Hub에서 이미지를 다운로드할 수 있습니다. 아래 예시는 node.js
공식 이미지를 다운로드받는 예시입니다.
1
docker pull node
이미지 목록 확인 - docker images
docker images
명령어를 입력하여 로컬에 저장된 모든 이미지 목록을 확인할 수 있습니다.
1
docker images
이미지 삭제 - docker rmi
docker rmi [이미지 이름]
명령어를 입력하여 특정 이미지를 삭제할 수 있습니다.
1
docker rmi node
이미지 빌드 - docker build
docker build -t [이미지 이름] .
명령어를 입력하여 Dockerfile을 기반으로 이미지를 빌드할 수 있습니다. 아래 예시는 현재 디렉토리에 있는 Dockerfile로 my-app
이라는 이름의 최신 태그를 가진 이미지를 생성하는 예시입니다.
1
docker build -t my-app:latest .
컨테이너 실행 - docker run
docker run [옵션] [이미지 이름]
명령어를 입력하여 특정 이미지를 기반으로 컨테이너를 생성하고 실행할 수 있습니다. 아래 예시는 openvidu/openvidu-dev:2.30.0
이미지를 기반으로 컨테이너를 생성하고 실행하는 예시입니다.
1
docker run -p 4443:4443 --rm -e OPENVIDU_SECRET=MY_SECRET openvidu/openvidu-dev:2.30.0
컨테이너 실행 시 사용할 수 있는 주요 옵션은 다음과 같습니다.
옵션 | 설명 |
---|---|
-d | 백그라운드에서 실행하는 옵션입니다. (Detached 모드) |
-p [호스트 포트]:[컨테이너 포트] | 호스트와 컨테이너의 포트를 매핑합니다. |
--rm | 컨테이너가 종료되면 자동으로 삭제되도록 설정하는 옵션입니다. 개발 및 테스트 환경에서 유용하게 사용할 수 있는 옵션입니다. |
--restart always | 컨테이너가 중단되었을 때 자동으로 재시작합니다. 서비스가 안정적으로 유지되어야 하는 배포 환경에서 유용하게 사용할 수 있는 옵션입니다. |
--restart unless-stopped | 수동으로 컨테이너를 중지하는 경우를 제외한 모든 경우에 대해서 자동으로 재시작합니다. |
--name | 컨테이너의 이름을 지정합니다. |
-e [환경 변수 이름]:[환경 변수 값] | 컨테이너에 환경 변수를 설정하는 옵션입니다. |
-v [호스트 디렉토리]:[컨테이너 디렉토리] | 호스트와 컨테이너의 디렉토리를 매핑합니다. (볼륨) |
컨테이너 목록 확인 - docker ps
docker ps
명령어를 입력하여 현재 실행 중인 컨테이너 목록을 확인할 수 있습니다. -a
옵션을 사용하면 정지된 컨테이너도 확인할 수 있습니다.
1
docker ps
컨테이너 정지 - docker stop
docker stop [컨테이너 이름]
명령어를 입력하여 실행 중인 특정 컨테이너를 정지할 수 있습니다.
1
docker stop my-app:latest
모든 컨테이너를 정지하려면 다음 명령어를 입력합니다.
1
docker stop $(docker ps -a -q)
컨테이너 재시작 - docker restart
docker restart [컨테이너 이름]
명령어를 입력하여 정지된 컨테이너를 재시작할 수 있습니다.
1
docker restart my-app
컨테이너 삭제 - docker rm
docker rm [컨테이너 이름]
명령어를 입력하여 정지된 컨테이너를 삭제할 수 있습니다.
1
docker rm my-app
모든 컨테이너를 삭제하려면 다음 명령어를 입력합니다.
1
docker rm $(docker ps -a -q)
컨테이너 로그 확인 - docker logs
docker logs [컨테이너 이름]
명령어를 입력하여 특정 컨테이너의 로그를 확인할 수 있습니다.
1
docker logs my-app
컨테이너에서 사용하고 있지 않은 이미지 일괄 삭제 - docker image prune -a
docker image prune -a
명령어를 입력하여 현재 컨테이너에서 사용하고 있지 않은 이미지들을 일괄 삭제할 수 있습니다.
1
docker image prune -a
추가로 --force
옵션을 사용하면 프롬프트를 표시하지 않습니다.
1
docker image prune -a --force
컨테이너 내에서 명령어 실행 - docker exec
docker exec [컨테이너 이름] [명령어]
명령어를 입력하여 컨테이너 내에서 명령어를 실행할 수 있습니다.
1
docker exec my-app ls -l
만약 bash, sh, node, python 등 대화형 프로그램을 실행하기 위해 interactive shell이 필요한 경우 -i(interactive)
와 -t(TTY)
옵션을 사용할 수 있습니다.
1
docker exec -it my-app bash
예를 들어 아래와 같이 -it
옵션을 사용하지 않는 경우 명령어 실행 후 바로 종료됩니다.
반면에 -it
옵션을 사용하는 경우 컨테이너 내부의 Bash Shell로 들어가 직접 명령어를 실행할 수 있습니다.
Step 4 - Docker Compose 명령어 사용하기
Compose 실행 - docker compose up
docker compose up [옵션]
명령어를 입력하여 현재 디렉토리에 있는 docker-compose.yml
파일을 기반으로 모든 서비스를 실행할 수 있습니다.
1
docker compose up
만약 특정 서비스만 실행하고 싶다면 docker compose [서비스 이름]
명령어를 입력하면 됩니다.
1
docker compose up my-service
Compose 확인 - docker compose ps
docker compose ps
명령어를 입력하여 현재 실행 중인 서비스를 확인할 수 있습니다.
1
docker compose ps
Compose 종료 - docker compose down
docker compose down
명령어를 입력하여 실행 중인 모든 Compose 서비스를 중지하고, 네트워크나 볼륨 등을 정리할 수 있습니다.
1
docker compose down
Compose 로그 확인 - docker compose logs
docker compose logs
명령어를 입력하여 Compose로 실행된 서비스들의 로그를 확인할 수 있습니다.
1
docker compose logs