소개
이 튜토리얼은 Docker 컨테이너 이미지 복제 과정을 안내합니다. Docker 이미지는 애플리케이션 실행에 필요한 모든 것을 포함하는 패키지 템플릿이며, 복제를 통해 사용자 정의할 수 있는 복사본을 만들 수 있습니다. 이 가이드가 끝나면 Docker 이미지를 복제하고, 수정하고, 배포를 위해 공유하는 방법을 이해하게 될 것입니다.
이 튜토리얼은 Docker 컨테이너 이미지 복제 과정을 안내합니다. Docker 이미지는 애플리케이션 실행에 필요한 모든 것을 포함하는 패키지 템플릿이며, 복제를 통해 사용자 정의할 수 있는 복사본을 만들 수 있습니다. 이 가이드가 끝나면 Docker 이미지를 복제하고, 수정하고, 배포를 위해 공유하는 방법을 이해하게 될 것입니다.
Docker 이미지를 복제하기 전에 Docker 가 무엇인지 이해하고 환경이 제대로 설정되었는지 확인하는 것이 중요합니다.
Docker 는 컨테이너를 사용하여 애플리케이션을 개발, 배포 및 실행하는 플랫폼입니다. 컨테이너는 애플리케이션과 모든 종속성을 함께 패키징하여 서로 다른 환경에서 일관되게 작동하도록 보장합니다. 이는 Docker 를 개발 및 배포 워크플로우에 특히 유용하게 만듭니다.
먼저 Docker 가 시스템에 올바르게 설치되었는지 확인해 보겠습니다. 터미널 창을 열고 다음을 실행합니다.
docker --version
다음과 유사한 출력이 표시되어야 합니다.
Docker version 20.10.21, build baeda1f
다음으로 Docker 서비스가 실행 중인지 확인합니다.
sudo systemctl status docker
출력은 Docker 가 활성 상태 (실행 중) 임을 나타내야 합니다. 실행 중이 아니면 다음 명령으로 시작할 수 있습니다.
sudo systemctl start docker
Docker 가 제대로 작동하는지 확인하기 위해 간단한 테스트 명령을 실행해 보겠습니다.
docker run hello-world
이 명령은 hello-world 이미지를 다운로드하여 실행하며, 확인 메시지를 출력하고 종료합니다. 다음과 유사한 출력이 표시되어야 합니다.
Hello from Docker!
This message shows that your installation appears to be working correctly.
시스템에서 현재 사용 가능한 Docker 이미지를 확인하려면 다음을 실행합니다.
docker images
이 명령은 현재 로컬에 저장된 모든 Docker 이미지를 나열합니다. 출력은 이미지 레포지토리 (repository), 태그 (tag), 이미지 ID, 생성 날짜 및 크기를 보여줍니다.
이제 Docker 가 제대로 작동하는 것을 확인했으므로 다음 단계에서 Docker 이미지 작업을 시작할 준비가 되었습니다.
이 단계에서는 Docker Hub 에서 Docker 이미지를 풀 (pull) 하여 로컬 시스템에서 실행합니다. 이는 Docker 이미지 복제 과정의 첫 번째 단계입니다.
Docker Hub 는 사용자가 컨테이너 이미지를 찾고 공유할 수 있는 클라우드 기반 레지스트리 서비스입니다. 소프트웨어 공급업체가 유지 관리하는 많은 공식 이미지와 커뮤니티에서 기여한 이미지를 포함합니다.
Docker Hub 에서 공식 Nginx 웹 서버 이미지를 풀해 보겠습니다. Nginx 는 이 튜토리얼 전체에서 예제로 사용할 인기 있는 웹 서버입니다.
다음 명령을 실행하여 Nginx 이미지를 다운로드합니다.
docker pull nginx:latest
이 명령은 Nginx 이미지의 최신 버전을 다운로드합니다. 다운로드 진행 상황을 보여주는 출력이 표시되어야 합니다.
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
이미지가 성공적으로 다운로드되었는지 확인하려면 Docker 이미지를 다시 나열합니다.
docker images
이제 목록에 Nginx 이미지가 표시되어야 합니다.
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 142MB
이제 방금 풀한 Nginx 이미지를 기반으로 컨테이너를 실행해 보겠습니다.
docker run --name my-nginx -d -p 8080:80 nginx
이 명령은 다음을 수행합니다.
--name my-nginx: 컨테이너 이름을 "my-nginx"로 지정합니다.-d: 컨테이너를 detached 모드 (백그라운드) 로 실행합니다.-p 8080:80: 호스트의 포트 8080 을 컨테이너의 포트 80 에 매핑합니다.nginx: 이전에 풀한 Nginx 이미지를 사용합니다.컨테이너 ID 인 긴 문자열 출력이 표시되어야 합니다.
컨테이너가 실행 중인지 확인하려면 다음을 실행합니다.
docker ps
다음과 유사한 출력이 표시되어야 합니다.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8d3e9c5b9a7 nginx "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 0.0.0.0:8080->80/tcp my-nginx
이제 웹 브라우저를 열고 http://localhost:8080으로 이동하거나 curl 을 사용하여 Nginx 기본 페이지에 액세스할 수 있습니다.
curl http://localhost:8080
Nginx 환영 페이지의 HTML 콘텐츠가 표시되어야 합니다.
이제 Docker 이미지를 성공적으로 풀하고 실행했으므로 다음 단계에서 이를 기반으로 사용자 정의 이미지를 만들 준비가 되었습니다.
이제 실행 중인 Nginx 컨테이너가 있으므로 이를 수정하여 사용자 정의 이미지를 생성합니다. 이것이 복제 프로세스의 핵심입니다. 다음을 수행합니다.
Docker 이미지는 두 가지 방법으로 생성할 수 있습니다.
이 튜토리얼에서는 복제 프로세스를 이해하는 데 더 간단하므로 두 번째 방법을 사용합니다.
먼저 기본 Nginx 환영 페이지를 대체할 사용자 정의 HTML 파일을 만들어 보겠습니다. 실행 중인 컨테이너에 들어가서 파일을 수정해야 합니다.
다음 명령을 사용하여 실행 중인 컨테이너 내에서 셸을 실행합니다.
docker exec -it my-nginx bash
이렇게 하면 컨테이너 내에서 대화형 bash 셸이 열립니다. 이제 사용자 정의 HTML 파일을 만들어 보겠습니다.
echo "<html><body><h1>My Custom Docker Image</h1><p>This is a custom Nginx image created in the LabEx tutorial.</p></body></html>" > /usr/share/nginx/html/index.html
파일의 내용을 확인하여 변경 사항을 확인할 수 있습니다.
cat /usr/share/nginx/html/index.html
이제 컨테이너 셸을 종료합니다.
exit
Nginx 서버에 다시 액세스하여 변경 사항이 적용되었는지 테스트해 보겠습니다.
curl http://localhost:8080
이제 기본 Nginx 환영 페이지 대신 사용자 정의 HTML 콘텐츠가 표시되어야 합니다.
이제 컨테이너를 수정했으므로 이러한 변경 사항을 포함하는 새 이미지를 생성합니다. 이는 docker commit 명령을 사용하여 수행됩니다.
docker commit my-nginx my-custom-nginx:v1
이 명령은 my-nginx 컨테이너의 현재 상태를 기반으로 태그 v1이 있는 my-custom-nginx라는 새 이미지를 생성합니다.
새 이미지가 생성되었는지 확인해 보겠습니다.
docker images
목록에 새 이미지가 표시되어야 합니다.
REPOSITORY TAG IMAGE ID CREATED SIZE
my-custom-nginx v1 a1b2c3d4e5f6 10 seconds ago 142MB
nginx latest 605c77e624dd 2 weeks ago 142MB
이제 원래 컨테이너를 중지하고 제거한 다음 사용자 정의 이미지를 기반으로 새 컨테이너를 실행해 보겠습니다.
docker stop my-nginx
docker rm my-nginx
docker run --name my-custom-container -d -p 8081:80 my-custom-nginx:v1
이러한 명령은 다음을 수행합니다.
새 컨테이너가 올바르게 실행되고 있는지 확인해 보겠습니다.
docker ps
목록에 새 컨테이너가 표시되어야 합니다.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
g9h8i7j6k5l4 my-custom-nginx:v1 "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 0.0.0.0:8081->80/tcp my-custom-container
이제 새 포트에서 Nginx 서버에 액세스합니다.
curl http://localhost:8081
동일한 사용자 정의 HTML 콘텐츠가 표시되어 새 이미지에 우리가 만든 변경 사항이 포함되어 있는지 확인합니다.
축하합니다! Docker 이미지를 성공적으로 복제하고 사용자 정의했습니다. 다음 단계에서는 이 사용자 정의 이미지를 공유하는 방법을 배우겠습니다.
이제 사용자 정의 Docker 이미지를 만들었으므로 이를 적절하게 태깅하고 공유할 준비를 하는 방법을 배우겠습니다. 실제 시나리오에서는 이미지를 Docker Hub 와 같은 레지스트리에 푸시하겠지만, 이 튜토리얼에서는 준비 단계에 집중하겠습니다.
Docker 이미지는 레포지토리 이름과 태그로 식별됩니다. 태그는 이미지의 버전 관리 및 구성을 돕습니다. 기본 태그는 latest이지만 의미 있는 버전 태그를 사용하는 것이 좋습니다.
사용자 정의 이미지에 몇 가지 태그를 더 추가해 보겠습니다.
docker tag my-custom-nginx:v1 my-custom-nginx:latest
docker tag my-custom-nginx:v1 my-custom-nginx:stable
이러한 명령은 이미지에 latest 및 stable의 두 가지 추가 태그를 생성합니다. 실제 이미지 데이터는 세 개의 태그 간에 공유되므로 이 작업은 매우 효율적입니다.
이미지를 다시 확인해 보겠습니다.
docker images
이제 my-custom-nginx에 대한 여러 항목이 표시되어야 합니다.
REPOSITORY TAG IMAGE ID CREATED SIZE
my-custom-nginx v1 a1b2c3d4e5f6 10 minutes ago 142MB
my-custom-nginx latest a1b2c3d4e5f6 10 minutes ago 142MB
my-custom-nginx stable a1b2c3d4e5f6 10 minutes ago 142MB
nginx latest 605c77e624dd 2 weeks ago 142MB
모든 my-custom-nginx 이미지가 동일한 이미지 ID 를 가지고 있음을 알 수 있습니다. 이는 서로 다른 태그가 있는 동일한 이미지임을 나타냅니다.
실제 시나리오에서는 이미지를 Docker Hub 와 같은 레지스트리에 푸시합니다. 이렇게 하려면 다음을 수행해야 합니다.
데모 목적으로 Docker Hub 사용자 이름이 yourusername이라고 가정해 보겠습니다. 이미지를 푸시할 준비를 하는 방법은 다음과 같습니다.
docker tag my-custom-nginx:v1 yourusername/my-custom-nginx:v1
이미지를 푸시하려면 (실제 시나리오에서) 다음을 사용합니다.
## This is for demonstration only - we won't actually push
## docker push yourusername/my-custom-nginx:v1
레지스트리에 푸시하는 대신 수동 전송을 위해 Docker 이미지를 파일에 저장할 수도 있습니다.
docker save -o my-custom-nginx.tar my-custom-nginx:v1
이 명령은 이미지를 my-custom-nginx.tar라는 tarball 에 저장합니다. 파일이 생성되었는지 확인할 수 있습니다.
ls -lh my-custom-nginx.tar
다음과 유사한 출력이 표시되어야 합니다.
-rw------- 1 labex labex 142M Nov 10 12:34 my-custom-nginx.tar
다른 머신 (또는 이미지를 제거한 후 동일한 머신) 에서 tarball 에서 이미지를 로드하려면 다음을 사용합니다.
## We won't actually run this command as part of the tutorial
## docker load -i my-custom-nginx.tar
다른 사람들이 사용자 정의 이미지를 이해하도록 돕기 위해 변경 사항을 문서화하는 것이 좋습니다. 간단한 설명서 파일을 만들어 보겠습니다.
cat > my-custom-nginx-doc.txt << EOF
## My Custom Nginx Image
This is a custom Nginx image created by cloning the official Nginx image.
### Changes Made
- Replaced the default welcome page with a custom HTML page
### How to Run
docker run --name my-custom-container -d -p 8080:80 my-custom-nginx:v1
### Version History
- v1: Initial custom version with modified welcome page
EOF
이제 사용자 정의 이미지에 대한 설명서 파일이 있습니다.
축하합니다! Docker 이미지를 태깅하고 공유할 준비를 하는 방법을 배웠습니다. 다음 단계에서는 몇 가지 모범 사례를 살펴보고 환경을 정리합니다.
이 마지막 단계에서는 Docker 이미지를 사용하는 몇 가지 모범 사례를 다루고 환경을 정리합니다.
latest 태그에 의존하기보다는 항상 특정 버전 태그를 사용하십시오. 이렇게 하면 배포의 일관성이 보장됩니다.
## Better approach
docker pull nginx:1.23.2
## Less predictable
docker pull nginx:latest
이미지가 작을수록 다운로드 속도가 빠르고 저장 공간을 덜 사용합니다. 가능하면 alpine 기반 이미지를 사용하는 것을 고려하십시오.
## Let's see the size difference
docker pull nginx:alpine
docker images | grep nginx
다음과 같은 출력이 표시될 수 있습니다.
nginx alpine 2bc7edbc3cf2 2 weeks ago 40.7MB
nginx latest 605c77e624dd 2 weeks ago 142MB
alpine 버전이 훨씬 작습니다!
Dockerfile 로 이미지를 만들 때 최종 이미지 크기를 작게 유지하려면 멀티 스테이지 빌드를 사용하십시오. 다음은 간단한 예입니다 (이것을 실행할 필요는 없습니다).
## Build stage
FROM golang:1.17 AS builder
WORKDIR /app
COPY . .
RUN go build -o app
## Final stage
FROM alpine:3.15
COPY --from=builder /app/app /app
CMD ["/app"]
항상 사용자 정의 이미지에 대한 문서를 유지 관리합니다. 여기에는 다음이 포함됩니다.
이전 단계에서 간단한 설명서 파일을 만들었습니다.
이미지에 대한 취약성을 정기적으로 검사합니다.
## Example of scanning (Docker Desktop has this built-in)
## docker scan my-custom-nginx:v1
Docker 이미지를 검사하는 데 유용한 명령을 살펴보겠습니다.
docker inspect my-custom-nginx:v1
이 명령은 이미지의 레이어, 구성 및 환경 변수를 포함한 자세한 정보를 표시합니다.
이미지가 어떻게 빌드되었는지 기록을 볼 수 있습니다.
docker history my-custom-nginx:v1
이것은 이미지의 각 레이어와 이를 생성한 명령을 보여줍니다.
이제 생성한 컨테이너와 이미지를 제거하여 환경을 정리해 보겠습니다.
docker stop my-custom-container
docker rm my-custom-container
docker rmi my-custom-nginx:v1 my-custom-nginx:latest my-custom-nginx:stable
docker rmi nginx:latest nginx:alpine
docker ps -a
docker images
Docker 는 사용하지 않는 리소스를 정리하는 편리한 명령을 제공합니다.
docker system prune
이것은 중지된 모든 컨테이너, 사용하지 않는 네트워크, 댕글링 이미지 및 빌드 캐시를 제거합니다. 진행하기 전에 확인하라는 메시지가 표시됩니다.
더 적극적인 정리를 위해 다음을 사용할 수 있습니다.
docker system prune -a
이것은 댕글링 이미지뿐만 아니라 사용하지 않는 모든 이미지도 추가로 제거합니다.
이제 다음을 수행하는 방법을 배웠습니다.
이러한 기술은 Docker 이미지를 사용하는 기반을 형성하며 컨테이너화 여정을 계속 진행하는 데 유용할 것입니다.
이 실습 튜토리얼에서는 Docker 컨테이너 이미지를 복제하는 전체 프로세스를 배웠습니다. Docker 기본 사항을 이해하고 환경을 확인하는 것으로 시작했습니다. 그런 다음 공식 Nginx 이미지를 풀하고 컨테이너로 실행했습니다. 다음으로, 해당 내용을 수정하여 이 컨테이너를 사용자 정의하고 이러한 변경 사항을 커밋하여 고유한 사용자 정의 이미지를 만들었습니다.
또한 버전 관리 및 배포를 위해 이미지를 적절하게 태깅하는 방법, 수동 전송을 위해 이미지를 파일에 저장하는 방법, 변경 사항을 문서화하는 방법을 배웠습니다. 마지막으로, Docker 이미지를 사용하는 모범 사례를 살펴보고 환경을 정리했습니다.
이러한 기술은 개발 및 프로덕션 환경에서 Docker 를 사용하는 데 탄탄한 기반을 제공합니다. 이제 특정 요구 사항에 맞게 Docker 이미지를 자신 있게 생성하고 사용자 정의하여 애플리케이션을 서로 다른 환경에서 더욱 이식 가능하고 일관되게 만들 수 있습니다.