도커 이미지
★★★★★
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


# 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 nginxroot@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같은 사설 레지스트리를 직접 구축할수도 있다.
- 도커허브 = 퍼블릭한 레지스트리

도커이미지를 레지스트리에 올리려면
- 애초에 docker build를 레지스트리 주소로 만들면 된다.
- 기존의 이미지를 올리고 싶으면, 기존 이미지를 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
- 필요한 패키지 설치 - ubuntu 에서는 update 후에 openjdk-11-jdk unzip wget
- 압축해제후, tomcat 디렉토리 이름 변경후 권한 부여
- 호스트에 미리 만들어놓은 index.jsp 파일도 넣어주고
- 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 조회 후 접속

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
'AWS Cloud School 8기 > Docker' 카테고리의 다른 글
58일차) 2025-03-24(docker-compose) (0) | 2025.03.24 |
---|---|
57일차) 2025-03-21(앱배포-python, nginx) (0) | 2025.03.21 |
56일차) 2025-03-20(앱 배포-java/js, 컨테이너화, dockerignore) (0) | 2025.03.20 |
55일차) 2025-03-19(우분투 용량 추가, was-db, 사설저장소) (0) | 2025.03.19 |
53일차) 2025-03-17(컨테이너 가상화) (0) | 2025.03.17 |