도커 이미지

★★★★★

Dockerfile

도커이미지를 만들기 위한 명세표(주문자의 바람이 담김), IaC의 일종

root@host:~# mkdir /docker
root@host:~# cd /docker

FROM

베이스이미지를 지정, 맨 위에 표시

  • Dockerfile 생성
root@host:/docker# vi Dockerfile
FROM nginx:latest
#베이스 이미지
root@host:/docker# docker build -t mynginx:1 .

# -t(tag) : 이미지의 이름, 옵션 싹다 지정

 

# 이미지의 이름은 다르지만 모든레이어가 동일하기때문에 동일한 이미지를 참조하고 있다.

  • 기존꺼 삭제
root@host:/docker# docker rm -f $(docker ps -qa)
root@host:/docker# docker run -dp 8080:80 --name myweb mynginx:1
root@host:/docker# curl localhost:8080

# 만약에 안뜬다면 ip add로 docker0의 ip를 확인 → ip 없다면 systemctl restart docker


WORKDIR

디렉토리 지정, 재지정전까지 영구적으로 유지, cd 대신 사용(가급적 cd를 안쓰는게 좋음)

  • 컨테이너(myweb) 내부로 진입
root@host:/docker# docker exec -it myweb bash

  • Dockerfile workdir 추가
root@host:/docker# vi Dockerfile
WORKDIR /usr/share/nginx/html
#작업디렉토리 변경(nginx의 web root directory)

  • 현재디렉토리(.)의 Dockerfile를 토대로 mynginx:2라는 이미지 생성
root@host:/docker# docker build -t mynginx:2 .
  • 포트, 컨테이너 이름 안겹치게
root@host:/docker# docker run -dp 8082:80 --name myweb2 mynginx:2

이미지를 생성하면서 a라는 디렉토리에서 a-1작업후에 b디렉토리에서 b-1작업을 해야한다면, cd로 이동을 하는게 아니라 WORKDIR a 한후 a-1작업을 끝내고 다시 WORKDIR b 후에 b-1작업을 하면 된다.


COPY

호스트의 파일이나 폴더를 컨테이너 이미지에 삽입

  • Dockerfile copy 추가
root@host:/docker# vi Dockerfile
COPY index.html index.html
#파일이나 디렉토리를 복사
#파일이면 파일로, 디렉토리면 디렉토리로 하는 것이 좋음

  • COPY <호스트파일> <컨테이너파일>
  • COPY <호스트경로> <컨테이너경로>
root@host:/docker# echo copy_test > index.html
root@host:/docker# docker build -t mynginx:3 .

# WORKDIR에 index.html이 잘 복사된걸 확인 가능

  • Dockerfile copy 변경
root@host:/docker# vi Dockerfile
COPY . .

# 이번에는 경로를 복사

root@host:/docker# docker build -t mynginx:4 .
root@host:/docker# docker run -dp 8084:80 --name myweb4 mynginx:4


ADD

웹상에 존재하는 파일도 가져올 수 있고, tar로 압축된 파일은 압축이 자동해제

COPY와 비슷, 되도록이면 COPY 사용하기

root@host:/docker# tar -cvf test.tar index.html

root@host:/docker# tar -xvf test.tar

  • Dockerfile add 추가
root@host:/docker# vi Dockerfile
ADD test.tar .

root@host:/docker# docker build -t mynginx:5 .
root@host:/docker# docker run -dp 8085:80 --name myweb5 mynginx:5

# 압축이 해제되어 index.html파일이 잘 보이는걸 확인 가능


RUN

컨테이너 이미지 빌드 단계에서 수행되는 명령

  • Dockerfile run 추가
root@host:/docker# vi Dockerfile 
FROM nginx:latest
#베이스 이미지
RUN cd /usr/share/nginx/html
COPY index.html index.html
  • 이미지 생성 후 컨테이너 실행
root@host:/docker# docker build -t mynginx:6 .
root@host:/docker# docker run -dp 8086:80 --name myweb6 mynginx:6
  •  컨테이너 내부로 진입
root@host:/docker# docker exec -it myweb6 bash

# RUN 명령으로 cd /usr/share/nginx/html을 수행했지만, 결론적으로는 그 다음 레이어의 COPY라는 명령을 수행할때는 RUN 레이어의 수행결과가 반영되지 않았다. 왜냐하면 레이어끼리는 서로 독립적이기 때문

 

어떤 명령을 여러개 수행하고 싶다면 &&로 묶어서 길게 써준다.

