컨테이너가 종료되면 데이터가 손실됩니다


394

Docker의 대화 형 자습서FAQ 에도 불구하고 컨테이너가 종료되면 데이터가 손실됩니다.

여기에 설명 된대로 Docker를 설치했습니다 : 우분투 13.04에서 아무런 문제없이 http://docs.docker.io/en/latest/installation/ubuntulinux .

그러나 종료하면 모든 데이터가 손실됩니다.

iman@test:~$ sudo docker version
Client version: 0.6.4 
Go version (client): go1.1.2 
Git commit (client): 2f74b1c 
Server version: 0.6.4 
Git commit (server): 2f74b1c 
Go version (server): go1.1.2 
Last stable version: 0.6.4 


iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:05:47 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu apt-get install ping
Reading package lists... 
Building dependency tree... 
The following NEW packages will be installed: 
  iputils-ping 
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 
Need to get 56.1 kB of archives. 
After this operation, 143 kB of additional disk space will be used. 
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB] 
debconf: delaying package configuration, since apt-utils is not installed 
Fetched 56.1 kB in 0s (195 kB/s) 
Selecting previously unselected package iputils-ping. 
(Reading database ... 7545 files and directories currently installed.) 
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ... 
Setting up iputils-ping (3:20101006-1ubuntu1) ... 
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:06:11 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu touch /home/test
iman@test:~$ sudo docker run ubuntu ls /home/test
ls: cannot access /home/test: No such file or directory 

또한 동일한 결과로 대화식 세션으로 테스트했습니다. 내가 무언가를 잊었습니까?

편집 : 새로운 의사 사용자에게 중요

@으로 모하메드-noureldin 등은 실제로는 말했다 하지 종료 용기 . 매번 새 컨테이너를 만듭니다.


10
" 컨테이너 종료 " 라고 할 수는 없으며 새 컨테이너를 만드는 중입니다. 종료 단어를 사용하면 많은 혼란을 겪을 수 있습니다.
Mohammed Noureldin

1
@MohammedNoureldin, 당신은 옳습니다. 종료는 정확하지 않지만 이것은 정확히 당신, 나 및 다른 사람들이 생각한 것입니다. 더 나은 질문입니다. 편집하면 질문에 대한 답이됩니다! 새로운 검색자는 여기에서 찾을 수 없습니다!
iman

Docker를 처음 시작할 때 실제로 귀하의 질문으로 인해 해당 주소가 잘못되었다고 생각했습니다. 새 제목을 검토하고 수락했는데 어떤 사람이 잘못된 제목을 주장해야하는 이유를 이해하지 못합니다. 질문과 결정입니다.
Mohammed Noureldin

3
@MohammedNoureldin에 동의합니다. 특정 제목, 예 및 허용 된 답변의 조합은 미래의 독자와 특히 초보자가 이해하는 데 도움이되지 않습니다 Docker. 초보자는 분명히 이와 같은 것을 검색하기 때문에 제목과 원래 질문을 유지할 것을 제안합니다. 하지만 글을 쓸 당시의 오해를 설명하는 내용을 추가해 보시지 않겠습니까? 명확하게하는 데 도움이됩니다. 이것이 바로 여기 우리 문화입니다. 그렇지 않습니까? :-)
tgogos

2
나는 ... 유 ... u는 당신의 용기를 실행하지 시작할 필요가 종료 이미지를 실행할 때마다이 agane 새 컨테이너에 부착 고정 표시기이 의지 도움을 고정 표시기 시작 <컨테이너 ID>를 만들어이 문제를 가지고 <컨테이너 ID>
fatemeh

답변:


399

컨테이너에 대한 변경 사항 을 커밋 한 다음 실행해야합니다. 이 시도:

sudo docker pull ubuntu

sudo docker run ubuntu apt-get install -y ping

그런 다음이 명령을 사용하여 컨테이너 ID를 얻으십시오.

sudo docker ps -l

