마음에 드는 구글링 결과가 없어서 그냥 내가 찾아보려고 혼자 일일이 작성한 도커 총정리 글...ㅎ
1. 도커(Docker)란?

- 애플리케이션을 컨테이너(container)라는 독립된 환경에서 실행할 수 있게 도와주는 도구 (가상화 플랫폼)
- 컨테이너는 애플리케이션과 그 실행에 필요한 모든 것(코드, 라이브러리, 설정 파일 등)을 포함한 일종의 가상화된 경량 환경, 즉 가상 환경이 구축되어 있는 하나의 박스라고 보면 된다.
- 쉽게 말해 특정한 환경을 구성하기 위해 만들어진 가상의 공간
- 이를 통해 개발 환경과 배포 환경을 동일하게 유지할 수 있으며, 배포가 용이해짐
<도커 설치 방법 (ver.1)>
$ sudo apt-get update
- 우분투 시스템 패키지 업데이트
$ sudo apt-get install -y ca-certificates \
curl \
software-properties-common \
apt-transport-https \
gnupg \
lsb-release
- 필요한 패키지 설치
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- Docker의 공식 GPG 키를 추가하고 apt 저장소를 추가해줌
- 여기서 한 번 sudo apt-get update 시행해야 오류가 안나는 듯 함
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
- Docker 엔진 설치 -> CE(community edition)과 EE(enterprise edition) 중 무료인 CE 버전 설치
sudo docker version
- 위 명령어를 입력했을 때 버전이 제대로 나온다면 잘 설치된 것



<도커 설치 방법 (ver.2)> (더 권장)
이건 드림핵 강의에 나와있는 설치 방법이다.
아래 명령을 순서대로 실행하여 도커 엔진을 설치한다. (환경 : 우분투 22.04)
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg
$ sudo mkdir -m 0755 -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

아래 명령을 입력했을 때 사진과 같이 Hello from Docker ! 가 출력되면 도커 엔진이 정상적으로 설치된 것이다.
$ sudo docker run hello-world

Q. 도커를 사용하는 이유?
CTF나 워게임 문제에 도커 파일이 제공되는 경우가 많은데, 이 경우 제공되는 도커 파일을 빌드하고 컨테이너를 실행하면 문제 환경을 똑같이 재현하여 풀 수 있다.
문제에서 도커파일을 제공하여 도커를 사용할 수 있도록 하는 이유는 무엇일까?
도커가 없다면 vmware 같은 가상머신을 설치해서 일일이 직접 문제 환경을 구축해야 한다. 가상머신은 용량이 매우 크고 무거워서 동시에 여러 개를 실행하기 어려우며, 풀이자가 직접 가상 환경을 구축하면 출제자가 의도한 환경에서 벗어날 수도 있다. 특히 시스템 해킹의 경우 정교한 공격을 위해 똑같은 환경에서 바이너리를 디버깅하고 익스플로잇하는 것이 중요하다.
도커 컨테이너는 가상 환경 구축의 많은 부분을 생략하고 가볍게 실행되어, 매우 간편하게 문제 환경을 재현한다!
또한 문제 환경과 거의 동일한 환경을 제공하여 문제 풀이에 방해가 되는 요소를 줄인다.
2. 도커 이미지(Docker Image) 란?
도커 이미지는 도커 컨테이너의 전 단계로, 컨테이너를 생성하고 실행하기 위한 모든 것을 포함한다.
ex) 컨테이너 생성에 필요한 파일, 환경 변수, 명령어 등과 파일 시스템 등
- 자신만의 이미지를 만들거나 다른 사람이 만든 이미지를 사용할 수도 있음
- 이미지를 생성하려면 Dockerfile을 먼저 작성하고 이미지를 빌드해야 한다.
- 뒤에서 설명하겠지만 도커 파일은 이미지를 빌드하는 데 단계적으로 필요한 명령어가 있는 파일!
- 도커 이미지에는 태그(tag)를 붙일 수 있는데, 이는 하나의 이미지에 여러 개의 별명을 붙여 주는 것과 같으며 주로 이미지의 버전을 지정하기 위해 사용한다.
도커 컨테이너(Docker Container)
- 도커 이미지로부터 만들어진 실행 가능한 인스턴스
=> 즉, "실행 중인 이미지"를 컨테이너라고 한다!
컨테이너는 도커 이미지와 사용자가 컨테이너를 시작할 때 작성하는 옵션에 의해 정의된다.
컨테이너를 실행하는 동안은 분리된 파일 시스템을 이용한다.
도커 레지스트리(Docker Registry)
- 도커 이미지를 저장하는 "저장소"
도커의 공식 레지스트리로 Docker Hub라는 곳이 있으며, 누구나 레지스트리에 도커 이미지를 올리고 존재하는 도커 이미지를 가져올 수도 있다.
Docker Hub Container Image Library | App Containerization
Increase your reach and adoption on Docker Hub With a Docker Verified Publisher subscription, you'll increase trust, boost discoverability, get exclusive data insights, and much more.
hub.docker.com
도커 파일(Dockerfile)
- 특정 애플리케이션을 컨테이너에서 실행하기 위해 필요한 명령어들을 정의한 스크립트
- 이를 통해 해당 애플리케이션이 컨테이너에서 어떻게 빌드되고 실행될지를 설명함
도커 파일은 주로 아래와 같은 작업을 정의한다.
- 어떤 운영 체제를 사용하는가
- 어떤 소프트웨어 패키지를 설치하는가
- 애플리케이션의 파일을 어디에 위치시키는가
- 어떤 포트를 열어야 하는가
- 애플리케이션을 어떻게 실행하는가
3-1. Docker 명령어와 예시
자주 사용하는 도커 명령어들을 하단에 나열하였다.
(이들의 실제 활용 예시는 후반부에서 구체적으로 설명)
<Dockerfile로 이미지 생성하기 : docker build>
docker build [옵션] <경로>
docker build -t <이미지명:태그> <경로>
-t 옵션으로 이미지의 이름과 태그를 지정한 것이며, 태그를 지정하지 않을 경우 latest로 지정된다.
## 예시 ##
docker build . # 현재 디렉토리에 있는 Dockerfile로 이미지 생성
docker build -t my-image . # 현재 디렉토리에 있는 Dockerfile로 my-image:latest 이미지 생성
<도커 이미지 목록 출력 : docker images>
docker images
아래는 미리 준비된 Dockerfile을 이용해서 docker build 명령어로 이미지를 빌드한 후, docker images 명령어로 출력하는 모습이다.
user@user-VirtualBox:~/Desktop/ex-docker$ docker build .
[+] Building 27.1s (17/17) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> ...생략...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:08a83756c396b9ca5d83735153cf0176056fb23c3eb3c 0.0s
user@user-VirtualBox:~/Desktop/ex-docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 9d201c4de2b6 2 minutes ago 122MB
user@user-VirtualBox:~/Desktop/ex-docker$ docker build -t my-image:1 .
[+] Building 0.8s (17/17) FINISHED
=> ...생략...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9d201c4de2b62519383058265e31669b167c422502643 0.0s
=> => naming to docker.io/library/my-image:1 0.0s
user@user-VirtualBox:~/Desktop/ex-docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-image 1 9d201c4de2b6 4 minutes ago 122MB
<도커 이미지로 컨테이너 생성 및 실행하기 : docker run>
docker run [옵션] <이미지명|ID> [명령어]
docker run -p <호스트 PORT>:<컨테이너 PORT> <이미지명|ID>
-p 옵션은 도커 컨테이너의 포트와 호스트의 포트를 매핑한다.
컨테이너에서 리슨하고 있는 포트를 호스트의 특정 포트로 접속할 수 있도록 한다.
docker run -it <이미지명|ID> <명령어>
-it 옵션으로 컨테이너에서 bash 셸을 사용할 수 있다.
-i (--interactive)는 표준 입력을 활성화하여 사용자가 명령어를 입력할 수 있도록 하고, -t(--tty)는 가상 터미널(tty)을 사용할 수 있도록 한다.
## 예시 ##
# docker run -it my-image:1 /bin/bash : my-image:1 이미지로 컨테이너 생성하고 실행하여 bash 셸 열기
user@user-VirtualBox:~/Desktop/ex-docker$ docker run -it my-image:1 /bin/bash
chall@852bb2be037c:~$
<실행 중인 컨테이너 목록 출력 : docker ps>
docker ps -a
-a 옵션은 종료된 컨테이너까지 모두 출력한다.
컨테이너를 실행한 상태로 다른 터미널 창을 열어 docker ps를 입력하면 아래와 같이 실행 중인 컨테이너 목록이 출력됨

