(100프로는 아니고 한 10프로 정도 사용법..?)
"Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly."
도커는 인프라 리소스로부터 어플리케이션을 분리해서 개발할 수 있는 환경을 제공해주는 오픈 소스 플랫폼이라고 할 수 있다.
"With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production."
프레임워크나 라이브러리의 버전이 일치하지 않아서 개발 서버에서 실행된 프로그램이 프로덕션 서버에서는 실행되지 않는 문제에 대한 솔루션을 제공한다.
"Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you do not need to rely on what is currently installed on the host. You can easily share containers while you work, and be sure that everyone you share with gets the same container that works in the same way."
가상 머신(Virtual Machine)
참고
가상화란? 물리 리소스를 추상화하는 것. 추상화한다는 말의 의미는 간단히 말해 구체적인 실체를 가진 자원에서 기능이나 특징만을 뽑아내 재사용하기 위해 개념 단위로 함수화하는 것이라고 할 수 있음컨테이너(Container)
도커 이미지는 어플리케이션 실행 환경을 구축해주는 파일이라고 생각하면 되고, 도커 허브는 그런 이미지들을 업로드해놓고 받아서 쓸 수 있는 플랫폼이라고 할 수 있다.
쉽게 말해서 깃과 깃허브의 관계처럼, 파일을 만들어서 클라우드에 올려놓고 다른 곳에서 파일을 가져다 쓸 수 있게 해놓은 것이라고 생각하면 된다.
작업 플로우 : 도커 이미지 파일 작성 → 도커 허브에 업로드(push) → 도커 허브에서 도커 이미지를 받아와서(pull) 사용
도커가 컨테이너 기술을 개발했다기 보다는, 리눅스 자체에 이미 있던 컨테이너 기술을 활용하면서 이를 도커 허브와 연계시켜서 좀 더 편하게 컨테이너를 사용할 수 있게 한 것이라고 할 수 있다.
WSL2 환경에서 도커를 설치하는 법을 설명하려고 한다.
Install required Windows components for WSL 2
옵션을 선택하도록 한다. Settings → General
에서 다음과 같이 되어 있는지 확인해보고 체크가 안 되어 있으면 체크한 후 Apply & Restart 한다.docker
를 입력해서 커맨드 옵션이 뜨면 설치 완료이다. 이미지 관련 명령어
docker images
: 가지고 있는 이미지 확인하기 → 참고로 TAG는 버전을 의미
docker image push image_name:tag
: 도커 허브의 저장소에 이미지 올리기
docker pull image_name:tag
: 저장소에서 이미지 받아오기
docker search TERM
: 이미지 검색하기 → 이미지 이름 앞에 아이디가 없으면 공식 이미지이고 아이디가 있으면 사용자 커스터마이징 이미지
docker build -t image_name:tag .
: 이미지 생성하기
-t
: 이름 지정하는 옵션.
: 현재 디렉토리의 Dockerfile을 읽어서 이미지를 만듦-f
: 읽어올 파일을 알려주는 옵션. 디폴트로 Dockerfile이라는 파일을 찾아서 읽는데, -f this_file
이라는 옵션을 주면 해당 파일을 읽고 실행시킨다.docker rmi image_name
: 이미지 삭제하기
참고
alpine 이미지 : 일반적으로 우분투 같은 base image를 받으면 기본적인 기능이 포함되어 있는데, 따로 설치하지 않아도 되니까 편리하기는 한데 용량이 너무 커지는 문제가 있다. alpine 이미지는 이런 기본 기능을 전부 제외하고 오로지 우분투만 받아오는 것이다.
컨테이너 관련 명령어
docker ps
: 컨테이너 확인하기
-a
: 종료된 컨테이너까지 확인하기docker run -it image_name:tag /bin/bash
: 컨테이너 생성 및 실행하기
-i
: --interactive. 사용자로부터 인풋을 받도록 하는 옵션-t
: --tty. 터미널을 여는 옵션--name
: 컨테이너의 이름을 지정하는 옵션--rm
: 도커 컨테이너가 실행을 끝내고 종료되면 컨테이너를 삭제하는 옵션/bin/bash
는 커맨드이다.-d
: 데몬(daemon, detached mode)으로 백그라운드에서 실행시키는 옵션-p
: 포트 넘버 지정하는 옵션 ex) -p 8000:80
: 외부에서(로컬에서) 8000번으로 들어왔을 때 도커 컨테이너의 80번 포트로 포트 포워딩을 해주겠다는 의미docker start container_name
: 도커 컨테이너 실행시키기
docker attach container_name
: 컨테이너 안으로 들어가기
exit or ctrl+d
: 컨테이너에서 나가기 + 컨테이너 종료ctrl + P + Q
를 입력하면 됨참고
run vs start : start 명령어는 이미 생성되어 있는 컨테이너를 실행시키는 것이고, run 명령어는 이미지를 가지고 새롭게 컨테이너를 만들어서 실행시키는 것. 여기에 -it 옵션까지 더하면 컨테이너 생성 + start + attach 라고 생각하면 됨.docker stop container_name
: 컨테이너 실행 중지시키기
docker rm container_name
: 컨테이너 삭제하기
참고
: 하나의 이미지로 여러 개의 컨테이너를 실행할 수 있음. 그래서 컨테이너를 삭제하는 것과 이미지를 삭제하는 것은 완전히 다른 개념!
docker exec container_name COMMAND
: 실행 중인 도커 컨테이너 밖에서 컨테이너 안으로 명령 하기 ex) docker exec container_name touch /hello.txt
: 컨테이너에 hello.txt 파일을 생성해라 → docker attach
로 들어가서 확인해보면 해당 파일이 생성되어 있음
Dockerfile이란 빌드할 이미지에 어떤 패키지들이 들어갈 지에 대한 내용이 담긴 파일이다.
예를 들어, ubuntu:latest 이미지를 받아와서 컨테이너를 생성하면 해당 컨테이너에는 우분투 환경을 제외하고는 아무것도 설치되어 있지 않다. 여기에 git을 설치하고 싶다고 한다면 컨테이너에 들어가서 일일이 설치를 해줘야 하는데, 이런 수고로운 작업을 하나의 파일을 만들어서 거기에 설치할 패키지의 목록을 넣어둠으로써 자동화시키는 것이라고 할 수 있다.
따라서 위의 예시를 그대로 명령어로 표현해보면 다음과 같다.
$ docker run -it ubuntu:latest bash
>> apt-get update
>> apt-get install git
얘를 아래와 같이 하나의 파일 안에 넣은 게 Dockerfile이다.
# Base Image 지정
FROM ubuntu:latest
# 명령어
RUN apt-get update
RUN apt-get install git
# 위의 이미지 파일을 가지고 ubuntu:git-ver라는 이름의 이미지 만들기
docker build -t ubuntu:git-ver .
VSCode에서 도커를 GUI로 쉽게 사용하기 위한 익스텐션이 두 개 있다.
도커 명령어 옵션들을 하나의 파일(docker-compose.yml) 안에 key : value
의 형식으로 정리해놓고, 도커 컨테이너를 실행시킬 때마다 일일이 옵션을 입력할 필요 없이 docker-compose 명령어를 통해 컨테이너를 실행시킬 수 있도록 하는 것
특히 여러 개의 컨테이너를 동시에 띄워야 할 때, 하나의 파일 안에 각 컨테이너의 옵션들을 정의해놓고 한 번에 실행시킬 수 있어서 편리함
# docker run을 사용할 경우
docker run -d \
--name db \
-p 5432:5432 \
-v ./data/db:/var/lib/postgresql/data \
-e POSTGRES_DB=postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=password
postgres
# docker-compose.yml 파일을 만들어서 실행시킬 경우
version: "3.9"
services:
db:
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
djangoapp:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/backend
ports:
- "8000:8000"
depends_on:
- db
version
: 파일 규격 버전을 정의하는데, 레퍼런스를 참고해서 도커 버전에 맞게 적어 넣으면 된다.services
: 실행시킬 컨테이너를 정의하는 공간volumes
: 컨테이너를 실행시킬 때, 컨테이너 안에서 생성된 데이터는 컨테이너가 종료되면 함께 사라진다. 만약 데이터를 백업해두고 싶다면 로컬 경로와 컨테이너에서 데이터가 저장되는 경로를 심볼릭 링크시켜 컨테이너 안에서 생성된 데이터가 링크된 로컬 경로에 쌓이도록 하면 되는데, 이런 걸 volume이라고 한다. run 명령어와 함께 쓸 때는 -v
나 --mount
옵션을 주면 된다.-v host_dir:container_dir
depends_on
: 어떤 컨테이너를 먼저 띄울 지 알려주는 옵션. nginx가 web에 의존하고 있으므로 web을 먼저 실행시키고 nginx를 실행시키게 된다.docker-compose up
: docker-compose 파일을 읽어서 컨테이너를 실행시키기
--build
: 이미지를 빌드한 후 컨테이너를 생성해서 실행시키는 옵션docker-compose down
: 컨테이너를 전부 종료시키기
❓ 도커를 사용하면 가상 환경을 안 써도 되나요?
PROS : 도커를 사용하면 가상 환경을 안 써도 된다.
📄 참고글
의존성 격리를 위해 사용하는 게 가상 환경인데, 그 역할을 도커가 하고 있으므로 도커 안에서 가상 환경을 사용할 필요가 없다.
만약 도커 안에서 여러 개의 앱을 돌리고 있다면, 그건 도커를 잘못 사용하고 있는 것이므로 앱을 각기 다른 컨테이너에 분리해라.
CONS : 도커를 사용해도 가상 환경을 써야 한다.
📄 참고글
가상 환경을 사용하면 패키지에 대한 전반적인 컨트롤을 더 용이하게 할 수 있고 디버깅도 쉽다.
또 계속 가상 환경에서 작업하다가 컨테이너 쓰면서 가상 환경을 사용하지 않게 된다면 오히려 그게 더 불편하다.
가상 환경을 사용한다고 해서 도커 컨테이너가 느려지거나 성능이 저하되는 것도 아니므로 그냥 가상 환경 써라.
❓ 도커 안에서 개발을 하는 건가요, 아니면 배포할 때만 사용하는 건가요?
PROS : 도커 안에서 개발 해라.
📄 참고글
도커를 배포용으로만 생각하지 마라. 도커로 개발하면 장점이 많다.
CONS : 도커에서 개발하지 마라.
📄 참고글
도커 컨테이너 안에서 개발을 하면 추가적인 환경 설정 등 해줘야 할 게 많다.
특히 디버깅할 때 귀찮은 작업들을 해줘야 한다.
만약 규모가 작은 어플리케이션을 만들 생각이라면 개발할 때는 도커를 안 쓰는 게 훨씬 낫다.