컨테이너에 변경 사항을 커밋하십시오.

sudo docker commit <container_id> iman/ping 

그런 다음 컨테이너를 실행하십시오.

sudo docker run iman/ping ping www.google.com

이 작동합니다.


9
따라서 데이터를 보존하기 위해 각 실행 후에 커밋 을 사용해야 합니다.
iman

5
커밋은 변경 사항을 저장하고 다음에 해당 이미지에서 새 컨테이너를 실행할 때 마지막 저장 시점 또는 커밋, 데이터 보존.
Unferth

7
@ 변경 사항을 계속 커밋하려면 어떻게해야합니까? 지금까지로 더 많은 이미지를 만듭니다 <none>. 기존 이미지 위에 커밋을 계속 추가하려면 어떻게합니까?
Marconi

62
점진적으로 변경 사항을 커밋하는 것은 "도커 방식"이 아닙니다. DOCKERFILE을 사용하십시오.
user2105103

23
컨테이너 내에서 어떻게 커밋 하시겠습니까? 다음 시나리오를 고려하십시오 : 1) 컨테이너를 다음과 같이 실행 중입니다 : docker run -i -t myimage / bin / bash 2) 변경하십시오 .3) 컨테이너 내에서 커밋 할 수 없으므로 컨테이너를 종료하면 컨테이너가 종료됩니다. 이전 변경 사항을 적용하지 않고 모든 데이터를
잃게

374

docker run컨테이너를 시작하는 데 사용 하면 실제로 지정한 이미지를 기반으로 새 컨테이너생성 됩니다.

여기에있는 다른 유용한 답변 외에도 기존 컨테이너가 종료 된 후에 다시 시작할 수 있으며 변경 사항이 여전히 남아 있습니다.

docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin

88
docker ps도커 컨테이너 만 실행하는 것을 보여줍니다. docker ps -a당신에게도 나왔고 당신이 계속 달릴 수 있다는 것을 보여줍니다. 커밋은 나중에 사용할 수 있도록 스냅 샷을 만들려면 각 실행 후에 만 ​​필요합니다. 그렇지 않으면 컨테이너 자체가 계속 사용됩니다.
user1278519

2
질문하십시오. 따라서 jenkins서버 도커를 다운로드하여 CI 호스트에서 실행하고 일부 작업을 실행하면 jenkins 서버가 디스크에 로그를 기록합니다. 이제 내 도커를 호스팅 한 서버가 다시 시작되고 jenkins 도커를 다시 시작하면 모든 로그 파일이 손실됩니까? 그렇다면 jenkinsCI에 jenkins를 쉽게 설치하기 위해 어떻게 docker를 사용할 수 있습니까?
Jas

2
@Jas 동일한 컨테이너를 사용하고 새 컨테이너를 만들지 않아도 문제가 없습니다. 오늘날 Docker에는 재시작 정책이 있으므로 시스템 재부팅시 동일한 컨테이너를 다시 시작하도록 구성 할 수 있습니다. 또한 젠킨스를 집에 두어 외부에서 (백업 등) 액세스 할 수 있도록 권합니다.
ZeissS

7
종료하면 컨테이너에서 파일을 복사하는 편리한 방법이 있습니다.docker cp $(docker ps -alq):/path/to/file .
Josh Habdas

3
이름으로 컨테이너를 시작하고 첨부 할 수도 있습니다. (eg docker run -it --name my_debian debianand after docker start my_debian && docker attach my_debian)
Johnny Willer 2016 년

127

