2023. 6. 1. 22:42ㆍTIL/2023.6월
2023.06.01 목
6월이 시작되었습니다.
오늘도 도커 강의를 봤습니다.
도커
도커는 관리자 권한으로 실행됨(sudo)
sudo apt install docker.io
도커설치 명령어
sudo apt install docker.io -y
아래 것은 정말 설치할 것인지 물어보는 질문에 yes를 사용한다는 명령어
설치확인 명령어
docker --version
설치된 도커의 버전을 확인함
컨테이너 생성하기
sudo docker run -d -p 80:80 httpd:latest
컨테이너를 생성함
조건 의미
run : 이미지를 사용해 컨테이너를 실행.
-d : 컨테이너를 백그라운드로 실행.
80:80 : 80번 포트로 접속했을 때 컨테이너에 접근할 수 있도록 포트포워딩 설정
httpd:latest : httpd의 가장 최신 이미지를 사용해 컨테이너를 생성
이미지 실행하는 순서
다운로드된 이미지가 있는지 확인->없다면 이미지 다운로드
실행중인 컨테이너 확인
sudo docker ps(필요할 때 계속 까먹네요)
차례로
CONTAINER ID : 컨테이너가 가지고 있는 고유한 id
IMAGE : 컨테이너가 생성될 때 사용된 이미지
COMMAND : 컨테이너가 생성될 때 실행되는 명령어
CREATED : 생성 후 경과 시간
STATUS : 컨테이너 상태
PORTS : 사용중인 포트
sudo docker ps -a
-a : 중지된 컨테이너 목록까지 포함해서 모두 확인하기
컨테이너 이미지확인
sudo docker images
# REPOSITORY : 이미지 저장소 이름
# TAG : 이미지 버전
# IMAGE ID : 이미지의 고유한 id
# CREATED : 이미지 생성일(마지막 업데이트 일)
# SIZE : 이미지 용량
컨테이너 내부 들어가기
sudo docker exec -it $container_id /bin/bash
$containser_id : sudo docker ps를 쳤을 때 확인되는 container_id를 입력
(나의 경우는 7b81e03bd54b인데 7b81만 쳐도 됨)
/bin/bash : 컨테이너에 접속할 때 사용되는 쉘을 입력
이미지에 따라 /bin/bash라는 쉘이 존재하지 않을 수 있는데, 이 경우에는 /bin/sh를 사용해 접속
컨테이너 나오는 명령어
exit
주소창에 연결한 인스턴스의 ip주소를 넣어 검색하면, 웹사이트에서 접속가능
이 때 출력되는 http는
컨테이너 내부에 htdocs안에 있는 index.html을 보여주는 거임
cat ./htdocs/index/html
명령어로 내용 확인 가능
docker-compose(도커-컴포즈)
설치
두개 이상의 컨테이너를 쉽게 관리하기 위해 사용되는 툴
docker-compose를 사용할 때에는 docker-compose.yml (혹은 .yaml)이라는 파일에 컨테이너에서 사용 될 이미지, 옵션 등을 작성한 후 사용
이를 통해 docker 명령어만 사용할 때보다 여러 컨테이너를 더 간편하고 직관적으로 컨테이너를 관리 가능
플러그인을 설치할 경로(폴더)를 먼저 만들기
sudo mkdir -p /usr/lib/docker/cli-plugins
/usr/lib/docker 경로에 cli-plugins라는 디렉토리를 생성
-p : 만약 상위 디렉토리가 없다면 함께 생성
도커-컴포즈 설치
sudo curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 -o /usr/lib/docker/cli-plugins/docker-compose
curl명령어로 깃허브에 올라와있는 도커-컴포즈를 다운 받을 것이며
/usr/lib ... 경로에 우리가 만든 폴더안에
docker-compose 이름으로 다운받는것을 의미합니다.
다운로드 확인
ls -l /usr/lib/docker/cli-plugins/
실행권한 부여
기본적으로 리눅스에서는 파일에 대한 실행권한이 없기에 권한을 부여해야함
(r은 읽기, w은 쓰기, x는 실행)
sudo chmod +x /usr/lib/docker/cli-plugins/docker-compose
도커-컴포즈 설치확인
sudo docker compose version
버전이 출력되면 잘 설치된 거
도커-컴포즈는 사용자가 작성한 docker-compose.yml 파일의 내용에 맞게 컨테이너를 설정하고 실행함
그러니 파일이 존재하지 않는 경로에서 docker-compose 명령어를 실행하면 에러가 발생함
도커컴포즈 사용방법
도커-컴포즈를 사용하여 컨테이너 생성
도커-컴포즈를 사용하기 위해서 현재 실행중인 컨테이너를 삭제해야 함
sudo docker run -d -p 80:80 httpd:latest
이 명령어를 사용해만든 컨테이너 삭제해야 함
그러기 위해 현재 실행중인 컨테이너를 확인해야 함
sudo docker ps -a
-a는 실행중인 컨테이너를 찾아줌
sudo docker rm -f 컨테이너아이디
-f 컨테이너가 구동중일 때는 삭제가 불가능함
그러니 -f 강제하여 삭제시킴
마찬가지로 컨테이너 아이디는 일부만 쳐도 됨
삭제 후 위의 실행 중인 컨테이너 확인 명령어를 사용하면, 항목이 비어있음
도커-컴포즈는 yml파일을 바탕으로 컨테이너를 설정하고 실행함
그리니 vi편집기를 사용하여 docker-compose.yml을 조작해주어야 함
vi docker-compose.yml을 사용하여 파일 생성 및 편집을 해줌
#은 주석처리
yml 파일 작성
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.
services:
example: # 서비스 이름을 지정합니다. 서비스 이름은 컨테이너끼리 통신할 때 사용됩니다.
container_name: example # 컨테이너 이름을 지정합니다.
image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정합니다.
restart: always # 컨테이너가 종료됐을 때 다시 실행시켜 줍니다.(항상 실행된 상태로 유지)
도커 실행시키기
sudo docker compose up -d
run 대신 compose로 실행
up : docker-compose.yml 파일을 읽어 정의된 서비스들을 실행시킵니다.
-d : 컨테이너를 백그라운드로 실행시킵니다.
컨테이너를 중지시킬 때,
stop, down
sudo docker compose stop
컨테이너 일시정지 명령어
sudo docker compose start
명령어로 다시 가동시킬 수 있음
sudo docker compose down
컨테이너를 삭제함
sudo docker compose up -d
명령어를 사용하면, 다시 실행가능
단,삭제되었다, 다시 생성되는 것이기에 컨테이너 아이디가 바뀜
port forwarding(포트 포워딩)
run을 사용해서 만든 컨테이너의 경우 별다른 조작없이 ipv4주소를 주소창에 사용하면, 접근이 가능했지만, 컴포즈를 사용하여 만든 컨테이너의 경우 같은 방법으로는 접근이 불가하다
이유는 포트 포워딩이 되어있지 않아서 그럼
vi docker-compose.yml
명령어를 사용하여 vi편집기에 들어간 후
ports: # 포트포워딩을 설정해줍니다.
- 80:80
추가해줍니다.
외부에서 80 포트로 접속했을 때 컨테이너의 80 포트서비스로 연결해줌
장고 서비스에 연결하고 싶다면
80:8000 으로 설정하면 됨
설정을 추가해줌
80:80은 80번 포트로 들어왔을 때 80번 포트로 연결한다는 의미
변경사항이 생겼을 때 적용하기 위해서는
sudo docker compose up -d
를 사용
다시 ipv4 퍼블릭 주소로 검색하면 잘 접속됨
도커로 배포를 하다보면, 배포가 정상적으로 되고 있는지 확인해야함
sudo docket compose logs
명령어를 사용하면, 컨테이너가 실행된 후 부터 지금까지의 로그를 확인할수 있음
실시간으로 확인하고 싶을 때에는
sudo docket compose logs -f
vs코드 runserver처럼 실시간으로 상태를 확인가능
창에서 나가고 싶을 때에는
컨트롤 + c
volume
컨테이너 접속 명령어
sudo docker exec -it example /bin/bash
docker exec -it
컨테이너에 접속하겠다
example
컨테이너 이름
/bin/bash
위의 명령어를 사용하여
echo "test" >> /usr/local/apache2/htdocs/index.html
을 사용하면
index.html 파일에 test를 추가해줌
echo는 출력하라는 의미
실제 ip주소로 접속하면 test가 추가됨

