Docker 컨테이너 내부로 파일을 복사하는 방법, 바인드 마운트와 볼륨 마운트를 통해 호스트와 컨테이너 간의 데이터를 공유하는 방법, 그리고 Docker 이미지의 생성 및 관리 방법과 또한, Docker 이미지를 사용하여 Java 애플리케이션을 컨테이너화하는 과정을 포함하여, Dockerfile을 사용하여 이미지를 빌드하고 컨테이너를 실행하는 예제를 포함합니다.
1. Docker에 파일 복사하기
- 파일 복사하기
Bash
docker cp index.html nginxwebserver:/usr/share/nginx/html
docker cp hostmakefile.txt nginxwebserver:/usr/share/nginx/html
- 실행 해보기
Bash
docker exec nginxwebserver sh -c 'ls /usr/share/nginx/html'
docker exec nginxwebserver sh -c 'curl localhost'
docker exec nginxwebserver sh -c 'cat /usr/share/nginx/html/ho*'
- docker exec nginxwebserver sh -c ‘cat /usr/share/nginx/html/ho*’ 실행결과
- docker exec nginxwebserver sh -c ‘curl localhost’ 실행결과
- docker exec nginxwebserver sh -c ‘ls /usr/share/nginx/html’ 실행결과
2. 마운트
2-1. 바인드 마운트 (Bind Mount):
- 바인드 마운트는 호스트의 파일 시스템 경로를 직접 컨테이너 내의 경로에 연결합니다.
- 호스트의 특정 디렉토리를 컨테이너 내의 디렉토리에 바인딩하여 해당 디렉토리를 컨테이너 내부에서 직접 사용할 수 있습니다.
- 호스트와 컨테이너 간에 파일 및 디렉토리를 실시간으로 공유하므로 호스트 시스템의 변경 사항이 즉시 컨테이너에 반영됩니다.
- 일반적으로 개발 및 테스트 환경에서 자주 사용됩니다.
2-2. 볼륨 마운트 (Volume Mount):
- 볼륨 마운트는 도커 엔진이 관리하는 볼륨을 사용하여 호스트와 컨테이너 간의 데이터를 공유합니다.
- 도커 엔진이 관리하는 특정 디렉토리를 사용하여 컨테이너 내부에 마운트되며, 호스트 시스템의 파일 시스템과는 독립적으로 관리됩니다.
- 볼륨은 도커 엔진이 관리하기 때문에 도커 명령어를 통해서만 접근이 가능합니다. 볼륨은 도커 컨테이너의 수명 주기와 관련하여 관리되며, 컨테이너가 삭제되어도 볼륨은 유지됩니다.
- 볼륨은 데이터를 영구적으로 저장하고 관리해야 할 때 사용됩니다. 예를 들어 데이터베이스 파일이나 로그 파일과 같은 데이터를 보관해야 할 때 유용합니다.
2-3. Container 생성 명령어
- docker run –name <생성하는컨테이너_이름> -d -p <포트포워딩> -v <호스트경로>:<컨테이너경로> <이미지명>
2-4. 바인드 마운트 실행하기
Bash
# 리눅스에서
docker run --name mynginxserver1 -d -p 81:80 -v /root/test:/usr/share/nginx/html nginx
# 윈도우에서
docker run --name mynginxserver -d -p 8090:80 -v C:\ITStudy\07_docker\:/usr/share/nginx/html nginx
- 컨테이너에 지정한 폴더에 docker_desktop으로 확인시 mount 된 것을 확인할 수 있다.
2-5. 볼륨마운트 실행하기
- 생성
- docker volume create test_vol
- 리스트 확인
- docker volume ls
- 정보 확인
- docker volume inspect test_vol
- mountpoint가 아래와 같은 경로에 저장
3. 도커 이미지
3-1. 개념
- 이미지란?
- 컨테이너를 실행하기 위해 필요한 빌드된 패키지
- 이미지 구성 방법
- 이미지 생성 후 dockerhub에 업로드 미 ㅊ외부에서 자유롭게 다운로드 및 재사용이 가능하다.
docker image build
→docker image push
- [저장소 이름]/[이미지이름]:[태그 ]
- 저장소 : 이미지가 저장된 장소 의미
- 이미지 이름 : 역할 표현, 필수
- 태그 : 이미지 버전 관리, 생략시 latest로 인식
3-2. 도커 이미지 만들기
docker login
- nginx에 덧붙여서 만들기
docker pull nginx
- 컨테이너 만들기
docker run --name userserver -d -p 80:80 nginx
- index.html 파일 수정 후 확인, 새로운 이미지 구성을 위한 변화 적용
- docker cp <로컬_파일_또는_디렉토리_경로> <컨테이너_이름>:<컨테이너_내부_경로>
docker cp C:\\ITStudy\\07_docker\\bindmount\\. userserver:/usr/share/nginx/html
- commit 명령어로 이미지 구성
- docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker commit userserver userimage
- 태그 걸기(버전)
- docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker tag userimage [user_id]/userimage
- push로 hub에 때리기
- docker push [OPTIONS] NAME[:TAG]
docker push ioshe/minsuimage
3-3. 도커 이미지를 생성할 때 발생할 수 있는 오류
- 컨테이너가 실행 중인 경우: 도커 이미지가 하나 이상의 실행 중인 컨테이너에 의해 사용되고 있을 때, 해당 이미지를 삭제하려고 하면 오류가 발생합니다. 이 경우, 이미지를 삭제하기 전에 해당 컨테이너를 멈추거나 삭제해야 합니다.
- 컨테이너가 이미지에 의존하는 경우: 이미지를 삭제하려고 할 때, 해당 이미지에 의존하는 중지된 컨테이너가 있으면 삭제가 거부될 수 있습니다. 이 컨테이너들을 먼저 삭제하거나
docker image prune
명령어를 사용해 더 이상 사용되지 않는 모든 도커 이미지를 정리해야 합니다. - 컨테이너가 이미지를 사용 중인 경우:
nginx
이미지를 삭제하려고 했을 때 발생한 오류는,nginx
이미지를 사용하는 컨테이너가 여전히 존재하기 때문입니다. 이 이미지를 삭제하려면, 먼저 해당 컨테이너를 중지하고 삭제해야 합니다.
4. 도커 빌드
4-1. 도커파일 커맨드 종류
커맨드 | 의미 |
FROM | 베이스 이미지 지정 |
RUN | shell command를 해당 docker image에 실행시킬 때 사용함 |
CMD | 컨테이너 시작시 실행할 커맨드 설정 |
LABEL | 이미지에 레이블 지정 |
EXPOSE | 컨테이너에서 노출하는 포트 번호 설정 |
ENV | 환경 변수 설정 |
ADD | 이미지에 파일 복사 |
COPY | 이미지에 파일 복사 |
ENTRYPOINT | 컨테이너 시작시 실행할 커맨드 설정 |
VOLUME | 볼륨이 마운트 될 위치 설정 |
USER | 커맨드를 실행할 때 사용자 ID 설정 |
WORKDIR | 커맨드를 실행할 때 작업 디렉터리 설정 |
ARG | 빌드 시에만 사용되는 변수 설정 |
ONBUILD | 이 이미지를 베이스로 빌드할 때 커맨드가 실행되도록 하기 |
STOPSIGNAL | 컨테이너를 중지시킬 때의 시그널 번호 설정 |
HEALTHCHECK | 헬스 체크를 위한 커맨드 설정 |
4-2. 도커 빌드하기
Bash
# Dockerfile
FROM nginx:latest
RUN echo '<h1> test nginx web page </h1>' >> index.html
RUN cp /index.html /usr/share/nginx/html
- 도커를 빌드하면 Dockerfile에 정의된 내용에 따라 도커 이미지가 생성됩니다.
- Dockerfile은 도커 이미지를 만들기 위한 레시피이며, 컨테이너가 실행될 환경, 필요한 의존성 패키지, 실행할 명령 등을 정의합니다.
- docker build -t build_test C:\ITStudy\07_Docker\bindmount
4-3. 자바로 해보기
Dockerfile
#Dockerfile
FROM openjdk:17
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
CMD ["java", "Main"]
Java
//Main.java
public class Main{
public static void main(String [] args){
System.out.println("안녕 ~");
}
}
docker build -t [docker_username]/myjavarun:1.0 .
- 실행결과 Dockerfile의 WORKDIR 인 /usr/src/myapp에 javac로 class가 만들어지고 실행이 된 것을 볼 수 있음.