컨테이너 안에서 exit 명령어를 실행하여 컨테이너를 종료한 후 docker ps를 입력하면 컨테이너가 출력되지 않고, docker ps -a 를 입력하면 종료된 컨테이너까지 출력되는 모습을 볼 수 있다.

앞서 봤던 docker run 명령 대신, 컨테이너 생성과 실행을 따로따로 명령할 수도 있다!
(run은 생성과 실행 같이함)
<도커 이미지로 컨테이너 생성 : docker create>
docker create [옵션] <이미지명|ID> [명령어]
<중단된 컨테이너 시작 : docker start>
docker start [옵션] <컨테이너명|ID>
## 예시 ##
user@user-VirtualBox:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-image 1 9d201c4de2b6 2 hours ago 122MB
user@user-VirtualBox:~$ docker create my-image:1
eb01688504dc201d9f3a03bf3a27d84cdeafca4b2110766d52fc7551a7d9d05a
user@user-VirtualBox:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb01688504dc my-image:1 "/bin/sh -c 'socat -…" 4 seconds ago Created priceless_meninsky
user@user-VirtualBox:~$ docker start eb01688504dc
eb01688504dc
user@user-VirtualBox:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb01688504dc my-image:1 "/bin/sh -c 'socat -…" 19 seconds ago Up 4 seconds 2222/tcp priceless_meninsky
<실행 중인 컨테이너에 접속하여 명령 수행 : docker exec>
docker exec [옵션] <컨테이너명|ID> [명령어]
docker run과 유사하게 -it 옵션으로 bash 셸 실행 가능!
## 예시 ##
user@user-VirtualBox:~$ docker exec -it eb01688504dc /bin/bash
chall@eb01688504dc:~$
<실행 중인 컨테이너 중단 : docker stop>
docker stop [옵션] <컨테이너명|ID>
<레지스트리에 존재하는 도커 이미지 다운로드 : docker pull>
docker pull [옵션] <이미지명>
## 예시 ##
user@user-VirtualBox:~$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
0c5227665c11: Pull complete
Digest: sha256:8aa9c2798215f99544d1ce7439ea9c3a6dfd82de607da1cec3a8a2fae005931b
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
<도커 컨테이너 삭제 : docker rm>
docker rm [옵션] <컨테이너명|ID>
<도커 이미지 삭제 : docker rmi>
docker rmi [옵션] <이미지명|ID>
<도커 이미지/컨테이너 정보 출력 : docker inspect>
docker inspect [옵션] <이미지 혹은 컨테이너명|ID>
user@user-VirtualBox:~$ docker inspect ubuntu:18.04
[
{
"Id": "sha256:3941d3b032a8168d53508410a67baad120a563df67a7959565a30a1cb2114731",
"RepoTags": [
"ubuntu:18.04"
],
"RepoDigests": [
"ubuntu@sha256:8aa9c2798215f99544d1ce7439ea9c3a6dfd82de607da1cec3a8a2fae005931b"
],
"Parent": "",
"Comment": "",
"Created": "2023-03-08T03:22:44.73196058Z",
"Container": "ee3fcc8c88d3f3129f1236850de28a7eba0da7c548a7b23a6495905ebcf255ea",
"ContainerConfig": {
"Hostname": "ee3fcc8c88d3",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/bash\"]"
],
"Image": "sha256:b64649bc9d1a48300ec5a929146aa3c5ca80046f74c33aa5de65a7046f5177a6",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "18.04"
}
},
"DockerVersion": "20.10.12",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "sha256:b64649bc9d1a48300ec5a929146aa3c5ca80046f74c33aa5de65a7046f5177a6",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "18.04"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 63146040,
"VirtualSize": 63146040,
"GraphDriver": {
"Data": {
"MergedDir": "/var/lib/docker/overlay2/0fe24c66cfaad338ccd55946d7734702a3575513fb2e697b409d3194c95c7e62/merged",
"UpperDir": "/var/lib/docker/overlay2/0fe24c66cfaad338ccd55946d7734702a3575513fb2e697b409d3194c95c7e62/diff",
"WorkDir": "/var/lib/docker/overlay2/0fe24c66cfaad338ccd55946d7734702a3575513fb2e697b409d3194c95c7e62/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:b7e0fa7bfe7f9796f1268cca2e65a8bfb1e010277652cee9a9c9d077a83db3c4"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
3-2. Dockerfile 명령어
아래 도커파일은 드림핵 강의에서 가져온 내용이다.
<전체 코드>
FROM ubuntu:22.04
ENV user chall
ENV chall_port 2222
RUN apt-get update
RUN apt-get install -y socat
RUN adduser $user
ADD ./deploy/flag /home/$user/flag
ADD ./deploy/$user /home/$user/$user
RUN chown -R root:$user /home/$user
RUN chown root:$user /home/$user/flag
RUN chown root:$user /home/$user/$user
RUN chmod 755 /home/$user/$user
RUN chmod 440 /home/$user/flag
WORKDIR /home/$user
USER $user
EXPOSE $chall_port
CMD socat -T 30 TCP-LISTEN:$chall_port,reuseaddr,fork EXEC:/home/$user/$user
도커 이미지를 빌드하기 위해서는 Dockerfile이 필요하다.
도커파일은 앞서 언급했듯이 이미지를 생성하는데 필요한 명령어를 포함하여 모든 설정이 정의된 파일이다.
(운영체제와 버전, 환경 변수, 파일 시스템, 사용자 등을 정의)
기본적으로 도커 파일의 파일명은 확장자 없이 "Dockerfile" 이며, 기본 형식은 아래와 같다.
docker build 명령어를 수행하면 자동으로 이름이 Dockerfile 인 파일을 찾아 이미지를 빌드한다!
-f 옵션으로 원하는 이름의 도커 파일을 사용할 수도 있음
# 주석
명령어 인자
# ---예시---
FROM ubuntu:18.04
dockerfile은 FROM 명령어로 시작해야 하며, 이후에는 순서대로 명령어를 실행한다.
FROM
- 생성할 이미지의 기반이 되는 base 이미지를 지정
- 보통 사용할 운영체제의 공식 이미지를 Dockerhub에서 가져온다.
FROM 이미지:태그
➡️ FROM ubuntu:18.04 # 예시
ENV
- dockerfile 내에서 사용하는 환경 변수를 지정
- 파일 내에서 변수는 $변수명 or ${변수명} 형태로 표현
ENV 변수명 값 or ENV 변수명=값
➡️ ENV PYTHON_VERSION 3.11.2 → .../python/$PYTHON_VERSION/... # 예시
RUN
- 이미지를 빌드할 때 실행할 명령어 작성
- 필요한 패키지를 설치하거나, 파일 권한 설정 등의 작업 수행
RUN 명령어 or RUN ["명령어", "인자1", "인자2"]
➡️ RUN apt-get update
➡️ RUN ["/bin/bash", "-c", "echo hello"]
COPY
- src 파일이나 디렉토리를 이미지 파일 시스템의 dest로 복사
COPY <src> <dest>
➡️ COPY . /app
ADD
- src 파일이나 디렉토리, URL을 이미지 파일 시스템의 dest로 복사
ADD <src> <dest>
➡️ ADD . /app
WORKDIR
- Dockerfile 내의 명령을 수행할 작업 디렉토리를 지정 (cd 명령어와 유사)
WORKDIR 디렉토리
➡️ WORKDIR /home/user
USER
- 명령을 수행할 사용자 혹은 그룹을 지정
USER 사용자명|UID or USER 사용자명|UID[:그룹명|GID]
➡️ USER $username
EXPOSE
- 컨테이너가 실행 중일 때 들어오는 네트워크 트래픽을 리슨할 포트와 프로토콜을 지정
- 사용할 수 있는 프로토콜은 TCP와 UDP 이며, 기본적으로 TCP가 지정됨
EXPOSE 포트 or EXPOSE 포트/프로토콜
➡️ EXPOSE 80/tcp
ENTRYPOINT
- 컨테이너가 실행될 때 수행할 명령어 지정
ENTRYPOINT 명령어 인자1 인자2 or ENTRYPOINT ["명령어", "인자1", "인자2"]
➡️ ENTRYPOINT ["echo", "hello"]
CMD
- 컨테이너가 실행될 때 수행할 명령어를 지정하거나, ENTRYPOINT 명령어에 인자를 전달
CMD 명령어 인자1 인자2 or CMD ["명령어", "인자1", "인자2"] or CMD ["인자1", "인자2"]
➡️ CMD ["echo", "hello"]
- dockerfile 내에 CMD 명령이 여러 개 존재하면 마지막 CMD를 사용
- docker run의 인자를 작성하면 cmd 명령어는 무시됨
- ENTRYPOINT가 있는 경우, docker run의 인자가 ENTRYPOINT의 인자로 들어감
ENTRYPOINT ["python"]
CMD ["app.py"]
도커파일이 위와 같을 때,
docker run [이미지] 로 컨테이너 실행하면 python app.py를 실행
docker run 이미지 test.py로 컨테이너를 실행하면 python test.py를 실행
아래 또 다른 도커파일 예시 코드를 보면서 기본적인 명령어들을 다시 이해해보자~
<전체 코드>
#Dockerfile
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y
RUN apt-get install apache2 -y
RUN apt-get install php -y
RUN apt-get install php7.2-xml -y
RUN apt-get install php-xmlrpc -y
RUN apt-get install libapache2-mod-php -y
COPY ./transcript /etc
COPY ./php.ini /etc/php/7.2/php.ini
RUN rm /var/www/html/index.html
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
WORKDIR /var/www/html/
EXPOSE 3000
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
FROM ubuntu:18.04
- FROM: 도커 이미지의 기반이 될 운영체제를 정의
- 이 코드는 ubuntu 18.04를 기반으로 하고 있으며, 이후 모든 명령은 해당 운영체제를 기반으로 실행된다!
ENV DEBIAN_FRONTEND=noninteractive
- ENV: 컨테이너 안에서 환경 변수를 설정
- 여기서 DEBIAN_FRONTEND=noninteractive 는 패키지를 설치할 때 대화형 프롬프트를 비활성화하도록 설정하는 환경 변수로서, 자동화된 설치 과정을 용이하게 한다.
RUN apt-get update -y
RUN apt-get install apache2 -y
RUN apt-get install php -y
RUN apt-get install php7.2-xml -y
RUN apt-get install php-xmlrpc -y
RUN apt-get install libapache2-mod-php -y
- RUN: 컨테이너 내부에서 명령어를 실행
- 여기서는 ubuntu의 패키지 관리자 apt-get을 사용해서 apache 웹 서버와 PHP 및 관련 패키지들을 설치하고 있다.
COPY ./transcript /etc
COPY ./php.ini /etc/php/7.2/php.ini
- COPY: 호스트 시스템에서 파일이나 디렉토리를 컨테이너 이미지 안의 지정된 위치로 복사
- 여기서는 ./transcript 파일을 컨테이너의 /etc 디렉토리로 복사하고,
- php.ini 파일을 /etc/php/7.2/php.ini 위치에 복사하여 PHP 설정 파일을 수정한 내용을 반영한다.
- 경로 작성할 때 주의사항: Dockerfile은 ~(틸다) 를 인식하지 못하므로, ~/Desktop 과 같은 경로 대신 절대 경로 사용!
RUN rm /var/www/html/index.html
- 기존의 기본 웹 페이지 파일인 index.html을 삭제한다.
- 이는 자신의 웹사이트를 새롭게 배포하기 위한 사전 작업!
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
- apache 웹 서버가 www-data라는 사용자와 그룹으로 실행되도록 환경 변수를 설정
WORKDIR /var/www/html/
- WORKDIR: 이후 명령어들이 실행될 작업 디렉토리를 설정
- 여기서는 /var/www/html/ 디렉토리로 설정하여, 해당 위치에서 이후 작업들이 이루어지게 한다.
- 참고로 /var/www/html 디렉토리는 apache 서버에서 실행되는 파일들의 저장 위치임
EXPOSE 3000
- EXPOSE: 컨테이너가 외부에 노출할 포트를 지정
- 여기서는 3000 포트를 열어서 외부에서 해당 포트로 접근할 수 있게 한다.
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
- CMD: 컨테이너가 실행될 때 기본적으로 수행할 명령어를 지정
- 여기서는 apache 서버를 실행하여 백그라운드에서 실행되는 대신 포그라운드에서 유지하도록 한다.
- 이렇게하면 컨테이너가 종료되지 않도록 할 수 있음!
4. Docker Hub 란?

- Docker Hub는 도커의 공식 레지스트리로, 도커 이미지를 저장하는 저장소
- Docker Hub 사용자는 이미지를 자유롭게 업로드하거나 다운 받아 사용함
- 다른 사용자가 업로드 한 이미지 뿐만 아니라 도커에서 제공하는 공식 이미지를 사용할 수 있다는 것도 편리
- 공식 이미지는 기본 OS(Linux, CentOS 등) 이미지나, 특정 프로그래밍 언어의 개발 환경 등을 제공
- 비공개 이미지를 업로드하여 개인적으로 사용하거나 팀끼리 공유할 수 있다.
<Docker Hub에 이미지 업로드하는 방법>
도커 허브를 이용하면 도커 파일이 아닌 이미지 "그 자체"를 보관하고 공유할 수 있다.
자신만의 문제 풀이 환경을 구축해두고 사용하고 싶거나, 워게임을 직접 제작하여 다른 사람들과 공유하고 싶은 경우 등에 유용함!
1. docker login : Docker Hub에 로그인
user@user-VirtualBox:~$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: dreamhackofficial
Password:
WARNING! Your password will be stored unencrypted in /home/user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
user@user-VirtualBox:~$
2. docker build -t [사용자]/[레포지토리명]:[TAG] [Dockerfile 경로] : Dockerfile을 이용하여 이미지 빌드하기
이미지 이름은 [사용자]/[레파지토리명]:[TAG] 형식으로 작성한다.
다음은 dreamhackofficial/exercise-docker:1 을 빌드해본 모습
user@user-VirtualBox:~/Desktop/ex-docker$ docker build -t dreamhackofficial/exercise-docker:1 .
[+] Building 1.8s (18/18) FINISHED
=> ...생략...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9d201c4de2b62519383058265e31669b167c422502643 0.0s
=> => naming to docker.io/dreamhackofficial/exercise-docker:1 0.0s
user@user-VirtualBox:~/Desktop/ex-docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dreamhackofficial/exercise-docker 1 9d201c4de2b6 6 hours ago 122MB
3. docker push [사용자]/[레파지토리명]:[TAG] : 레파지토리에 이미지 업로드
user@user-VirtualBox:~/Desktop/ex-docker$ docker push dreamhackofficial/exercise-docker:1
The push refers to repository [docker.io/dreamhackofficial/exercise-docker]
5f70bf18a086: Pushed
4958ae9bc6ae: Pushed
4b9b1ff53c81: Pushed
5d89cab1df92: Pushed
557171cb0464: Pushed
e04c36b2101d: Pushed
c8fe798e77a1: Pushed
714c2f225f87: Pushed
60ac9e1e9e64: Pushed
3cc715e175c0: Pushed
0482f429f461: Pushed
b93c1bd012ab: Mounted from library/ubuntu
1: digest: sha256:b0288419aa476a56c62d380f41c384f345405b41f7cffffa41aa9c1860fe4617 size: 2818
user@user-VirtualBox:~/Desktop/ex-docker$
아래는 위 과정을 거쳐 Docker Hub의 레포지토리에 이미지가 업로드된 모습이다.
우측의 명령어를 복사하여 누구나 이미지를 다운받을 수 있다.


<Docker Hub에서 이미지 다운로드하는 방법>
도커 허브에서 이미지는 레포지토리에 보관된다.
dreamhackofficial/exercise-docker 레포지토리에서 앞서 업로드했던 이미지를 다운받을 수 있다.
docker pull : Docker Hub에서 이미지 다운로드
- 원하는 레포지토리와 태그를 클릭하여 제공되는 명령어이다.
아래는 dreamhackofficial/exercise-docker 레포지토리의 tag 1 이미지를 성공적으로 다운로드한 모습이며, 해당 이미지로 컨테이너를 생성하고 실행하여 사용할 수 있다!
user@user-VirtualBox:~/Desktop/ex-docker$ docker pull dreamhackofficial/exercise-docker:1
1: Pulling from dreamhackofficial/exercise-docker
2ab09b027e7f: Already exists
dae082a9e205: Pull complete
ab969aeba5d6: Pull complete
cff12ac5c589: Pull complete
3f1e6d67fba6: Pull complete
818905cc8cec: Pull complete
09532c870255: Pull complete
3eda49607555: Pull complete
a88f78b4c1db: Pull complete
4ccef51b986d: Pull complete
5cf58cbc005e: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:b0288419aa476a56c62d380f41c384f345405b41f7cffffa41aa9c1860fe4617
Status: Downloaded newer image for dreamhackofficial/exercise-docker:1
docker.io/dreamhackofficial/exercise-docker:1
5. 도커 컴포즈(Docker-compose) 란?
- 단일 서버에서 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너의 묶음으로 관리할 수 있는 작업 환경을 제공하는 관리 도구
- 도커 컴포즈를 사용하지 않을 경우, 테스트 시 각 컨테이너를 하나씩 생성해야 함 (서버 컨테이너 하나.. db 컨테이너 하나... etc)
- 즉 매번 RUN 으로 옵션을 설정하여 컨테이너를 생성하기 보단, 여러 개의 컨테이너를 하나의 서비스로 정리해 컨테이너 묶음으로 관리하여 편의성을 도모할 수 있음!
- 따라서 단일 컨테이너를 실행 및 관리할 경우 dockerfile만 있으면 돼서 해당 파일이 꼭 필요하지는 않음
- 그러나 여러 컨테이너를 함께 사용하거나, 더 복잡한 애플리케이션을 구성하는 경우 도커 컴포즈 파일이 매우 유용
- 특히 개발 환경에서 로컬 파일을 컨테이너와 동기화하거나, 여러 서비스를 함께 실행해야 할 때 유용하다.
- dockerfile vs docker-compose 차이?
- Dockerfile : 하나의 컨테이너 이미지 빌드 과정을 정의
- docker-compose.yml : 여러 컨테이너의 조합을 정의하고, 이들 간의 연결을 설정
<docker-compose 설치 방법>
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- docker-compose 명령어는 docker 설치 후에 별도로 설치해줘야 하므로 위와 같이 설치
$ sudo chmod +x /usr/local/bin/docker-compose
- 설치가 끝났다면 docker-compose에 권한 부여
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
- 심볼릭 링크 설정
docker-compose --version
- 위 명령어를 입력했을 때 버전이 제대로 나온다면 잘 설치된 것

6. docker-compose.yml 예시 분석
<전체 코드>
#docker-compose.yml
version: "3"
services:
main:
build: .
container_name: pepero_theif
volumes:
- "./src:/var/www/html"
ports:
- 3000:80
restart: always
version: "3"
- version : 이 파일이 사용하는 docker compose의 파일 포맷 버전을 지정
services:
- services: 애플리케이션을 구성하는 하나 이상의 컨테이너를 정의하는 섹션
- 해당 섹션 아래에서 여러 개의 서비스를 정의할 수 있으며, 각각의 서비스는 개별 컨테이너로 실행됨
main:
- main 이라는 이름의 서비스를 정의하는 섹션
- 각 서비스는 개별 컨테이너에 매핑되며, main이라는 이름을 가진 컨테이너가 생성됨
build: .
- build: 도커 이미지를 빌드할 때 사용할 컨텍스트를 지정 (도커 파일 위치)
- 현재 디렉토리에서 Dockerfile을 찾고, 이를 기반으로 이미지를 빌드한다.
container_name: pepero_theif
- container_name: 생성되는 컨테이너의 이름을 지정
- 여기서 컨테이너의 이름은 peperop_thief 로 설정됨!
volumes:
- "./src:/var/www/html"
- volumes: 호스트 시스템의 디렉토리와 컨테이너 내부의 디렉토리를 연결 (호스트 : 컨테이너)
- 여기서는 호스트의 ./src 디렉토리를 컨테이너의 /var/www/html 디렉토리에 연결
- 이를 통해 개발 중인 파일을 호스트 시스템에서 수정하면, 컨테이너 내에서도 즉시 반영됨
ports:
- 3000:80
- ports: 호스트와 컨테이너 간의 포트 매칭을 정의
- 여기서는 호스트의 3000번 포트를 커네이너의 80번 포트와 연결
- 이를 통해 호스트의 localhost:3000으로 접속하면 컨테이너의 웹 서버에 접근할 수 있음
restart: always
- restart: 컨테이너가 중단될 경우 재시작 정책을 정의
- always 로 설정되면, 컨테이너가 중지되더라도 항상 다시 시작되도록 함
- 이는 서버가 재부팅되거나 컨테이너가 예기치 않게 종료되었을 때 유용!
7. 우분투에서 도커파일 생성 및 배포하는 방법
다들 도커 파일 작성에 대한 내용만 있고 정작 이를 "어떻게" 작성하고 이미지는 "어떻게" 빌드하는지 등등
super 왕초보들을 위한 내용은 없어서... 내가 기록해보려고 한다.
설마 이것도 모를까? 싶은 것들도 적음 (내가 몰라서 ㅎ)
1. dockerfile 작성
예를 들어 바탕화면에 tiramisu_cake 라는 이름의 폴더 안에 내가 배포하고 싶은 웹페이지 파일들이 있다고 가정하자.
그렇다면 이 폴더 안에 동일 경로에 Dockerfile을 생성해야 한다.
따라서 해당 폴더를 열어서 해당 위치에서 터미널을 열고 다음 명령어를 입력한 뒤 도커파일 코드를 넣고 Save
gedit Dockerfile

참고로 도커파일은 3번 주제에서 있었던 예시 양식 코드를 기반으로 변형하면 되는데,
초보자의 경우 지피티에게 물어보면 잘 변형해준다...ㅎㅎ

2. Docker 이미지 빌드
- 단일 dockerfile 사용하는 경우 -> 웹 서버만을 운영하는 경우, dockerfile만으로도 충분하기 때문에 sudo docker build와 sudo docker run 명령어를 사용하는 것이 적합함
- 여러 개의 컨테이너(웹 서버, db) 를 사용해야 하는 경우 -> docker-compose.yml 파일을 작성하고 docker-compose up -d 명령어를 사용하는 것이 더 효율적임
나의 경우는 db를 사용하지 않기 때문에 단일 dockerfile 이므로, 다음과 같이 이미지를 빌드했다.
sudo docker build -t tiramisu_cake .
- -t : 이미지의 이름을 지정하는 옵션
- ' . ' 은 현재 디렉토리를 의미

여기 이미지 빌드하는 과정에서 꽤나 애를 많이...먹었는데
당연한 얘기지만 경로를 꼼꼼하게 잘 체크해야 한다.
현재 바탕화면 Desktop 안에 있는 tiramisu_cake 라는 폴더 전체를 올리고 싶은 것이고, dockerfile도 해당 폴더 내부에 있기 때문에 도커 이미지 빌드 작업도 "해당 폴더 경로 내"에서 진행해야함
또한 도커파일 내에 COPY ./tiramisu_cake /var/www/html/ 이렇게 경로A에서 경로B로 복사하는 이런 코드들의 경로까지 꼼꼼하게 체크 해줘야 한다.
나는 해당 코드가 문제였어서 COPY . /var/www/html/ 로 변경 (현재 디렉토리인 '.' ) 했더니 겨우 성공했다...
- docker-compose를 이용하는 경우 다음 명령어를 이용하면 됨 (다음의 컨테이너 실행부분 명령어 안써도 됨)
sudo docker-compose up -d

나는 이런 warning 사인이 떠서 sudo docker-compose up --build -d 해줬더니 정상적으로 실행됐다.
3. Docker 컨테이너 실행
이미지 빌드가 완료되면, 해당 이미지를 기반으로 컨테이너를 실행할 수 있다.
sudo docker run -d -p 916:916 tiramisu_cake
- -d : 컨테이너를 백그라운드에서 실행하는 옵션
- -p 916:916 : 로컬 머신의 916번 포트를 컨테이너의 80번 포트에 매핑한다는 의미
- 여기서 916숫자는 포트번호를 의미하는 것으로서, 자신이 원하는 숫자 아무거나 넣으면 된다! 그러나 이는 도커파일에도 똑같이 적혀져 있어야 함 (EXPOSE ~~ 부분)
**참고**
- 도커 컨테이너 현황 확인
sudo docker ps -a
- 도커 컨테이너 멈추기
sudo docker stop {id}
- 도커 컨테이너 지우기
sudo docker rm {id}
- (도커 컨테이너를 모두 멈추고 지운 다음에) 도커 이미지 지우기
sudo docker rmi [이미지이름]
- 도커 컨테이너 다시 시작
sudo docker start

4. 웹사이트 확인
컨테이너가 정상적으로 실행되었다면, 이제 웹 브라우저를 열고 localhost:[포트번호] 이렇게 입력한 뒤에 웹사이트가 나오면, 정상적으로 작동하는 것을 볼 수 있다!

'Linux' 카테고리의 다른 글
[Ubuntu] gcc 설치 오류 해결 방법 : sudo apt-get install gcc (0) | 2024.09.01 |
---|---|
[Ubuntu] 용량 부족 시 디스크 용량 확인하는 방법 (disk space) (0) | 2024.08.21 |
[Ubuntu] 우분투 Desktop 이전 버전 설치하는 방법 (0) | 2024.08.09 |
[Ubuntu] Access denied 되었을 때 파일 권한 설정 하는 법 (0) | 2024.08.08 |
[Ubuntu] VMware 드래그 앤 드롭 (복사 붙여넣기) 설정하기 (0) | 2024.08.08 |
마음에 드는 구글링 결과가 없어서 그냥 내가 찾아보려고 혼자 일일이 작성한 도커 총정리 글...ㅎ
1. 도커(Docker)란?

- 애플리케이션을 컨테이너(container)라는 독립된 환경에서 실행할 수 있게 도와주는 도구 (가상화 플랫폼)
- 컨테이너는 애플리케이션과 그 실행에 필요한 모든 것(코드, 라이브러리, 설정 파일 등)을 포함한 일종의 가상화된 경량 환경, 즉 가상 환경이 구축되어 있는 하나의 박스라고 보면 된다.
- 쉽게 말해 특정한 환경을 구성하기 위해 만들어진 가상의 공간
- 이를 통해 개발 환경과 배포 환경을 동일하게 유지할 수 있으며, 배포가 용이해짐
<도커 설치 방법 (ver.1)>
$ sudo apt-get update
- 우분투 시스템 패키지 업데이트
$ sudo apt-get install -y ca-certificates \
curl \
software-properties-common \
apt-transport-https \
gnupg \
lsb-release
- 필요한 패키지 설치
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- Docker의 공식 GPG 키를 추가하고 apt 저장소를 추가해줌
- 여기서 한 번 sudo apt-get update 시행해야 오류가 안나는 듯 함
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
- Docker 엔진 설치 -> CE(community edition)과 EE(enterprise edition) 중 무료인 CE 버전 설치
sudo docker version
- 위 명령어를 입력했을 때 버전이 제대로 나온다면 잘 설치된 것



<도커 설치 방법 (ver.2)> (더 권장)
이건 드림핵 강의에 나와있는 설치 방법이다.
아래 명령을 순서대로 실행하여 도커 엔진을 설치한다. (환경 : 우분투 22.04)
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg
$ sudo mkdir -m 0755 -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

아래 명령을 입력했을 때 사진과 같이 Hello from Docker ! 가 출력되면 도커 엔진이 정상적으로 설치된 것이다.
$ sudo docker run hello-world

Q. 도커를 사용하는 이유?
CTF나 워게임 문제에 도커 파일이 제공되는 경우가 많은데, 이 경우 제공되는 도커 파일을 빌드하고 컨테이너를 실행하면 문제 환경을 똑같이 재현하여 풀 수 있다.
문제에서 도커파일을 제공하여 도커를 사용할 수 있도록 하는 이유는 무엇일까?
도커가 없다면 vmware 같은 가상머신을 설치해서 일일이 직접 문제 환경을 구축해야 한다. 가상머신은 용량이 매우 크고 무거워서 동시에 여러 개를 실행하기 어려우며, 풀이자가 직접 가상 환경을 구축하면 출제자가 의도한 환경에서 벗어날 수도 있다. 특히 시스템 해킹의 경우 정교한 공격을 위해 똑같은 환경에서 바이너리를 디버깅하고 익스플로잇하는 것이 중요하다.
도커 컨테이너는 가상 환경 구축의 많은 부분을 생략하고 가볍게 실행되어, 매우 간편하게 문제 환경을 재현한다!
또한 문제 환경과 거의 동일한 환경을 제공하여 문제 풀이에 방해가 되는 요소를 줄인다.
2. 도커 이미지(Docker Image) 란?
도커 이미지는 도커 컨테이너의 전 단계로, 컨테이너를 생성하고 실행하기 위한 모든 것을 포함한다.
ex) 컨테이너 생성에 필요한 파일, 환경 변수, 명령어 등과 파일 시스템 등
- 자신만의 이미지를 만들거나 다른 사람이 만든 이미지를 사용할 수도 있음
- 이미지를 생성하려면 Dockerfile을 먼저 작성하고 이미지를 빌드해야 한다.
- 뒤에서 설명하겠지만 도커 파일은 이미지를 빌드하는 데 단계적으로 필요한 명령어가 있는 파일!
- 도커 이미지에는 태그(tag)를 붙일 수 있는데, 이는 하나의 이미지에 여러 개의 별명을 붙여 주는 것과 같으며 주로 이미지의 버전을 지정하기 위해 사용한다.
도커 컨테이너(Docker Container)
- 도커 이미지로부터 만들어진 실행 가능한 인스턴스
=> 즉, "실행 중인 이미지"를 컨테이너라고 한다!
컨테이너는 도커 이미지와 사용자가 컨테이너를 시작할 때 작성하는 옵션에 의해 정의된다.
컨테이너를 실행하는 동안은 분리된 파일 시스템을 이용한다.
도커 레지스트리(Docker Registry)
- 도커 이미지를 저장하는 "저장소"
도커의 공식 레지스트리로 Docker Hub라는 곳이 있으며, 누구나 레지스트리에 도커 이미지를 올리고 존재하는 도커 이미지를 가져올 수도 있다.
Docker Hub Container Image Library | App Containerization
Increase your reach and adoption on Docker Hub With a Docker Verified Publisher subscription, you'll increase trust, boost discoverability, get exclusive data insights, and much more.
hub.docker.com
도커 파일(Dockerfile)
- 특정 애플리케이션을 컨테이너에서 실행하기 위해 필요한 명령어들을 정의한 스크립트
- 이를 통해 해당 애플리케이션이 컨테이너에서 어떻게 빌드되고 실행될지를 설명함
도커 파일은 주로 아래와 같은 작업을 정의한다.
- 어떤 운영 체제를 사용하는가
- 어떤 소프트웨어 패키지를 설치하는가
- 애플리케이션의 파일을 어디에 위치시키는가
- 어떤 포트를 열어야 하는가
- 애플리케이션을 어떻게 실행하는가
3-1. Docker 명령어와 예시
자주 사용하는 도커 명령어들을 하단에 나열하였다.
(이들의 실제 활용 예시는 후반부에서 구체적으로 설명)
<Dockerfile로 이미지 생성하기 : docker build>
docker build [옵션] <경로>
docker build -t <이미지명:태그> <경로>
-t 옵션으로 이미지의 이름과 태그를 지정한 것이며, 태그를 지정하지 않을 경우 latest로 지정된다.
## 예시 ##
docker build . # 현재 디렉토리에 있는 Dockerfile로 이미지 생성
docker build -t my-image . # 현재 디렉토리에 있는 Dockerfile로 my-image:latest 이미지 생성
<도커 이미지 목록 출력 : docker images>
docker images
아래는 미리 준비된 Dockerfile을 이용해서 docker build 명령어로 이미지를 빌드한 후, docker images 명령어로 출력하는 모습이다.
user@user-VirtualBox:~/Desktop/ex-docker$ docker build .
[+] Building 27.1s (17/17) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> ...생략...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:08a83756c396b9ca5d83735153cf0176056fb23c3eb3c 0.0s
user@user-VirtualBox:~/Desktop/ex-docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 9d201c4de2b6 2 minutes ago 122MB
user@user-VirtualBox:~/Desktop/ex-docker$ docker build -t my-image:1 .
[+] Building 0.8s (17/17) FINISHED
=> ...생략...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9d201c4de2b62519383058265e31669b167c422502643 0.0s
=> => naming to docker.io/library/my-image:1 0.0s
user@user-VirtualBox:~/Desktop/ex-docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-image 1 9d201c4de2b6 4 minutes ago 122MB
<도커 이미지로 컨테이너 생성 및 실행하기 : docker run>
docker run [옵션] <이미지명|ID> [명령어]
docker run -p <호스트 PORT>:<컨테이너 PORT> <이미지명|ID>
-p 옵션은 도커 컨테이너의 포트와 호스트의 포트를 매핑한다.
컨테이너에서 리슨하고 있는 포트를 호스트의 특정 포트로 접속할 수 있도록 한다.
docker run -it <이미지명|ID> <명령어>
-it 옵션으로 컨테이너에서 bash 셸을 사용할 수 있다.
-i (--interactive)는 표준 입력을 활성화하여 사용자가 명령어를 입력할 수 있도록 하고, -t(--tty)는 가상 터미널(tty)을 사용할 수 있도록 한다.
## 예시 ##
# docker run -it my-image:1 /bin/bash : my-image:1 이미지로 컨테이너 생성하고 실행하여 bash 셸 열기
user@user-VirtualBox:~/Desktop/ex-docker$ docker run -it my-image:1 /bin/bash
chall@852bb2be037c:~$
<실행 중인 컨테이너 목록 출력 : docker ps>
docker ps -a
-a 옵션은 종료된 컨테이너까지 모두 출력한다.
컨테이너를 실행한 상태로 다른 터미널 창을 열어 docker ps를 입력하면 아래와 같이 실행 중인 컨테이너 목록이 출력됨

컨테이너 안에서 exit 명령어를 실행하여 컨테이너를 종료한 후 docker ps를 입력하면 컨테이너가 출력되지 않고, docker ps -a 를 입력하면 종료된 컨테이너까지 출력되는 모습을 볼 수 있다.

앞서 봤던 docker run 명령 대신, 컨테이너 생성과 실행을 따로따로 명령할 수도 있다!
(run은 생성과 실행 같이함)
<도커 이미지로 컨테이너 생성 : docker create>
docker create [옵션] <이미지명|ID> [명령어]
<중단된 컨테이너 시작 : docker start>
docker start [옵션] <컨테이너명|ID>
## 예시 ##
user@user-VirtualBox:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-image 1 9d201c4de2b6 2 hours ago 122MB
user@user-VirtualBox:~$ docker create my-image:1
eb01688504dc201d9f3a03bf3a27d84cdeafca4b2110766d52fc7551a7d9d05a
user@user-VirtualBox:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb01688504dc my-image:1 "/bin/sh -c 'socat -…" 4 seconds ago Created priceless_meninsky
user@user-VirtualBox:~$ docker start eb01688504dc
eb01688504dc
user@user-VirtualBox:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb01688504dc my-image:1 "/bin/sh -c 'socat -…" 19 seconds ago Up 4 seconds 2222/tcp priceless_meninsky
<실행 중인 컨테이너에 접속하여 명령 수행 : docker exec>
docker exec [옵션] <컨테이너명|ID> [명령어]
docker run과 유사하게 -it 옵션으로 bash 셸 실행 가능!
## 예시 ##
user@user-VirtualBox:~$ docker exec -it eb01688504dc /bin/bash
chall@eb01688504dc:~$
<실행 중인 컨테이너 중단 : docker stop>
docker stop [옵션] <컨테이너명|ID>
<레지스트리에 존재하는 도커 이미지 다운로드 : docker pull>
docker pull [옵션] <이미지명>
## 예시 ##
user@user-VirtualBox:~$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
0c5227665c11: Pull complete
Digest: sha256:8aa9c2798215f99544d1ce7439ea9c3a6dfd82de607da1cec3a8a2fae005931b
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
<도커 컨테이너 삭제 : docker rm>
docker rm [옵션] <컨테이너명|ID>
<도커 이미지 삭제 : docker rmi>
docker rmi [옵션] <이미지명|ID>
<도커 이미지/컨테이너 정보 출력 : docker inspect>
docker inspect [옵션] <이미지 혹은 컨테이너명|ID>
user@user-VirtualBox:~$ docker inspect ubuntu:18.04
[
{
"Id": "sha256:3941d3b032a8168d53508410a67baad120a563df67a7959565a30a1cb2114731",
"RepoTags": [
"ubuntu:18.04"
],
"RepoDigests": [
"ubuntu@sha256:8aa9c2798215f99544d1ce7439ea9c3a6dfd82de607da1cec3a8a2fae005931b"
],
"Parent": "",
"Comment": "",
"Created": "2023-03-08T03:22:44.73196058Z",
"Container": "ee3fcc8c88d3f3129f1236850de28a7eba0da7c548a7b23a6495905ebcf255ea",
"ContainerConfig": {
"Hostname": "ee3fcc8c88d3",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/bash\"]"
],
"Image": "sha256:b64649bc9d1a48300ec5a929146aa3c5ca80046f74c33aa5de65a7046f5177a6",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "18.04"
}
},
"DockerVersion": "20.10.12",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "sha256:b64649bc9d1a48300ec5a929146aa3c5ca80046f74c33aa5de65a7046f5177a6",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "18.04"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 63146040,
"VirtualSize": 63146040,
"GraphDriver": {
"Data": {
"MergedDir": "/var/lib/docker/overlay2/0fe24c66cfaad338ccd55946d7734702a3575513fb2e697b409d3194c95c7e62/merged",
"UpperDir": "/var/lib/docker/overlay2/0fe24c66cfaad338ccd55946d7734702a3575513fb2e697b409d3194c95c7e62/diff",
"WorkDir": "/var/lib/docker/overlay2/0fe24c66cfaad338ccd55946d7734702a3575513fb2e697b409d3194c95c7e62/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:b7e0fa7bfe7f9796f1268cca2e65a8bfb1e010277652cee9a9c9d077a83db3c4"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
3-2. Dockerfile 명령어
아래 도커파일은 드림핵 강의에서 가져온 내용이다.
<전체 코드>
FROM ubuntu:22.04
ENV user chall
ENV chall_port 2222
RUN apt-get update
RUN apt-get install -y socat
RUN adduser $user
ADD ./deploy/flag /home/$user/flag
ADD ./deploy/$user /home/$user/$user
RUN chown -R root:$user /home/$user
RUN chown root:$user /home/$user/flag
RUN chown root:$user /home/$user/$user
RUN chmod 755 /home/$user/$user
RUN chmod 440 /home/$user/flag
WORKDIR /home/$user
USER $user
EXPOSE $chall_port
CMD socat -T 30 TCP-LISTEN:$chall_port,reuseaddr,fork EXEC:/home/$user/$user
도커 이미지를 빌드하기 위해서는 Dockerfile이 필요하다.
도커파일은 앞서 언급했듯이 이미지를 생성하는데 필요한 명령어를 포함하여 모든 설정이 정의된 파일이다.
(운영체제와 버전, 환경 변수, 파일 시스템, 사용자 등을 정의)
기본적으로 도커 파일의 파일명은 확장자 없이 "Dockerfile" 이며, 기본 형식은 아래와 같다.
docker build 명령어를 수행하면 자동으로 이름이 Dockerfile 인 파일을 찾아 이미지를 빌드한다!
-f 옵션으로 원하는 이름의 도커 파일을 사용할 수도 있음
# 주석
명령어 인자
# ---예시---
FROM ubuntu:18.04
dockerfile은 FROM 명령어로 시작해야 하며, 이후에는 순서대로 명령어를 실행한다.
FROM
- 생성할 이미지의 기반이 되는 base 이미지를 지정
- 보통 사용할 운영체제의 공식 이미지를 Dockerhub에서 가져온다.
FROM 이미지:태그
➡️ FROM ubuntu:18.04 # 예시
ENV
- dockerfile 내에서 사용하는 환경 변수를 지정
- 파일 내에서 변수는 $변수명 or ${변수명} 형태로 표현
ENV 변수명 값 or ENV 변수명=값
➡️ ENV PYTHON_VERSION 3.11.2 → .../python/$PYTHON_VERSION/... # 예시
RUN
- 이미지를 빌드할 때 실행할 명령어 작성
- 필요한 패키지를 설치하거나, 파일 권한 설정 등의 작업 수행
RUN 명령어 or RUN ["명령어", "인자1", "인자2"]
➡️ RUN apt-get update
➡️ RUN ["/bin/bash", "-c", "echo hello"]
COPY
- src 파일이나 디렉토리를 이미지 파일 시스템의 dest로 복사
COPY <src> <dest>
➡️ COPY . /app
ADD
- src 파일이나 디렉토리, URL을 이미지 파일 시스템의 dest로 복사
ADD <src> <dest>
➡️ ADD . /app
WORKDIR
- Dockerfile 내의 명령을 수행할 작업 디렉토리를 지정 (cd 명령어와 유사)
WORKDIR 디렉토리
➡️ WORKDIR /home/user
USER
- 명령을 수행할 사용자 혹은 그룹을 지정
USER 사용자명|UID or USER 사용자명|UID[:그룹명|GID]
➡️ USER $username
EXPOSE
- 컨테이너가 실행 중일 때 들어오는 네트워크 트래픽을 리슨할 포트와 프로토콜을 지정
- 사용할 수 있는 프로토콜은 TCP와 UDP 이며, 기본적으로 TCP가 지정됨
EXPOSE 포트 or EXPOSE 포트/프로토콜
➡️ EXPOSE 80/tcp
ENTRYPOINT
- 컨테이너가 실행될 때 수행할 명령어 지정
ENTRYPOINT 명령어 인자1 인자2 or ENTRYPOINT ["명령어", "인자1", "인자2"]
➡️ ENTRYPOINT ["echo", "hello"]
CMD
- 컨테이너가 실행될 때 수행할 명령어를 지정하거나, ENTRYPOINT 명령어에 인자를 전달
CMD 명령어 인자1 인자2 or CMD ["명령어", "인자1", "인자2"] or CMD ["인자1", "인자2"]
➡️ CMD ["echo", "hello"]
- dockerfile 내에 CMD 명령이 여러 개 존재하면 마지막 CMD를 사용
- docker run의 인자를 작성하면 cmd 명령어는 무시됨
- ENTRYPOINT가 있는 경우, docker run의 인자가 ENTRYPOINT의 인자로 들어감
ENTRYPOINT ["python"]
CMD ["app.py"]
도커파일이 위와 같을 때,
docker run [이미지] 로 컨테이너 실행하면 python app.py를 실행
docker run 이미지 test.py로 컨테이너를 실행하면 python test.py를 실행
아래 또 다른 도커파일 예시 코드를 보면서 기본적인 명령어들을 다시 이해해보자~
<전체 코드>
#Dockerfile
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y
RUN apt-get install apache2 -y
RUN apt-get install php -y
RUN apt-get install php7.2-xml -y
RUN apt-get install php-xmlrpc -y
RUN apt-get install libapache2-mod-php -y
COPY ./transcript /etc
COPY ./php.ini /etc/php/7.2/php.ini
RUN rm /var/www/html/index.html
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
WORKDIR /var/www/html/
EXPOSE 3000
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
FROM ubuntu:18.04
- FROM: 도커 이미지의 기반이 될 운영체제를 정의
- 이 코드는 ubuntu 18.04를 기반으로 하고 있으며, 이후 모든 명령은 해당 운영체제를 기반으로 실행된다!
ENV DEBIAN_FRONTEND=noninteractive
- ENV: 컨테이너 안에서 환경 변수를 설정
- 여기서 DEBIAN_FRONTEND=noninteractive 는 패키지를 설치할 때 대화형 프롬프트를 비활성화하도록 설정하는 환경 변수로서, 자동화된 설치 과정을 용이하게 한다.
RUN apt-get update -y
RUN apt-get install apache2 -y
RUN apt-get install php -y
RUN apt-get install php7.2-xml -y
RUN apt-get install php-xmlrpc -y
RUN apt-get install libapache2-mod-php -y
- RUN: 컨테이너 내부에서 명령어를 실행
- 여기서는 ubuntu의 패키지 관리자 apt-get을 사용해서 apache 웹 서버와 PHP 및 관련 패키지들을 설치하고 있다.
COPY ./transcript /etc
COPY ./php.ini /etc/php/7.2/php.ini
- COPY: 호스트 시스템에서 파일이나 디렉토리를 컨테이너 이미지 안의 지정된 위치로 복사
- 여기서는 ./transcript 파일을 컨테이너의 /etc 디렉토리로 복사하고,
- php.ini 파일을 /etc/php/7.2/php.ini 위치에 복사하여 PHP 설정 파일을 수정한 내용을 반영한다.
- 경로 작성할 때 주의사항: Dockerfile은 ~(틸다) 를 인식하지 못하므로, ~/Desktop 과 같은 경로 대신 절대 경로 사용!
RUN rm /var/www/html/index.html
- 기존의 기본 웹 페이지 파일인 index.html을 삭제한다.
- 이는 자신의 웹사이트를 새롭게 배포하기 위한 사전 작업!
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
- apache 웹 서버가 www-data라는 사용자와 그룹으로 실행되도록 환경 변수를 설정
WORKDIR /var/www/html/
- WORKDIR: 이후 명령어들이 실행될 작업 디렉토리를 설정
- 여기서는 /var/www/html/ 디렉토리로 설정하여, 해당 위치에서 이후 작업들이 이루어지게 한다.
- 참고로 /var/www/html 디렉토리는 apache 서버에서 실행되는 파일들의 저장 위치임
EXPOSE 3000
- EXPOSE: 컨테이너가 외부에 노출할 포트를 지정
- 여기서는 3000 포트를 열어서 외부에서 해당 포트로 접근할 수 있게 한다.
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
- CMD: 컨테이너가 실행될 때 기본적으로 수행할 명령어를 지정
- 여기서는 apache 서버를 실행하여 백그라운드에서 실행되는 대신 포그라운드에서 유지하도록 한다.
- 이렇게하면 컨테이너가 종료되지 않도록 할 수 있음!
4. Docker Hub 란?

- Docker Hub는 도커의 공식 레지스트리로, 도커 이미지를 저장하는 저장소
- Docker Hub 사용자는 이미지를 자유롭게 업로드하거나 다운 받아 사용함
- 다른 사용자가 업로드 한 이미지 뿐만 아니라 도커에서 제공하는 공식 이미지를 사용할 수 있다는 것도 편리
- 공식 이미지는 기본 OS(Linux, CentOS 등) 이미지나, 특정 프로그래밍 언어의 개발 환경 등을 제공
- 비공개 이미지를 업로드하여 개인적으로 사용하거나 팀끼리 공유할 수 있다.
<Docker Hub에 이미지 업로드하는 방법>
도커 허브를 이용하면 도커 파일이 아닌 이미지 "그 자체"를 보관하고 공유할 수 있다.
자신만의 문제 풀이 환경을 구축해두고 사용하고 싶거나, 워게임을 직접 제작하여 다른 사람들과 공유하고 싶은 경우 등에 유용함!
1. docker login : Docker Hub에 로그인
user@user-VirtualBox:~$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: dreamhackofficial
Password:
WARNING! Your password will be stored unencrypted in /home/user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
user@user-VirtualBox:~$
2. docker build -t [사용자]/[레포지토리명]:[TAG] [Dockerfile 경로] : Dockerfile을 이용하여 이미지 빌드하기
이미지 이름은 [사용자]/[레파지토리명]:[TAG] 형식으로 작성한다.
다음은 dreamhackofficial/exercise-docker:1 을 빌드해본 모습
user@user-VirtualBox:~/Desktop/ex-docker$ docker build -t dreamhackofficial/exercise-docker:1 .
[+] Building 1.8s (18/18) FINISHED
=> ...생략...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9d201c4de2b62519383058265e31669b167c422502643 0.0s
=> => naming to docker.io/dreamhackofficial/exercise-docker:1 0.0s
user@user-VirtualBox:~/Desktop/ex-docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dreamhackofficial/exercise-docker 1 9d201c4de2b6 6 hours ago 122MB
3. docker push [사용자]/[레파지토리명]:[TAG] : 레파지토리에 이미지 업로드
user@user-VirtualBox:~/Desktop/ex-docker$ docker push dreamhackofficial/exercise-docker:1
The push refers to repository [docker.io/dreamhackofficial/exercise-docker]
5f70bf18a086: Pushed
4958ae9bc6ae: Pushed
4b9b1ff53c81: Pushed
5d89cab1df92: Pushed
557171cb0464: Pushed
e04c36b2101d: Pushed
c8fe798e77a1: Pushed
714c2f225f87: Pushed
60ac9e1e9e64: Pushed
3cc715e175c0: Pushed
0482f429f461: Pushed
b93c1bd012ab: Mounted from library/ubuntu
1: digest: sha256:b0288419aa476a56c62d380f41c384f345405b41f7cffffa41aa9c1860fe4617 size: 2818
user@user-VirtualBox:~/Desktop/ex-docker$
아래는 위 과정을 거쳐 Docker Hub의 레포지토리에 이미지가 업로드된 모습이다.
우측의 명령어를 복사하여 누구나 이미지를 다운받을 수 있다.


<Docker Hub에서 이미지 다운로드하는 방법>
도커 허브에서 이미지는 레포지토리에 보관된다.
dreamhackofficial/exercise-docker 레포지토리에서 앞서 업로드했던 이미지를 다운받을 수 있다.
docker pull : Docker Hub에서 이미지 다운로드
- 원하는 레포지토리와 태그를 클릭하여 제공되는 명령어이다.
아래는 dreamhackofficial/exercise-docker 레포지토리의 tag 1 이미지를 성공적으로 다운로드한 모습이며, 해당 이미지로 컨테이너를 생성하고 실행하여 사용할 수 있다!
user@user-VirtualBox:~/Desktop/ex-docker$ docker pull dreamhackofficial/exercise-docker:1
1: Pulling from dreamhackofficial/exercise-docker
2ab09b027e7f: Already exists
dae082a9e205: Pull complete
ab969aeba5d6: Pull complete
cff12ac5c589: Pull complete
3f1e6d67fba6: Pull complete
818905cc8cec: Pull complete
09532c870255: Pull complete
3eda49607555: Pull complete
a88f78b4c1db: Pull complete
4ccef51b986d: Pull complete
5cf58cbc005e: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:b0288419aa476a56c62d380f41c384f345405b41f7cffffa41aa9c1860fe4617
Status: Downloaded newer image for dreamhackofficial/exercise-docker:1
docker.io/dreamhackofficial/exercise-docker:1
5. 도커 컴포즈(Docker-compose) 란?
- 단일 서버에서 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너의 묶음으로 관리할 수 있는 작업 환경을 제공하는 관리 도구
- 도커 컴포즈를 사용하지 않을 경우, 테스트 시 각 컨테이너를 하나씩 생성해야 함 (서버 컨테이너 하나.. db 컨테이너 하나... etc)
- 즉 매번 RUN 으로 옵션을 설정하여 컨테이너를 생성하기 보단, 여러 개의 컨테이너를 하나의 서비스로 정리해 컨테이너 묶음으로 관리하여 편의성을 도모할 수 있음!
- 따라서 단일 컨테이너를 실행 및 관리할 경우 dockerfile만 있으면 돼서 해당 파일이 꼭 필요하지는 않음
- 그러나 여러 컨테이너를 함께 사용하거나, 더 복잡한 애플리케이션을 구성하는 경우 도커 컴포즈 파일이 매우 유용
- 특히 개발 환경에서 로컬 파일을 컨테이너와 동기화하거나, 여러 서비스를 함께 실행해야 할 때 유용하다.
- dockerfile vs docker-compose 차이?
- Dockerfile : 하나의 컨테이너 이미지 빌드 과정을 정의
- docker-compose.yml : 여러 컨테이너의 조합을 정의하고, 이들 간의 연결을 설정
<docker-compose 설치 방법>
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- docker-compose 명령어는 docker 설치 후에 별도로 설치해줘야 하므로 위와 같이 설치
$ sudo chmod +x /usr/local/bin/docker-compose
- 설치가 끝났다면 docker-compose에 권한 부여
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
- 심볼릭 링크 설정
docker-compose --version
- 위 명령어를 입력했을 때 버전이 제대로 나온다면 잘 설치된 것

6. docker-compose.yml 예시 분석
<전체 코드>
#docker-compose.yml
version: "3"
services:
main:
build: .
container_name: pepero_theif
volumes:
- "./src:/var/www/html"
ports:
- 3000:80
restart: always
version: "3"
- version : 이 파일이 사용하는 docker compose의 파일 포맷 버전을 지정
services:
- services: 애플리케이션을 구성하는 하나 이상의 컨테이너를 정의하는 섹션
- 해당 섹션 아래에서 여러 개의 서비스를 정의할 수 있으며, 각각의 서비스는 개별 컨테이너로 실행됨
main:
- main 이라는 이름의 서비스를 정의하는 섹션
- 각 서비스는 개별 컨테이너에 매핑되며, main이라는 이름을 가진 컨테이너가 생성됨
build: .
- build: 도커 이미지를 빌드할 때 사용할 컨텍스트를 지정 (도커 파일 위치)
- 현재 디렉토리에서 Dockerfile을 찾고, 이를 기반으로 이미지를 빌드한다.
container_name: pepero_theif
- container_name: 생성되는 컨테이너의 이름을 지정
- 여기서 컨테이너의 이름은 peperop_thief 로 설정됨!
volumes:
- "./src:/var/www/html"
- volumes: 호스트 시스템의 디렉토리와 컨테이너 내부의 디렉토리를 연결 (호스트 : 컨테이너)
- 여기서는 호스트의 ./src 디렉토리를 컨테이너의 /var/www/html 디렉토리에 연결
- 이를 통해 개발 중인 파일을 호스트 시스템에서 수정하면, 컨테이너 내에서도 즉시 반영됨
ports:
- 3000:80
- ports: 호스트와 컨테이너 간의 포트 매칭을 정의
- 여기서는 호스트의 3000번 포트를 커네이너의 80번 포트와 연결
- 이를 통해 호스트의 localhost:3000으로 접속하면 컨테이너의 웹 서버에 접근할 수 있음
restart: always
- restart: 컨테이너가 중단될 경우 재시작 정책을 정의
- always 로 설정되면, 컨테이너가 중지되더라도 항상 다시 시작되도록 함
- 이는 서버가 재부팅되거나 컨테이너가 예기치 않게 종료되었을 때 유용!
7. 우분투에서 도커파일 생성 및 배포하는 방법
다들 도커 파일 작성에 대한 내용만 있고 정작 이를 "어떻게" 작성하고 이미지는 "어떻게" 빌드하는지 등등
super 왕초보들을 위한 내용은 없어서... 내가 기록해보려고 한다.
설마 이것도 모를까? 싶은 것들도 적음 (내가 몰라서 ㅎ)
1. dockerfile 작성
예를 들어 바탕화면에 tiramisu_cake 라는 이름의 폴더 안에 내가 배포하고 싶은 웹페이지 파일들이 있다고 가정하자.
그렇다면 이 폴더 안에 동일 경로에 Dockerfile을 생성해야 한다.
따라서 해당 폴더를 열어서 해당 위치에서 터미널을 열고 다음 명령어를 입력한 뒤 도커파일 코드를 넣고 Save
gedit Dockerfile

참고로 도커파일은 3번 주제에서 있었던 예시 양식 코드를 기반으로 변형하면 되는데,
초보자의 경우 지피티에게 물어보면 잘 변형해준다...ㅎㅎ

2. Docker 이미지 빌드
- 단일 dockerfile 사용하는 경우 -> 웹 서버만을 운영하는 경우, dockerfile만으로도 충분하기 때문에 sudo docker build와 sudo docker run 명령어를 사용하는 것이 적합함
- 여러 개의 컨테이너(웹 서버, db) 를 사용해야 하는 경우 -> docker-compose.yml 파일을 작성하고 docker-compose up -d 명령어를 사용하는 것이 더 효율적임
나의 경우는 db를 사용하지 않기 때문에 단일 dockerfile 이므로, 다음과 같이 이미지를 빌드했다.
sudo docker build -t tiramisu_cake .
- -t : 이미지의 이름을 지정하는 옵션
- ' . ' 은 현재 디렉토리를 의미

여기 이미지 빌드하는 과정에서 꽤나 애를 많이...먹었는데
당연한 얘기지만 경로를 꼼꼼하게 잘 체크해야 한다.
현재 바탕화면 Desktop 안에 있는 tiramisu_cake 라는 폴더 전체를 올리고 싶은 것이고, dockerfile도 해당 폴더 내부에 있기 때문에 도커 이미지 빌드 작업도 "해당 폴더 경로 내"에서 진행해야함
또한 도커파일 내에 COPY ./tiramisu_cake /var/www/html/ 이렇게 경로A에서 경로B로 복사하는 이런 코드들의 경로까지 꼼꼼하게 체크 해줘야 한다.
나는 해당 코드가 문제였어서 COPY . /var/www/html/ 로 변경 (현재 디렉토리인 '.' ) 했더니 겨우 성공했다...
- docker-compose를 이용하는 경우 다음 명령어를 이용하면 됨 (다음의 컨테이너 실행부분 명령어 안써도 됨)
sudo docker-compose up -d

나는 이런 warning 사인이 떠서 sudo docker-compose up --build -d 해줬더니 정상적으로 실행됐다.
3. Docker 컨테이너 실행
이미지 빌드가 완료되면, 해당 이미지를 기반으로 컨테이너를 실행할 수 있다.
sudo docker run -d -p 916:916 tiramisu_cake
- -d : 컨테이너를 백그라운드에서 실행하는 옵션
- -p 916:916 : 로컬 머신의 916번 포트를 컨테이너의 80번 포트에 매핑한다는 의미
- 여기서 916숫자는 포트번호를 의미하는 것으로서, 자신이 원하는 숫자 아무거나 넣으면 된다! 그러나 이는 도커파일에도 똑같이 적혀져 있어야 함 (EXPOSE ~~ 부분)
**참고**
- 도커 컨테이너 현황 확인
sudo docker ps -a
- 도커 컨테이너 멈추기
sudo docker stop {id}
- 도커 컨테이너 지우기
sudo docker rm {id}
- (도커 컨테이너를 모두 멈추고 지운 다음에) 도커 이미지 지우기
sudo docker rmi [이미지이름]
- 도커 컨테이너 다시 시작
sudo docker start

4. 웹사이트 확인
컨테이너가 정상적으로 실행되었다면, 이제 웹 브라우저를 열고 localhost:[포트번호] 이렇게 입력한 뒤에 웹사이트가 나오면, 정상적으로 작동하는 것을 볼 수 있다!

'Linux' 카테고리의 다른 글
[Ubuntu] gcc 설치 오류 해결 방법 : sudo apt-get install gcc (0) | 2024.09.01 |
---|---|
[Ubuntu] 용량 부족 시 디스크 용량 확인하는 방법 (disk space) (0) | 2024.08.21 |
[Ubuntu] 우분투 Desktop 이전 버전 설치하는 방법 (0) | 2024.08.09 |
[Ubuntu] Access denied 되었을 때 파일 권한 설정 하는 법 (0) | 2024.08.08 |
[Ubuntu] VMware 드래그 앤 드롭 (복사 붙여넣기) 설정하기 (0) | 2024.08.08 |