이후 exit로 컨테이너를 나가고 down명령어로 컨테이너 삭제 후 up -d를 사용해 컨테이너를 다시 생성하여 ip주소로 접속하면, test가 사라져있음
도커 컴포즈를 사용할 때, 수정사항이 발생하여 그것을 적용시키려면, down 후 up을 해주어야 함
그러니, 기존 내용이 사라진다면, 도커 컴포즈를 사용할 이유가 없음
이것을 해결하기 위해 volume(볼륨)을 사용하여
컨테이너에 저장하지 않고 host에 저장시킴
방법이 volume말고도 다른 방법이 있는데
bind mount, tmpfs mount가 있음
docker volume을 docker에서 가장 권장함
bind mount 사용방법
volumes: # volume을 설정해줍니다.
- ./example_http_code/:/usr/local/apache2/htdocs/ # 정의한 volume의 mount할 경로를 지정합니다.
위에서
./example_http_code/ 는
docker-compose.yml 파일이 있는 경로를 의미합니다.
/usr/local/apache2/htdocs/ 는
컨테이너 내부 index.html이 위치하는 경로를 의미합니다.
ip주소를 사용하여 들어가보면 index of/라고 출력됨

host부분에서 경로를 지정해주지 않아 발생한 문제임
example_http_code 경로에 index.html 파일을 만들어주고 vi를 사용하여, 내용을 넣어주면 됨
컨테이너에 들어가서
echo "test" >> /usr/local/apache2/htdocs/index.html
다음 명령어를 사용하여 index.html에 test를 추가 후
주소창을 통해 확인하면 추가됨

