본문 바로가기
개발공부 개발새발/Docker

Docker ) 이미지, 컨테이너 관리.

by 휴일이 2024. 3. 3.

 

꿀팁 : 모든 도커 명령에 --help 를 추가하여 모든 옵션을 볼 수 있다.

모든 컨테이너 보기 (중지된 컨테이너 포함)

docker ps -a

이미지를 기반으로 새로운 컨테이너 만들기

docker run 'container_id or names'

중지한 컨테이너 재시작하기

docker start 'container_id or names'
  • docker run 과는 다르다, 단지 중지된 컨테이너를 재시작하는 것뿐임.

docker start ≠ docker run

  • docker run 으로 실행하면 ?
    • attached 모드 (default)
    • 터미널이 멈추고 더 이상 명령어를 입력할 수 없음
    • 컨테이너는 포어그라운드로 실행중…
  • 하지만 docker start 로 실행하면?
    • detached 모드 (default)
    • 컨테이너가 실행된 후 터미널로 다른 명령도 실행 가능

attached

  • 컨테이너에 바로 연결하며 실행하는 모드
  • 컨테이너 출력결과를 그대로 터미널에 수신한다. (콘솔 출력 결과 등)
    • log 를 터미널에서 그대로 확인 가능

detached

  • 컨테이너를 실행과 동시에 분리한다.

detached 모드로 실행

docker run -p 8000:80 -d 'image_id'
  • -d 플래그를 추가한다. (detached 모드로 실행한다는 명령어)
  • 컨테이너 아이디가 뜨면서 컨테이너가 실행되는 동시에 분리된다.
  • 터미널에 명령어를 입력할 수 있당. (컨테이너에 접속 X)

실행 중인 컨테이너가 보고 싶어요 !

# 컨테이너 직접 접속
docker attach 'container_id or names'

# 로그 메시지 엑세스
docker logs 'container_id or names'

# 로그 메시지 엑세스 + 컨테이너 직접 접속 -> 과거 현재 미래 로그 동시에 볼 수 있음.
docker logs -f 'container_id or names'

# 참고
# start 에 -a 태그를 추가하면 start 도 attached 모드 실행 가능
docker start -a 'container_id or ...'

컨테이너 삭제

# 컨테이너 중지
docker stop (container_id or names)

# 컨테이너 삭제
docker rm (container_id or names)

# 여러 개 컨테이너 한번에 삭제
docker rm (container_id or names) (container_id or names) (container_id or names) ... 
  • 반드시 중지 후에만 삭제 가능.
  • 여러 개를 한 번에 삭제할 땐 띄어쓰기로 구분.

중지 컨테이너 자동 삭제

# 컨테이너가 종료될 때 자동으로 제거하는 설정
docker --rm

# 사용 예시
docker run -p 3000:80 -d --rm (image_id)
  • --rm 설정을 사용하고 컨테이너를 올린 뒤 중지시키면, 컨테이너가 자동으로 삭제된다.
  • 애플리케이션 서버를 올린 경우 흔히 사용되는 명령어기도 하다.
    • 어차피 컨테이너를 중지시킬 땐 코드가 변경되는 경우니까, 그러면 보통 컨테이너 중지 후 바로 삭제하고 새 이미지로 컨테이너를 만들징~

컨테이너 안의 파일 조사

# 실행 중인 컨테이너로 (또는 안에서 밖으로) 파일 또는 폴더를 복사하는 명령어
docker cp (복사하려는 폴더 또는 파일 경로) (container_id or names):(복사하려는 경로)

# EXAMPLE (local to container)
# dummy 디렉토리 안의 파일 전부를 -> 컨테이너 안의 /test 디렉토리로 복사한다.
docker cp dummy/. pensive_margulis:/test

# EXAMPLE (container to local)
# 컨테이너 안의 /test 디렉토리를 dummy 디렉토리로 복사한다.
docker cp pensive_margulis:/test dummy
  • 컨테이너를 삭제하고 다시 빌드하지 않고도 소스코드 내용 복사 가능.
    • 물론 좋은 방법은 아님.
  • 웹 서버 구성 파일만 추가 변경 되었을 경우엔 사용 유용
  • 도커 로그 파일을 로컬 호스트로 복사 가능.
    • 직접 로그 파일 볼 수 있음.

이미지 삭제

를 하기 전

  • mysql 이미지 크기는 596MB 이다.
  • 이건 mysql 이미지 뿐만 아니라 운영체제 이미지까지 추가된 크기!
    • mysql + mysql 이 구동할 수 있는 환경까지 구성한 크기.
# 특정 이미지 제거
docker rmi (image_id)

# 사용되지 않는 모든 이미지 제거
docker image prune
  • 이렇게 이미지를 삭제하면?

  • 이미지 하나가 삭제되는 게 아니라 내부의 모든 레이어가 삭제되는 것을 볼 수 있다. (이건 ubuntu 이미지 삭제해본 것)