컨테이너 데이터를 유지하는 방법은 다음과 같습니다.

  1. 도커 볼륨

  2. 도커 커밋

    a) 우분투 이미지에서 컨테이너를 만들고 bash 터미널을 실행하십시오.

       $ docker run -i -t ubuntu:14.04 /bin/bash
    

    b) 터미널 설치 컬 내부

       # apt-get update
       # apt-get install curl
    

    c) 컨테이너 터미널을 종료

       # exit
    

    d) 다음 명령을 실행하여 컨테이너 ID를 기록하십시오.

       $ docker ps -a
    

    e) 컨테이너를 새로운 이미지로 저장

       $ docker commit <container_id> new_image_name:tag_name(optional)
    

    f) 말림이 설치된 새 이미지를 볼 수 있는지 확인하십시오.

       $ docker images           
    
       $ docker run -it new_image_name:tag_name bash
          # which curl
            /usr/bin/curl
    

exit이전에 필요 docker commit합니까? 감사.
Abhishek Anand

2
@AbhishekAnand yes. docker run명령으로 컨테이너에서 bash를 실행하고 -i-t옵션 (TTY와 상호 작용) 으로 인해 bash를 유지하기 때문 입니다. 그러나 Docker는 컨테이너 외부의 컴퓨터에서 실행되므로 컨테이너를 내부에서 필요한대로 변경 한 후 시스템 쉘로 돌아가려면 컨테이너 쉘로 이동해야합니다 exit(또는 Ctrl + D). 또한 명령에 쓰여지는 다른 쉘을 나타내는 #$대답에 유의하십시오 .
Erik

빠른 질문 : 커밋하지 않으면 데이터가 손실됩니다. 알았습니다. 그러나 nginx 구성을 변경할 때 왜 업데이트가 유지됩니까? @Erik
grep

@grep 명확하고 재현 가능한 MWE가있는 경우이 특정 사용 사례에 대해 아직없는 경우 새로운 질문을하십시오.
Erik

3. docker stop뒤에 docker start.
carillonator

59

뿐만 아니라 Unferth의 대답 , 생성하는 것이 좋습니다 Dockerfile을 .

빈 디렉토리 에서 다음 내용으로 "Dockerfile"이라는 파일을 만듭니다 .

FROM ubuntu
RUN apt-get install ping
ENTRYPOINT ["ping"]

Dockerfile을 사용하여 이미지를 작성하십시오 . 16 진수 이미지 번호를 기억할 필요가 없도록 태그를 사용하겠습니다.

$ docker build -t iman/ping .

그런 다음 컨테이너 에서 이미지실행하십시오 .

$ docker run iman/ping stackoverflow.com

1
수동으로 두 번 이상 수행 할 필요가 정확히 도커의 요점입니다. dockerfile을 만들고 결과 이미지를 커밋하고 업로드하십시오. 이미지를 앞으로 당깁니다.
Brandon Bertelsen

11

귀하의 질문에 대해 훨씬 간단한 답변을 얻었습니다. 다음 두 명령을 실행하십시오.

sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a

위의 ps -a 명령은 모든 컨테이너의 목록을 반환합니다. 이미지 이름- 'ubuntu'를 참조하는 컨테이너 이름을 사용하십시오. docker auto는 컨테이너의 이름을 생성합니다 (예 :-- 'lightlyxuyzx'옵션을 사용하지 않는 경우).

-t 및 -d 옵션은 중요하며 작성된 컨테이너는 분리되어 있으며 -t 옵션을 사용하여 아래에 제공된대로 다시 연결할 수 있습니다.

--name 옵션을 사용하면 내 경우 'mycontainername'으로 컨테이너 이름을 지정할 수 있습니다.

sudo docker exec -ti mycontainername bash

위의 명령은 bash 쉘을 사용하여 컨테이너에 로그인하는 데 도움이됩니다. 이 시점에서 컨테이너의 변경 사항은 docker에 의해 자동으로 저장됩니다. 예를 들어- apt-get install curl컨테이너 내부 문제없이 컨테이너를 종료하면 docker가 변경 사항을 자동으로 저장합니다.

다음 사용시에는이 컨테이너로 작업 할 때마다이 두 명령을 실행하면됩니다.

이 아래 명령은 중지 된 컨테이너를 시작합니다.

sudo docker start mycontainername

sudo docker exec -ti mycontainername bash

