Docker 명령어
생성한 컨테이너에 접근
- 외부에서 컨테이너 내부에 개방된 포트에 접근하려면 외부와 접속하기 위한 설정이 필요한데 이를 위해서 포트를 설정해줘야 한다.
- port forwarding
- 호스트 머신의 포트를 Container 포트와 연결해 Container 밖에서 온 통신을 Container 포트로 전달한다.
- Container 포트를 Container 외부에서도 사용이 가능하다.
- -p 외부포트: 내부포트 형태로 작성한다.
- apache 컨테이너를 이용해서 웹서버를 만들어서 외부에서 접근한다. 이때 image 이름은 httpd 이고 내부 포트는 80번을 이용한다.
docker run --name apa000ex2 -d -p 8080:80 httpd
→ 항상 서버는 -d를 줘야 한다.
- 컨테이너 중지 & 삭제
docker stop apa000ex2
docker rm apa000ex2
다양한 이미지
- 리눅스 운영체제가 담긴 컨테이너
- ubuntu
- centos
- debian
- fedora
- busybox
- alpine
- 웹 서버 및 데이터베이스가 담긴 이미지
- httpd - apache 웹 서버
- nginx
- mysql - MYSQL_ROOT_PASSWORD로 관리자 비밀번호를 설정해야 한다.
- postgres
- mariadb
- 프로그래밍 언어의 런타임
- openjdk
- python
- php
- ruby
- perl
- gcc
- node
- registry (도커 레지스트리)
실습
- nginx(80번 포트를 외부로 노출)를 웹 서버로 만들고 외부에서 접근
docker run --name nginx -d -p 8001:80 nginx
- 확인
docker ps -a
→ curl localhost:8001로 데이터가 넘어오는 것을 확인
- 리소스 사용량 확인
docker stats nginx
- 실행 중인 프로세스 확인
docker top nginx
- 로그 확인
docker logs -f nginx
관리 명령어
- 실행 중인 Container를 제외한 모든 Container를 파기 (Status가 Up이 아닌 컨테이너들 지우기)
docker container prune
- 사용하지 않는 Docker Image, Container, Volume, Network 등 모든 Docker 리소스를 일괄 삭제
docker system prune
- 사용 현황 확인
docker container stats
실습
- ubuntu를 설치해서 내부에 접속해서 작업을 수행 --- A 방법
- ubuntu 이미지 검색해보기
docker search ubuntu
- ubuntu 공식 이미지 다운로드
docker image pull ubuntu
- 컨테이너 생성
docker create --name ubuntu -it ubuntu
- 컨테이너 실행
docker start ubuntu
- 컨테이너 내부 접속
docker attach ubuntu
→ 만들어져 있는 컨테이너 내부에 접속할 때는 attach 이고 만들 때 내부에 접속할 때는 이미지 이름 뒤에 /bin/bash 형태로 작성한다.
- 명령 수행
cat etc/issue
apt update # sudo 안 붙여도 된다.
apt upgrade
apt install vim
→ 도커 컨테이너는 기본적으로 root 계정으로 접속하기 때문에 sudo 명령 안 붙여도 된다.
- 컨테이너를 만들면서 컨테이너 내부에 접속 ---- B 방법
docker run --name ubuntu -it ubuntu /bin/bash
- 컨테이너에 명령 수행
docker exec [OPTIONS] 컨테이너이름 또는 아이디 명령어
docker exec -it ubuntu /bin/bash
컨테이너와 호스트 간의 공유
docker cp 소스 목적지
- 컨테이너와 호스트 간의 파일 복사
아파치 컨테이너와 파일 복사
- 아파치 컨테이너 생성
docker run --name apa000ex19 -d -p 8080:80 httpd
→ 아파치 서비스 /usr/local/apache2/htdocs 디렉토리에 index.html을 소유하고 있다.
- 아파치 서버의 index.html을 복사하기
docker cp 컨테이너이름:소스 복사할것
docker cp apa000ex19:/usr/local/apache2/htdocs/index.html index.html
- 복사한 index.html을 vi로 hello local로 내용 바꾸기
- 로컬의 파일을 컨테이너로 복사
docker cp index.html apa000ex19:/usr/local/apache2/htdocs/index.html
nginx 컨테이너의 메인 화면을 수정
- nginx 컨테이너는 /usr/share/nginx/html 디렉토리 안의 index.html을 화면에 출력
- nginx 컨테이너 구동
docker run --name nginx -d -p 8001:80 nginx
50x.html : 서버가 오류 났을 때 띄어주는 거
- 파일 복사
docker cp index.html nginx:/usr/share/nginx/html/index.html
기타 명령
docker pause 컨테이너이름
- 컨테이너 정지
docker pause nginx
- 일시 정지 해제
docker unpause nginx
- 컨테이너 재시작
docker restart nginx
→ 변경된 내용이 있으면 재시작
- docker stop은 해당 컨테이너에서 실행되는 모든 프로세스를 KILL하는 반면, docker pause는 컨테이너에서 실행되는 프로세스를 잠깐 중단(SIGSTOP) 시킨다.
- 파이썬 코드 작성
from random import shuffle
from time import sleep
gamenum = input('lotto game count: ')
for i in range(int(gamenum)):
balls = [x for x in range(1, 46)]
ret = []
for j in range(6):
shuffle(balls)
number = balls.pop()
ret.append(number)
ret.sort()
print("lotto number[%d]: " %(i+1), end=' ')
print(ret)
sleep(1)
- 파이썬 컨테이너 생성
docker run -dit --name=python_test python
→ web이면 포트포워딩 해주지만 여기는 웹이 아니기 때문에 ex. -p 8900:8900 안해도 된다.
- 파일 복사
- 로컬의 lotto.py을 python_test 컨테이너의 루트로 복사
docker cp 원본이있는곳 복사할곳
docker cp lotto.py python_test:/
docker exec -it python_test /bin/bash # 복사 잘 되었는지 확인용
python
pip list #로 명령어들 잘 설치되어있나 확인
- 컨테이너에서 파이썬 파일 실행
docker exec -it python_test python /lotto.py
- 노드 실행
- 소스 코드 작성: index.js
let http = require('http'); let content = function(req, resp){ resp.end("Good Morning Kyla!!" + '\\n'); resp.writeHead(200); } let web = http.createServer(content) web.listen(8000);
- 노드 이미지 다운로드 (노드의 이미지는 노드)
docker pull node
- 실행 (웹 서버니까 왠만해서는 -dit 붙이고 포트포워딩 하기!)
→ 외부포트(9000)은 마음대로 써도 되는데 내부포트(8000)은 index.js에서 8000이라고 썼으니까 꼭 8000이라고 쓰기docker run --name=nodejs -dit -p 9000:8000 node
- 지금은 파일이 없어서 curl localhost:9000 이라고 해도 실패한다.
- 파일 복사
docker cp index.js nodejs:/index.js
- 파일 실행 (컨테이너이름: nodejs, 이미지: node)
-it가 아니라 -dit로 백그라운드에서 실행됨docker exec -dit nodejs node /index.js
- 컨테이너를 이미지로 만들고 이미지를 도커 허브에 업로드
- 도커 허브에 업로드 할 때는 도커 허브에 로그인이 되어 있어야 한다.
docker login -u ~~~~~@gmail.com
- 컨테이너를 이미지로 생성
docker commit -a '메시지' 컨테이너이름 이미지이름:태그 docker commit -a 'kyla' nodejs webserver:1.0
- 이미지 만들어졌는지 확인
docker images
- 도커 허브에 업로드 할 이미지로 변경 (자신의도커허브이름/이미지이름:태그)
docker tag webserver:1.0 kyla333/webserver:1.0
- 도커 허브에 업로드
docker push kyla333/webserver:1.0
- 지금까지 만든 이미지 다 지우고 도커 허브에서 이미지 가져오기
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker rmi $(docker images -q)
docker pull kyla333/webserver:1.0
# 이미지를 컨테이너로 실행
docker run -dit --name webserver -p 8009:8000 kyla333/webserver:1.0
# 컨테이너에 명령 수행
docker exec -dit webserver node /index.js
# 확인
curl localhost:8009
Docker volume
볼륨 마운트
- Volume: 스토리지의 한 영역을 분할한 것
- Mount: 연결
- 도커는 Union File System을 사용해서 하나의 이미지로부터 여러 개의 컨테이너를 만들 수 있는 방법을 제공하고 이미지에 변경된 내용을 저장할 수 있도록 해주는데 이를 위한 기능이 볼륨 마운트이다.
- 도커 볼륨은 컨테이너에서 생성하고 재사용할 수 있고 호스트 운영체제에서 직접 접근이 가능하다. (둘이서 공유할 수 있다.)
- 이 기능으로 보존되어야 하는 데이터를 유지하기 위한 메커니즘을 제공한다.
2가지 방식
- Volume Mount
- Docker Engine이 관리하는 영역 내에 만들어진 볼륨을 컨테이너에 디스크 형태로 마운트 하는 방식
- Bind Mount
- Docker Engine이 관리하지 않는 Host 운영체제의 영역과 마운트하는 방식
Volume Mount Bind Mount
스토리지 영역 | 볼륨 | 디렉토리 또는 파일 |
물리적 위치 | 도커 엔진의 관리 영역 | 어디든지 가능 |
마운트 절차 | 볼륨을 생성한 후 마운트 | 기존 파일 또는 디렉토리를 마운트 |
내용 편집 | 도커 컨테이너를 통해서 | 일반적인 파일과 같다. |
백업 | 절차가 복잡함 | 일반적인 파일과 같다. |
볼륨 마운트
docker volume create 이름
- 볼륨 마운트 영역 생성
docker volume rm 이름
- 볼륨 마운트 영역 삭제
docker run -v 볼륨이름:컨테이너의 마운트 경로
- 마운트
실습
- 볼륨 생성
docker volume create my-appvol-1
- 볼륨 확인
docker volume ls
- 볼륨 정보 자세히 보기
docker volume inspect my-appvol-1
sudo ls /var/lib/docker/volumes/my-appvol-1/_data
- ubuntu 이미지에 마운트
docker run -d --name vol-test1 -v my-appvol-1:/var/log ubuntu
- 볼륨을 생성하면서 마운트
- 없는 볼륨 이름을 주면 된다.
docker run -d --name vol-test2 -v my-appvol-2:/var/log ubuntu
- vol-test1 컨테이너에 접속
docker exec -it vol-test1 /bin/bash
- volume 제거: 연결된 컨테이너가 있으면 삭제 불가
docker volume rm my-appvol-1
- 컨테이너를 중지하고 삭제
docker stop vol-test1 vol-test2
docker rm vol-test1 vol-test2
docker volume rm my-appvol-1 my-appvol-2
바인드 마운트
호스트 파일 시스템의 파일 또는 디렉토리와 컨테이너의 파일 또는 디렉토리를 직접 매핑하는 것
- 사용자가 파일 또는 디렉토리를 생성하면 해당 호스트 파일 시스템의 소유자 권한으로 연결이 되고 존재하지 않는 경우 자동 생성된다.
- 자동 생성된 디렉토리는 루트 사용자 소유이다.
- 컨테이너 실행 시 지정하여 사용하고 컨테이너 제거 시 바인드 마운트는 해제되지만 호스트 디렉토리는 유지된다.
실습
- apache webserver(https)는 /usr/local/apache2/htdocs 디렉토리의 index.html을 기본적으로 외부로 노출
- 마운트할 디렉토리를 호스트 컴퓨터에 생성: apa_folder
mkdir apa_folder
pwd로 절대 경로 확인: /home/kyla/docker
- 컨테이너를 생성
- 호스트 컴퓨터의 /home/kyla/docker/apa_folder 디렉토리를 컨테이너 내부의 /usr/local/apache2/htdocs 디렉토리와 매핑
docker run --name apa000ex20 -d -p 8090:80 -v /home/kyla/docker/apa_folder:/usr/local/apache2/htdocs httpd
- 기본 페이지 요청
curl localhost:8090
→ 현재는 index of / 내용이 출력됨
- apa_folder에 index.html 파일을 생성해서 작성
vi apa_folder/index.html
##
<h1>Hello Volume</h1> 작성
- 기본 페이지 요청
→ curl localhost:8090: 위에서 작성한 내용이 출력된다.
→ 호스트 컴퓨터의 디렉토리가 마운트 되어서 컨테이너에서는 /usr/local/apache2/htdocs 디렉토리가 된다.
- 컨테이너를 건드린 적이 없는데 변경된 내용이 적용됨
- 컨테이너 삭제
docker stop apa000ex20
docker rm apa000ex20
→ 호스트 디렉토리와 연결해서 쓰는 것 : 바인드 마운트
임시 마운트
호스트 컴퓨터의 메모리에만 지속되는 데이터를 활용하고자 할 때 사용한다.
- 이 때는 컨테이너를 만들 때 -v 대신에 --tmpfs 마운트할디렉토리 형태로 설정해주면 된다.
- 대신 컨테이너가 없어지면 내용이 소멸된다. (컨테이너가 살아 있을 동안만 넣어 놓고 싶을 때)
MySQL 컨테이너 생성
docker run -dit --name=이름 -e MYSQL_ROOT_PASSWORD=루트비밀번호 -e MYSQL_DATABASE=데이터베이스 -p 포트번호:3306 mysql:5.7
mac에서 설치가 안되면
--platform linux/amd64 옵션을 추가하면 된다.