도커 이미지 삭제할 때 주의

  • 이미지가 더 이상 컨테이너에서 사용되지 않고
  • 중지된 컨테이너에 불포함된 경우에만 삭제 가능
    • 특정 컨테이너에서 이미지가 사용되고 있다면(중지 중이더라도) 삭제 불가.
    • 먼저 컨테이너를 삭제해야 한다.

이미지 정보 보기

docker image inspect (image_id)
  • 이미지에 대한 정보를 볼 수 있음.

예시 ) mysql 이미지

[
    {
				# 이미지 id
        "Id": "sha256:a2ad6bf2910601c0b626d270f335549fef8ce5b69f0e5f65760b6fc6647cc562",
        "RepoTags": [],
        "RepoDigests": [],
        "Parent": "",
        "Comment": "buildkit.dockerfile.v0",
				# 이미지 생성 시간
        "Created": "2024-02-28T13:10:45.31942569Z",
        "Container": "",
        "ContainerConfig": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": null,
            "Cmd": null,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
				# 사용 중인 도커 버전
        "DockerVersion": "",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
						# 노출될 포트
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
						# 환경 변수
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NODE_VERSION=21.6.2",
                "YARN_VERSION=1.22.19"
            ],
            "Cmd": [
                "node",
                "server.js"
            ],
            "ArgsEscaped": true,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "/app",
						# default entry point (커스텀 엔트리포인트가 없을 경우 해당 엔트리포인트 실행)
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
				# 운영 체제
        "Os": "linux",
        "Size": 1109081638,
        "VirtualSize": 1109081638,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/sg8uupz37v8srioqg4589ks8e/diff:/var/lib/docker/overlay2/ydn6asttq6p4dcg9xe8tadqxy/diff:/var/lib/docker/overlay2/upq3vs22x5g8pq0to37kcwkds/diff:/var/lib/docker/overlay2/d178c0f61146e474c34749548fade7234aa7b480c8f8628c4ed56a2ee75050ac/diff:/var/lib/docker/overlay2/6f56c396e8d3e198b3d4deacaf79fb11e1fb3544cb5f7ae91f4db7e2a76d3278/diff:/var/lib/docker/overlay2/84e5666801d9fb1cfef2773a8463b225a85123a3252d057d1f4152e6677c01e4/diff:/var/lib/docker/overlay2/f9239e255572da6d28db34a71d2d1efc9c9cb5378cb31d631673b9499923068c/diff:/var/lib/docker/overlay2/498c4eb5823c868ee55f98b9c8d814f0357fd697500e917c24c874304a81c3eb/diff:/var/lib/docker/overlay2/61ddc2f740b8b41967f832d10193885e9e8ea6dab9e15baf4af5de54bfe9e8d9/diff:/var/lib/docker/overlay2/455109bd959ebf6fcbba0124958557360d03f4f8b529b4b8d44ac0687683492b/diff:/var/lib/docker/overlay2/b639267ecc9cf5e60c807195e0feff12f36e0b4bc468d8ac1c1912394b08def7/diff",
                "MergedDir": "/var/lib/docker/overlay2/gnlxudgbv7ir45rpyhmcepzxv/merged",
                "UpperDir": "/var/lib/docker/overlay2/gnlxudgbv7ir45rpyhmcepzxv/diff",
                "WorkDir": "/var/lib/docker/overlay2/gnlxudgbv7ir45rpyhmcepzxv/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
						# 해당 이미지 구성 레이어
            "Layers": [
                "sha256:1a5fc1184c481caeb279bce728e080daba423b5215282318ba86e9b8c388a2b4",
                "sha256:f3f47b3309ca3efcca62cc16aee76177047f0535d9ea6a03546be0b8bee30ded",
                "sha256:909275a3eaaa473a212a77d34de795cea1396d9106e9bae20d4fe9b2e052b01f",
                "sha256:9fe4e8a1862c0b5b34840dda2f7b9e6cb10723f51dac0b0cad1f1ef44bf2b4a1",
                "sha256:2c2decbeb47fc629664b7b1584db0793eab9b96d1f582f580386952159bacbfe",
                "sha256:ec1836af8e1eba5b990e2b5dbce2825d82e394a4e964f303f0848e4c566e1d0b",
                "sha256:54ec21bbb047dc9ddcb1279a1d59b3e16bcac60b30ee9d72c9052ee4de352eba",
                "sha256:0b609c0d4b7122b4c9049928fce9ec7de93add1a8a0fc297a2902ecf1a48a6ca",
                "sha256:2b0c1e12eaa99e43738af2e90a813714c7916bf07382ce66a17fef1b9abc8181",
                "sha256:023eca14140563d18947f145ca9b6d291aec54b0e786667b9df9a511554bf13c",
                "sha256:968ac35e4a5aa7373467abb8d40f25ec4de4f29dc9c6bb3592514f13cafe0a58",
                "sha256:13ebcd3732747244c82ddf7bf0072f1e964bc10792a69196a6f45c82b09393c8"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

컨테이너 이름 지정 !

docker --name

# container EXAMPLE
docker run -p 3000:80 -d --rm --name 컨테이너이름 (image_id)

이미지 이름 지정

  • 도커에서 이미지는 name:tag (이름:태그)로 나뉜다.
    • name : repository 라고도 함. 일반적인 이미지 그룹.
    • tag : 이미지의 버전
      • 이 태그를 이용해 같은 이미지여도 다른 버전, 구성을 이용할 수 있음.
      • 태그가 없다면 그 이미지 자체로 고유 식별자.
docker build -t 이름:태그 .

# EXAMPLE
# latest : 최신 버전임을 나타냄.
docker build -t goals:latest .
docker build -t goals:v1.0.0 .
# ... 등등
  • 이미지 뒤에 특정 태그를 추가함으로서 같은 이미지여도 특정 버전, 구성임을 알려줄 수 있다.

이미지 공유

  • 이미지가 있는 모든 사람은 이미지를 기반으로 컨테이너를 만들 수 있다.
    • 누군가와 공유할 때는 컨테이너를 공유하는 게 아니라, 이미지를 공유하는 것.

이미지 공유법

  • 도커 파일 공유.
    • (코드) 파일 필요 → 기반으로 이미지 빌드해야 함.
  • 빌드된 전체 이미지 공유.
    • 소스코드 필요 없이 이미지만으로 즉시 컨테이너 실행 가능.

공유 장소 (?)

  • 도커 허브
    • 도커 공식 이미지 레지스트리
    • 다른 레지스트리 서비스도 많음~
    • 다만 여기는 공식이고 무료당.
      • 유료도 있음.
    • public , private 으로 다 저장 가능.
  • 개인 레지스트리
    • 제공 업체에 따라 기능이 다릅니다.,,
    • 기본적으로 도커 명령어로 push, pull 하면 도커 허브에 저장됨.
      • 개인 레지스트리는 url 추가해야 함.

도커 허브에 이미지를 공유(push)하자 !

docker push (image_name)
docker pull (image_name)
  • 보통 push → upload 라고 생각하자 pull → download

 

  • 기본적으로 도커 허브에 repository 만들고, Docker commands 사용해서 push
  • 이미지 이름에 docker id 가 접두사로 들어가야 한다.
    • 일단 기존에 만들어진 이미지가 있다면, 이미지 이름 수정해야 함.
# 기존에 만들어진 이미지가 있다면, 이미지 이름을 수정하장.
docker tag 이전이름:태그 새이름:태그

# EXAMPLE
# holidaykang : 내 도커 아이디 ㅎㅎ
docker tag node-demo:latest holidaykang/node-demo:latest
  • 이미지 이름을 바꿔도 이전 이미지가 제거되는 게 아님!!!
    • 이전 이미지의 복제본이 생성됨.
docker login
  • 기본적으로 본인 레포에만 push 가능.
    • 로그인해서 push 권한을 부여해준다.
docker push 도커아이디/이름:태그

# EXAMPLE
docker push holidaykang/node-demo:latest
  • 이미 이용하고 있는 노드 이미지 등을 전부 업로드하는 게 아니라 추가 코드만 푸쉬함
    • 도커허브에서는 공간 절약
    • 나는 대역폭 절약~

 

  • 이전에 내가 push 했던 요만큼 이미지 ㅎㅎ
  • 여러 태그로 푸쉬해싸는 걸 볼 수 있당. 날짜도 있음.

공유 이미지를 가져와서 사용하자

# 항상 컨테이너 레지스트리에서 최신 이미지를 가져온다.
docker pull 이미지이름

# 1. 일단 로컬에 이미지가 있다면 로컬 이미지를 사용한다.
# 2. 없다면 자동으로 도커 허브에서 이미질르 가져와 실행한다.
# 3. 단, 이미 로컬에 이미지가 있다면 최신 버전인지 체크하지 않고 그냥 사용한다.
# 최신 버전을 사용하려면 pull 로 새로 이미지를 업데이트 해야한다.
docker run 이미지이름...

이 명령의 결과는

docker build -t myimage .
docker run --name mycontainer myimage
docker stop mycontainer
  • 이미지를 빌드한다. 이름은 myimage 로 한다.
  • 컨테이너를 시작한다. 컨테이너 이름은 mycontainer 이며 myimage 를 기반으로 한다.
  • mycontainer 가 중지된다.

다음 중 어떤 명령이 실패하는가

docker build -t myimage:latest .
docker run --name mycontainer --rm myimage
docker stop mycontainer

1. docker ps -a
2. docker rmi myimage:latest
3. docker rm mycontainer
  • 3번 docker rm mycontainer
    • —rm 명령으로 이미 컨테이너는 중지와 동시에 삭제되었으므로 이 명령이 실패함.

태그란

이미지 이름에 그 이미지의 여러 ‘버전’을 같이 붙인 것.

728x90