포트와 공유 공간이있는 또 다른 예는 다음과 같습니다.

docker run -t -d --name mycontainername -p 5000:5000 -v ~/PROJECTS/SPACE:/PROJECTSPACE 7efe2989e877 /bin/bash

내 경우 : 7efe2989e877-이전 컨테이너를 사용하여 얻은 이미지입니다.

도커 ps -a


4
Ubuntu 18.04의 Docker 18.09.2에서는 그대로 작동하지 않습니다. --name이미지 이름 앞에 및 옵션을 다음 과 같이 입력하면 작동합니다 .docker run --name mycontainername -t -d ubuntu /bin/bash
Stéphane Gourichon


3

내 제안은 docker compose와 함께 docker를 관리하는 것입니다. 프로젝트의 모든 도커 컨테이너를 관리하는 쉬운 방법입니다. 버전을 매핑하고 다른 컨테이너를 연결하여 함께 사용할 수 있습니다.

문서는 docker의 문서보다 이해하기 매우 쉽습니다.

도커 작성 문서

베스트


3

질문에 대한 위의 답변이 실제로 있습니다. 다른 답변이 필요하지는 않지만 가능한 한 가장 간단한 단어로 주제에 대한 개인적인 의견을 제시하고 싶습니다.

다음은 결론을 내리는 데 도움이되는 컨테이너 및 이미지에 대한 몇 가지 사항입니다.

  • 도커 이미지는 다음과 같습니다.
    1. 주어진 컨테이너에서 생성
    2. 삭제
    3. 컨테이너 수를 작성하는 데 사용
  • 도커 컨테이너는 다음과 같습니다.
    1. 이미지에서 생성
    2. 시작
    3. 중지
    4. 다시 시작
    5. 삭제
    6. 많은 수의 이미지를 만드는 데 사용
  • docker run 명령은 다음을 수행합니다 .
    1. 이미지를 다운로드하거나 캐시 된 이미지를 사용합니다
    2. 그것으로부터 새로운 컨테이너를 만듭니다
    3. 컨테이너를 시작합니다
  • Dockerfile을 사용하여 이미지를 만드는 경우 :
    1. 이미 이미지가 도커 컨테이너를 실행하는 데 사용된다는 것은 이미 잘 알려져 있습니다.
    2. docker build 명령을 실행 한 후 docker back-the-sscenes는 기본 파일 시스템으로 실행중인 컨테이너를 만들고 Dockerfile 내부의 단계에 따라 개발자가 필요에 따라 컨테이너를 구성합니다.
    3. 컨테이너가 Dockerfile의 사양으로 구성되면 이미지로 커밋됩니다.
    4. 이미지가 락앤롤 할 준비가되었습니다!

결론 :

보시다시피, 도커 컨테이너는 도커 이미지와 독립적입니다.

컨테이너의 고유 ID가 제공되면 컨테이너를 다시 시작할 수 있습니다 ( id를 얻는 데 사용 docker ps --all) .

컨테이너가 실행될 때 새 디렉토리 만들기, 파일 만들기, 도구 설치 등과 같은 모든 작업을 컨테이너 내부에서 수행 할 수 있습니다. 컨테이너가 중지되면 모든 변경 사항이 유지됩니다. 컨테이너 중지 및 재시작은 컴퓨터 시스템을 재부팅하는 것과 같습니다.

이미 생성 된 컨테이너는 항상 다시 시작할 수 있지만 docker run명령을 실행하면 이미지에서 새 컨테이너가 만들어 지므로 새 컴퓨터 시스템과 같습니다. 이전 컨테이너 내부에서 변경 한 사항은 현재 이해할 수 있듯이이 새로운 컨테이너에서는 사용할 수 없습니다.

마지막 메모 :

데이터가 손실 된 것처럼 보이는 이유가 아직 분명하지만 항상 존재합니다. 그러나 다른 [오래된] 컨테이너에 있습니다. 따라서 docker start& docker run명령 의 차이점을 잘 알고 혼동하지 마십시오.