exit 명령어로 컨테이너를 나가
cat example_http_code/index.html 명령어로 파일을 확인하면
test가 추가되어있음

host에서 수정하면 컨테이너에 반영되고 컨테이너에서 수정하면 host에 반영됨
컨테이너가 날아가도 host에 저장이 되어 있어 데이터를 보존가능
volume 사용방법
vi편집기를 통해 docker-compose.yml에 접속
version: '3.8'
# docker-compose.yml에 사용될 문법 버전을 정의합니다.
(추가)
volumes:
- ./example_http_code/:/usr/local/apache2/htdocs/ # 정의한 volume의 mount할 경로를 지정합니다.
services:
...
(변경)
volumes:
- example_http_code:/usr/local/apache2/htdocs/
# 정의한 volume의 mount할 경로를 지정합니다.
bind에서는 아래와 같이 volumes를 설정했음
- ./example_http_code/:/usr/local/apache2/htdocs/
host에서 index.html을 만들고 컨테이너 index.html과 연동하는 방식이 아님
컨테이너에 접속하여 index.html파일을 수정하면 host의 /var/lib/docker/volumes/ 경로에 저장됨
host영역에 저장되니 컨테이너를 삭제하여도 데이터는 남음
확인을 위해서는 관리자권한을 사용해야 함
sudo ls -l /var/lib/docker/volumes/
명령어 사용시 확인 가능

하지만 보통
sudo docket volume ls
명령어를 사용하여 확인함

volume의 자세한 정보를 확인하고 싶을 때에는
sudo docker volume inspect 볼륨이름
실습에서는 ubuntu_example_http_code