RUN <명령어1> && <명령어2> && <명령어3> && <명령어4> .....

ex) RUN apt update -y && apt install -y <패키지2> && systemctl restart <패키지>


실습)

FROM, RUN ,WORKDIR, COPY 명령을 활용하여 댕댕이 템플릿을 포함하는 도커이미지를 myhttpd:1 이라는 이미지를 생성해서 테스트 해보세요. 베이스이미지는 httpd:latest로 하고, 이 이미지로 컨테이너를 띄웠을때 211.183.3.100:9090 을 쳤을때 웹페이지가 뜨도록 해보세요.
root@host:/# apt update -y && apt install -y unzip wget
  • 템플릿 다운
root@host:/docker# pwd
/docker
root@host:/docker# mkdir copy
root@host:/docker# cd copy/
root@host:/docker# wget https://www.free-css.com/assets/files/free-css-templates/download/page21/dogs-palace.zip
root@host:/docker/copy# unzip dogs-palace.zip
root@host:/docker/copy# mv dogs-palace tem
  • 도커 파일 수정
root@host:/docker# vi Dockerfile
FROM httpd:latest
#베이스 이미지
WORKDIR /usr/local/apache2/htdocs
COPY tem .
#템플릿 경로를 현재 디렉토리에 복사

  • 이미지 생성 후 컨테이너 실행
root@host:/docker# docker build -t myhttpd:1 .
root@host:/docker# docker run -dp 9090:80 --name tem myhttpd:1
  • 템플릿 확인
root@host:/docker# curl localhost:9090
211.183.3.100:9090


CMD

컨테이너가 실행되는 단계에서 수행할 명령

  • 컨테이너를 run(생성+실행)했을때 컨테이너 내부에서 프로세스가 포어그라운드로 잘 동작하도록 하는 명령
  • 보통은 맨 마지막에 한번 작성

  • httpd컨테이너 : httpd -D FOREGROUND
    → CMD형태로 표현하면 [" "," "]로

root@host:/docker/copy# cd ..
root@host:/docker# mkdir cmd
root@host:/docker# cd cmd
root@host:/docker/cmd# vi Dockerfile
FROM centos:7
CMD ["sleep","infinity"]

root@host:/docker/cmd# docker build -t cent:1 .
root@host:/docker/cmd# docker run -d --name sleep cent:1

# 어거지로 컨테이너 내부의 포어그라운드 프로세스를 만들어줌


ENTRYPOINT

CMD 비슷한 명령, 옵션처럼 추가

root@host:/docker/cmd# vi Dockerfile
FROM centos:7
#CMD ["sleep","infinity"]
ENTRYPOINT ["sleep","infinity"]

  • 기존꺼 삭제
root@host:/docker/cmd# docker rm -f $(docker ps -qa)
root@host:/docker/cmd# docker build -t entry:1 .
root@host:/docker/cmd# docker run -dp 5959:80 --name etest entry:1

# CMD와 크게 다른게 없어 보임

 

# sleep infinity test라는 명령으로는 컨테이너가 포어그라운드가 될 수 없음

root@host:/docker/cmd# vi Dockerfile
FROM centos:7
#CMD ["sleep","infinity"]
ENTRYPOINT ["sleep"]

  • entrypoint의 인자로 120을 줌
root@host:/docker/cmd# docker build -t entry:2 .
root@host:/docker/cmd# docker run -dp 5952:80 --name etest2 entry:2 120

  • Dockerfile의 CMD 무시

CMD는 결국 Dockerfile에서도 지정가능하고 컨테이너를 실행할때도 이미지 오른쪽에 넣어줄 수 있다. 결국 컨테이너를 실행하면서 CMD를 적어주면 Dockerfile에서 작성했었던 CMD는 무시된다.


실습)

ubuntu:latest를 베이스이미지로 하여 컨테이너를 띄웠을때 간단한 웹페이지가 뜨는 myubun:1 이라는 컨테이너이미지를 만들어 보세요.
root@host:/docker# mkdir ubun
root@host:/docker# cd ubun/
root@host:/docker/ubun# vi Dockerfile
# 1. 베이스 이미지 지정
FROM ubuntu:latest