1

비슷한 문제 (Dockerfile만으로는 해결할 수없는 방법) 가이 페이지를 가져 왔습니다.

0 단계 : Dockerfile이이를 해결할 수 있기를 바라고 : --dns 및 --dns-search가 Dockerfile 지원에 나타날 때까지 – 인트라넷 기반 리소스를 통합 할 방법이 없습니다.

1 단계 : Dockerfile을 사용하여 이미지를 빌드 한 후 (Docker 실행 스크립트를 실행하여 인트라넷 기반의 이미지를 배포하는 이미지가 있는 심각한 Dockerfile이 현재 폴더 에 있어야 함 ). 예: docker run -d \ --dns=${DNSLOCAL} \ --dns=${DNSGLOBAL} \ --dns-search=intranet \ -t pack/bsp \ --name packbsp-cont \ bash -c " \ wget -r --no-parent http://intranet/intranet-content.tar.gz \ tar -xvf intranet-content.tar.gz \ sudo -u ${USERNAME} bash --norc"

2 단계 : 로컬 dns 레코드를 제공하는 데몬 모드 에서 docker run 스크립트를 적용 하여 로컬 항목을 다운로드하고 배포 할 수 있습니다.

중요한 점 : 실행 스크립트는 /usr/bin/sudo -u ${USERNAME} bash --norc설치 스크립트가 끝난 후에도 컨테이너를 계속 실행하는 것과 같은 것으로 끝나야 합니다.

아니요 , CTRL-p CTRL-q 를 누를 때까지 내부 should 명령 프롬프트 안에 남아 있기 때문에 전체 자동화 문제에 대해 컨테이너를 대화식 모드로 실행할 수 없습니다 .

아니 , 설치 스크립트의 끝에서 상호 작용 bash가 실행되지 않으면 컨테이너는 스크립트 실행이 완료된 직후 종료되어 모든 설치 결과를 잃습니다.

3 단계 : 컨테이너가 여전히 백그라운드에서 실행 중이지만 컨테이너가 설치 절차를 종료했는지 여부는 확실하지 않습니다. 다음 블록을 사용하여 실행 절차 완료를 결정 while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" - do echo "." sleep 5 done 합니다. 설치가 완료된 후에 만 ​​스크립트가 계속 진행됩니다. :이 통화에 대한 권리 순간이다 커밋 , (그것은이 (가)에서와 동일 할 수도 대상 이미지 이름으로 현재 컨테이너 ID를 제공하는 빌드 / 실행 예 절차하지만 로컬 설치 목적 태그가 추가 :. docker commit containerID pack/bsp:toolchained.이 링크를 참조하십시오 적절한 containerID 를 얻는 방법

4 단계 : 컨테이너가 로컬 설치로 업데이트되었으며 새로 할당 된 이미지 (목적 태그가 추가 된 이미지)로 커밋되었습니다. 컨테이너 실행을 중지하는 것이 안전합니다. 예:docker stop packbsp-cont

stage5 : 로컬 설치가있는 컨테이너를 실행해야 할 때마다 이전에 저장된 이미지로 시작하십시오. 예:docker run -d -t pack/bsp:toolchained


1

훌륭한 답변 here 사용자 kgs에서 빠져 나온 도커를 계속 사용하는 방법

docker start $(docker ps -a -q --filter "status=exited")
(or in this case just docker start $(docker ps -ql) 'cos you don't want to start all of them)

docker exec -it <container-id> /bin/bash

두 번째 줄은 중요합니다. 따라서 exec는 이미지가 아닌 containerid에서 실행 대신 사용됩니다. 그리고 컨테이너가 시작된 후에 수행합니다.


0

이 디자인 선택의 요점에 대한 답은 없습니다. 도 커가이 두 가지 오류를 방지하기 위해이 방법으로 작동한다고 생각합니다.

  • 반복 된 재시작
  • 부분 오류
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.