컨테이너가 삭제되어도, 볼륨은 host에 계속 저장되어있기에 리소스 관리를 위해 사용하지 않을 때에는 삭제해주어야 함
삭제를 위한 명령어
sudo docker volume prune
도커 이미지 빌드
Dockerfile
docker 의 이미지를 직접 생성하기 위한 용도로 작성하는 파일
사용자가 개발한 프로젝트 혹은 설정파일 등을 이미지에 포함시키거나 이미지에 기본적으로 특정 패키지를 설치하고싶을 때 등 다양한 용도로 사용
ex)
예를 들어 docker에서 django를 배포한다고 가정 했을 때, 기본 python 이미지를 불러온 후 django 패키지를 pip install 한 후 이미지를 생성
vi Dockerfile
명령어를 사용하여 Dockerfile를 만듬
vi편집기에서
FROM을 사용하여 이미지를 지정함
FROM httpd:lastest
copy를 사용하여 html 파일을 가져옴
./index.html /usr.local/apache2/htdocs/index.html
현재 경로의 index.html을
컨테이너에 위치한 index.html파일에 복사함
vi docker-compose.yml
을 사용하여, Dockerfile을 사용하기 위한 준비를 함
version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.
(강의에서 사용하지 않는 volumes 부분 삭제함)
services:
example:
# 서비스 이름을 지정합니다. 서비스 이름은 컨테이너끼리 통신할 때 사용됩니다.
container_name: example
# 컨테이너 이름을 지정합니다.
(추가됨)
build: .
# 현재 경로에 있는 Dockerfile을 사용해 이미지를 생성합니다.
ports:
# 포트포워딩을 설정해줍니다.
- 80:80
# 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결해줍니다.
(강의에서 사용하지 않는 volumes 부분 삭제함)
restart: always
# 컨테이너가 종료됐을 때 다시 실행시켜 줍니다.
host의 Dockerfile의 index.html을 복사해야 하니
vi index.html을 사용하여 생성 후 편집해줌
안에 내용을 적어주면됨
강의에서는 hello world Dockerfile
sudo docker compose up -d
sudo docker compose up -d --build
도커파일은 처음 사용될 때, 이미지를 가져오는 작업을 한다.
만약 down을 사용하여 삭제하고 다시
sudo docker compose up -d
명령어를 통해 생성한다면, 도커파일에서 이미지를 가져오지 않고 이전에 사용되었던 이미지를 가져오기 때문에
변경점을 불러올 수 없게된다.
그렇기에
sudo docker compose up -d --build
이 명령어를 사용하여, 변경점을 불러와 수정된 이미지를 적용시켜야 한다.
도커파일, bind, volume 모두 비슷한 역할을 한다.
셋 중 무엇이 더 좋다 할 수는 없으며, 상황에 따라 골라 써야한다.
도커이미지 빌드 중 발생한 문제
sudo docker compose up -d을 했을 때 오류가 발생함
한참을 강의노트와 파일을 비교하고, 강의와 비교하며 문제를 찾았습니다.
발견한 원인


latest이미지인데 lastest 오타를 내어 에러가 출력되었습니다.

문제해결 후 sudo docker compose up -d 사용