# 2. 패키지 목록 업데이트 및 필요한 패키지 설치
RUN apt-get update && apt-get install -y \
    apache2 \
    && rm -rf /var/lib/apt/lists/*

# 3. 기본 웹페이지 생성
RUN echo '<h1>Welcome to myubun:1</h1>' > /var/www/html/index.html

# 4. 컨테이너 실행 시 Apache 실행
CMD ["apachectl", "-D", "FOREGROUND"]
root@host:/docker/ubun# docker build -t myubun:1 .
root@host:/docker/cmd# docker run -dp 5960:80 --name myubun myubun:1
root@host:/docker/ubun# curl localhost:5960

풀이)

  • 컨테이너 내부에서 직접 동작
root@host:/docker/cmd# docker run -it --name ubun ubuntu:latest bash
  • 설치가 안된다면
    ubuntu에서는 update를 먼저 하자

  • 업뎃, 설치, nginx동작
     도커파일로 작성해야 하는 내용
root@7a6c9030ddd2:/# apt update -y
root@7a6c9030ddd2:/# apt install -y nginx

root@7a6c9030ddd2:/# nginx -g 'daemon off;'

root@host:/docker/cmd# vi Dockerfile

FROM ubuntu:latest
RUN apt update -y && apt install -y nginx 
CMD ["nginx","-g","daemon off;"]
root@host:/docker/cmd# docker build -t myubun:1 .
root@host:/docker/cmd# docker run -dp 5656:80 --name web myubun:1


  • 이미지 전체 삭제
root@host:/docker/cmd# docker image prune -fa

EXPOSE

포트를 노출 (사실상 의미 없음)
docker run을 통해 컨테이너 생성할때 -P의 경우엔 호스트의 포트를 랜덤하게 부여할 수 있음
이때 컨테이너의 포트는 EXPOSE 된 포트가 명시된다. -P 옵션을 쓸때만 유효한 명령어다. -p (publish)할때는 의미없음.

root@host:/docker/cmd# cd ..
root@host:/docker# mkdir expose
root@host:/docker# cd expose/
root@host:/docker/expose# vi Dockerfile
FROM nginx:latest
EXPOSE 80
root@host:/docker/expose# docker build -t expose:1 .
root@host:/docker/expose# docker run -dP --name exptest expose:1


ENV

환경변수 선언

vi Dockerfile

root@host:/docker/expose# docker build -t envtest:1 .
root@host:/docker/expose# docker run -it --name env envtest:1 bash

------------------- Dockerfile 작성법


컨테이너 레지스트리

Registry, 저장소

  • 레지스트리 = 도서관, 레포지토리 = 책장, 태그 = 책(버전)
    → 다양한 레지스트리 존재

클라우드는 기본적으로 AWS ECR, GCP GCR, Azure ACR 같은 프라이빗 및 퍼블릭 레지스트리 서비스를 제공하고,

내가 Harbor나 Nexus같은 사설 레지스트리를 직접 구축할수도 있다.

  • 도커허브 = 퍼블릭한 레지스트리

도커이미지를 레지스트리에 올리려면

  1. 애초에 docker build를 레지스트리 주소로 만들면 된다.
  2. 기존의 이미지를 올리고 싶으면, 기존 이미지를 docker tag라는 명령으로 새로 만들어 주면 된다.
root@host:/docker# vi Dockerfile
FROM nginx:latest
root@host:/docker# docker build -t leeseohoo/myweb:1 .

 

root@host:/docker# docker login -u <본인계정명>

# 먼저 로그인을 하고 push하면 된다.

root@host:/docker# docker push oolralra/myweb:1

# push된 레포를 확인

# 레포의 태그들을 확인 가능


실습)

ubuntu:latest를 베이스이미지로 하여 tomcat을 설치하고 컨테이너의 아이피를 보여주는 index.jsp파일을 배포하는 이미지를 만든 후, 도커 허브에 push 해서 테스트 해보세요. 레포이름은 tom, 태그는 81
curl localhost:8989 를 쳤을때 index.jsp 파일이 보이면 됩니다.
  • 포함되어야 할 내용
root@host:/docker/cmd# docker run -it --name tom ubuntu:latest bash
root@8767617c95a3:/# apt update && apt install -y openjdk-11-jdk wget unzip
root@8767617c95a3:/# wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.zip
  • 도커파일 생성
root@host:/docker/cmd# vi Dockerfile
# 베이스 이미지: Ubuntu 최신 버전
FROM ubuntu:latest

# 필요한 패키지 설치
RUN apt update && apt install -y openjdk-11-jdk wget unzip curl

# Tomcat 10 다운로드 및 압축 해제
RUN wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.zip \
    && unzip apache-tomcat-10.1.39.zip \
    && mv apache-tomcat-10.1.39 /opt/tomcat \
    && rm apache-tomcat-10.1.39.zip

# index.jsp 추가
COPY index.jsp /opt/tomcat/webapps/ROOT/index.jsp

# 실행 권한 부여
RUN chmod +x /opt/tomcat/bin/catalina.sh

# Tomcat 실행
CMD ["/opt/tomcat/bin/catalina.sh", "run"]
root@host:/docker/cmd# vi index.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
    	<head><title>hello world</title></head>
    	<body>
    	<h2>
            	TOMCAT TEST<br><br>
            	time : <%= new java.util.Date()%>
            	<%@ page import="java.net.InetAddress" %><br>
            	<%InetAddress inet= InetAddress.getLocalHost();%>
            	Container ip : <%=inet.getHostAddress()%>
    	</h2>
 
 
    	</body>
</html>
root@host:/docker/cmd# docker build -t tom:81 .
root@host:/docker/cmd# docker run -dp 8989:8080 --name tomcat tom:81
root@host:/docker/cmd# docker login
root@host:/docker/cmd# docker tag tom:81 leeseohoo/tom:81
root@host:/docker/cmd# docker push leeseohoo/tom:81
curl localhost:8989

풀이)

https://eitherwho.tistory.com/49

 

24일차) 2025-02-03 (Proxy, Mint, SSH, Telnet, Key Pair, 3 tier Architecture)

팀실습_풀이)여러분들의 노트북이나 스마트폰처럼 와이파이 어댑터로부터 외부 통신에 필요한 정보(디폴트루트, IP)를 받아옵니다.3명이 짝을 이뤄 내부에 다음과 같은 서버를 만드셔서 서로의

eitherwho.tistory.com

  1. 필요한 패키지 설치 - ubuntu 에서는 update 후에 openjdk-11-jdk unzip wget
  2. 압축해제후, tomcat 디렉토리 이름 변경후 권한 부여
  3. 호스트에 미리 만들어놓은  index.jsp 파일도 넣어주고
  4. tomcat을 foreground로 동작시키기 위한 CMD 구성
  • 들어가서 각 명령이 잘 먹히는지 확인
root@host:/docker/tom# docker run -it --name tomcat ubuntu:latest bash
root@379a9ca335a3:/# apt update -y
root@379a9ca335a3:/# apt install -y openjdk-11-jdk unzip wget
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.zip
root@379a9ca335a3:/# unzip apache-tomcat-10.1.39.zip
root@379a9ca335a3:/# mv apache-tomcat-10.1.39 tomcat
root@379a9ca335a3:/# rm -rf apache-tomcat-10.1.39.zip
root@379a9ca335a3:/# chmod 777 -R tomcat
root@379a9ca335a3:/# ./tomcat/bin/catalina.sh run
  • 창을 하나 더 열어서 컨테이너 IP 조회 후 접속

# tomcat이 잘 동작하는걸 확인

vi Dockerfile
  • 1. 따로 표시
FROM ubuntu:latest
WORKDIR /
RUN apt update -y && apt install -y wget unzip openjdk-11-jdk
RUN wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.zip
RUN unzip apache-tomcat-10.1.39.zip
RUN mv apache-tomcat-10.1.39 tomcat
RUN chmod 777 -R tomcat
ADD index.jsp /tomcat/webapps/ROOT/index.jsp
WORKDIR /tomcat/bin
CMD ["./catalina.sh","run"]
  • 2. 묶어 표시(전부 &&로 묶어서 하나의 레이어로 생성)
FROM ubuntu:latest
WORKDIR /
RUN apt update -y && apt install -y wget unzip openjdk-11-jdk && \
    wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.zip && \
    unzip apache-tomcat-10.1.39.zip && \
    rm apache-tomcat-10.1.39.zip \
    mv apache-tomcat-10.1.39 tomcat && \
    chmod 777 -R tomcat && \
COPY index.jsp /tomcat/webapps/ROOT/index.jsp
WORKDIR /tomcat/bin
CMD ["./catalina.sh","run"]
  • 이미지가 잘 동작하는지 테스트한 후, 도커이미지를 레지스트리 주소로 build, login, push
root@host:/docker/tom# docker build -t leeseohoo/tom:1 .
root@host:/docker/tom# docker login -u leeseohoo
root@host:/docker/tom# docker push leeseohoo/tom:1 .
root@host:/docker/tom# docker rmi oolralra/tom:1

# push후에 로컬에 존재하는 이미지를 삭제하고, 레지스트에 push된 이미지로 run을 해보면 좋다.

root@host:/docker/tom# docker run -dp 5959:8080 --name tomcat oolralra/tom:1