index.html도 잘 출력됩니다.
entrypoint(엔트리 포인트)
docker 컨테이너가 생성될 때 기본적으로 실행 할 명령어를 지정해 주는 옵션
entrypoint는 Dockerfile과 docker-compose.yml 모두 작성할 수 있습니다.
만약 Dockerfile, docker-compose.yml 모두 entrypoint가 작성되어 있다면 Dockerfile의 entrypoint는 무시되고 docker-compose.yml의 명령어가 우선적으로 수행됩니다.
vi Dockerfile
파이썬 이미지를 가져옴
FROM python:3.9.15
# .pyc 파일을 생성하지 않도록 설정합니다.
ENV PYTHONDONTWRITEBYTECODE 1
# 파이썬 로그가 버퍼링 없이 즉각적으로 출력하도록 설정합니다.
ENV PYTHONUNBUFFERED 1
# /app/ 디렉토리를 생성합니다.
RUN mkdir /app/
# /app/ 경로를 작업 디렉토리로 설정합니다.
WORKDIR /app/
# main.py 파일을 /app/ 경로로 복사합니다.
COPY ./main.py /app/
ENV는 컨테이너에 보내주는 환경변수
현재 설정된 환경변수는 파이썬 이미지를 사용할 때 거의 필수적으로 사용됨
vi docker-compose.yml
version: '3.8'
services:
example:
container_name: example
build: .
(ports는 사용하지 않아 강의에서 제거함)
entrypoint: sh -c "python3 main.py"
# 작업 디렉토리에 존재하는 main.py 파일을 실행시킵니다.
restart: always
따로 경로를 지정해주지 않은 이유는 Dockerfile에서 work 경로를 지정해 주었기 때문
컨테이너 안에서 실행할 파이썬 파일이 필요
vi main.py
from time import sleep
for i in range(100):
print(f"print number : {i}")
sleep(1)
100까지 숫자를 세는 기능을 함
컨테이너를 실행시키기 위해
sudo docker compose up -d
명령어를 사용하면, 변경점을 적용하지 않기에
sudo docker compose up -d --build
명령어를 사용하여 변경점을 적용시킴
엔트리포인트 실습 중 발생한 문제

up을 사용하여, 컨테이너 재설치




일단 계속 신텍스에러를 출력하기에 main.py를 집중하여 보았고, i를 1이라고 사용한 오타를 발견하고 다시 logs를 찍었지만, 계속하여 신텍스 에러를 출력했습니다.
그러다 생각한 것이 이미 100이 지나서 그렇거나, main.py가 컨테이너에 들어갔기 때문에 수정이 되지 않는 것일지도 모른다는 생각하여 down을 사용하여 컨테이너를 삭제하였습니다.
처음에는 up -build를 사용하여 컨테이너를 재설치하였고, 위의 기록처럼 ip 오타가 나왔는데, 리눅스가 알아서 설치를 해준 것인지 재설치가 완료되었습니다.
(오타가 발생했는지도 모르고 있다, TIL에 올릴려고 스크린샷을 찍다가 발견했습니다)
이후 설치가 된 것을 확인한 후 logs -f를 찍었고 강의와 같이 원하는 형태로 출력된 것을 확인했습니다.
이후 오타를 발견하고, history를 사용하여 확인했는데, 어떻게 되었는지 참 모르겠네요..
느낀점
강의 자체가 길지는 않습니다, 그냥 재생만 하고 보면, 1시간 20분 분량인데, 이걸 필기도 하고, 이해도 하고, 에러가 났을 때, 해결도 하려고 하니 8분짜리 강의를 30분 동안 듣고 있습니다.
사실 2주차 8분짜리 강의가 하나 남아있긴한데, 진짜 왠만해서는 안미루지만, 오늘은 좀 미뤄야겠습니다.
엔트리 포인트도 보는데 머리가 가득 찼는지 계속 돌려보고, 에러도 나오고 이러니 도저히 마지막 강의를 볼 자신이 안생깁니다.
양심의 삼각형이 닳고 있따!
'TIL > 2023.6월' 카테고리의 다른 글
TIL 최종프로젝트(4) 공연예약모델 (0) | 2023.06.09 |
---|---|
TIL최종프로젝트(3) permission, is_admin, is_superuser (0) | 2023.06.08 |
TIL 최종프로젝트(2) Invelid data. Expected a dictionary, but got list (0) | 2023.06.08 |
TIL 최종프로젝트(1) (0) | 2023.06.06 |
TIL docker 패스, 부족한 부분 보충 (0) | 2023.06.06 |