Dockerfile을 읽을 줄 안다는 것은 해당 이미지가 어떻게 구성되어 있는지 알 수 있다는 의미이다.
Dockerfile 작성 방법
키워드
FROM: 시작점이 될 베이스 이미지를 지정한다.
MAINTAINER: 이미지를 생성한 개발자의 정보를 표시한다. (1.13.0 이후에는 권장되지 않고, LABEL을 사용하는 것이 좋다.)
LABEL: 이미지에 메타데이터를 추가한다. key-value 형태로 지정된다.
RUN: 이미지 내에서 명령어를 실행한다. 실행 결과는 새로운 레이어에 기록되고, 이 레이어는 최종 이미지에 포함된다. 각 RUN 명령은 새로운 레이어를 생성하며, 이러한 레이어들은 캐시되어 재사용될 수 있다.
WORKDIR: 컨테이너 내에서의 작업 디렉토리를 지정한다. 해당 디렉토리가 없으면 자동으로 생성되며, 이후의 작업들은 이 디렉토리 내에서 실행된다.
EXPOSE: 이미지를 실행할 때 열려야 하는 포트를 지정한다. 이 포트는 컨테이너 실행 시 -p 옵션으로 호스트와 매핑될 수 있다.
USER: 컨테이너가 실행될 때 사용될 사용자를 지정한다. (기본값 root)
COPY / ADD: 호스트 시스템의 파일이나 디렉토리를 이미지에 복사한다. ADD는 COPY보다 확장된 기능을 제공한다. ADD는 URL로부터 파일을 가져오거나 압축 해제 기능도 제공한다. 특별한 기능이 필요하지 않은 경우, COPY를 사용하는 것이 권장된다.
ENV: 컨테이너 내에서 사용될 환경 변수를 설정한다.
CMD / ENTRYPOINT: 컨테이너를 생성하거나 실행할 때 수행될 명령어를 정의한다. docker run 명령으로 새 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 해당 명령어가 실행된다. 주로 컨테이너 내부에서 지속적으로 실행되어야 하는 서버나 애플리케이션을 시작할 때 사용된다.
CMD: CMD는 docker run 실행 시 추가적인 명령어가 주어지면, 해당 명령어를 ENTRYPOINT에 지정된 명령어의 인자로 사용한다. 만약 ENTRYPOINT가 정의되어 있지 않다면, CMD에서 지정한 명령어를 실행한다.
Dockerfile 내에서 CMD를 여러 번 정의할 수 있지만, 마지막으로 정의된 CMD만 최종적으로 사용된다.
CMD는 3가지 형태로 작성될 수 있다: - CMD ["executable", "param1", "param2"]: 실행할 프로그램과 그에 대한 인자를 지정한다. - CMD ["param1", "param2"]: ENTRYPOINT로 지정된 실행 가능한 파일의 인자로 사용된다. - CMD command param1 param2: shell 형태로 명령어를 실행한다. 여기서는 /bin/sh -c를 사용하여 해당 명령어를 실행한다.
ENTRYPOINT : ENTRYPOINT는 docker run 실행 시, 추가적인 명령어가 주어지면 이 명령어는 ENTRYPOINT에 지정된 명령어에 대한 인자로 사용된다. CMD에서 기본 인자가 제공되었을 때 docker run에서 명령어를 추가로 주게 되면, CMD의 인자는 덮어쓰여진다.
ENTRYPOINT 명령은 2가지 형태로 제공된다: - exec 형태: ENTRYPOINT ["executable", "param1", "param2"]. 이 형태는 명령어가 PID 1로 실행되어 신호 처리가 올바르게 이루어진다. - shell 형태: ENTRYPOINT command param1 param2. 이 형태를 사용할 때, 명령어는 실제로 /bin/sh -c 내에서 실행되므로 신호 처리에 주의가 필요하다.
ENTRYPOINT는 CMD와 함께 사용될 때, ENTRYPOINT는 실행할 명령어를, CMD는 그 명령어의 기본 인자로 사용된다.
Docker 빌드
Dockerfile의 기본이름은 Dockerfile이다. 파일명을 이렇게 설정하면 파일이 위치한 경로에서 docker build . 만 해도 빌드가 가능하다. 하지만 이렇게 생성하면 이미지의 이름과 태그가 없기 때문에 -t 옵션으로 태그와 파일명 지정이 가능하다.
docker build . -t container_name:tag
Dockerfile은 파일명 변경이 가능하다. 위에서 파일명을 다르게 지정했다면 -f 옵션으로 지정이 가능하다.
구글 검색을 통해 C++로 작성된 HTTP 클라이언트/서버 애플리케이션을 개발할 때 도움를 주는 C++ REST SDK (또는 Casablanca) 라이브러리를 찾았다.
해당 라이브러리는 microsoft의 공식 라이브러리로 깃 허브에 올라와 있었기 때문에, 빌드를 위해 아래 Dockerfile을 작성했다.
casablanka.Dockerfile
FROM ubuntu:latest AS env
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y sudo
RUN apt-get install -y g++ git libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev openssl libssl-dev ninja-build
RUN git clone https://github.com/microsoft/cpprestsdk.git
RUN apt-get install -y cmake zlib1g-dev
WORKDIR cpprestsdk
RUN mkdir build && cd build
RUN cmake . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DCMAKE_CXX_FLAGS="-Wno-error" -DCMAKE_CXX_FLAGS="-Wno-format-truncation"
RUN make -j$(nproc)
RUN sudo make install
위 코드를 사용해 docker로 빌드하면 .so 파일들이 나온다.
하지만 지금은 윈도우 용 프로그램을 만들고 있기 때문에 visual studio에서 사용할 수 있도록 설정을 다시해봐야 할 것 같다.
검색을 통해 /etc/resolv.conf 등 필요한 파일들을 수정해줬고, DNS (8.8.8.8) 주소도 잘 설정되어 있다.
하지만 여전히 update가 안되었기 때문에 결국 필요한 패키지들을 수동으로 설치하기로 했다.
apt-get download
보통 필요한 패키지들은 apt-get install로 시스템에 바로 설치하지만 현재는 원인을 알 수 없는 이유로 저장소 연결이 제한된다. 패키지의 수동 설치를 위해서 먼저 docker 컨테이너를 빠져나가 apt-get이 잘 작동되는 os에서 필요한 패키지들을 다운로드 받는다.
$ sudo apt-get download vim net-tools iproute2 iputil-ping
apt-get download 명령어는 현재 디렉토리에 .deb 형태로 필요한 패키지를 다운로드 받는다.
aaa라는 임시 폴더를 만들어 내부에 필요한 deb 들을 설치했다.
이제 이 파일들을 도커 내부의 ubuntu:20.04로 전달하여 수동으로 설치하면 된다.
docker cp
도커는 도커 외부와 내부 컨테이너 간의 파일 공유가 가능하며 docker cp 명령어로 해당 기능을 제공한다.
위에서 내려받은 deb 파일을 ubuntu:20.04 컨테이너에 넣어준다.
$ sudo docker cp ../aaa/ test:/aaa/
잘 전달되었다.
이제 전달된 deb를 설치해주자.
apt install ./
apt install 명령어를 사용하면 패키지를 설치할 수 있다.
여기서 주의할 점이 있는데, install 뒤에 패키지 명을 그냥 입력하면 저장소에서 해당 패키지를 찾기 때문에
이 글에선 컨테이너 외부의 우분투에 미리 설정되어 있기 때문에 해당 파일을 도커 내부 같은 경로에 cp 명령어로 덮어씌워 줬다.
아래는 /etc/apt/source.list의 내용이고 기존 파일에 kakao 서버 주소만 추가해 주었다.
필요하다면 그대로 사용해도 좋고 다른 국내 서버 주소를 찾아서 추가해줘도 좋다.
$ vi /etc/apt/source.list
# deb cdrom:[Ubuntu 20.04.4 LTS _Focal Fossa_ - Release amd64 (20220223)]/ focal main restricted
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://kr.archive.ubuntu.com/ubuntu/ focal main restricted
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal main restricted
## Major bug fix updates produced after the final release of the
## distribution.
deb http://kr.archive.ubuntu.com/ubuntu/ focal-updates main restricted
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-updates main restricted
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://kr.archive.ubuntu.com/ubuntu/ focal universe
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal universe
deb http://kr.archive.ubuntu.com/ubuntu/ focal-updates universe
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-updates universe
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb http://kr.archive.ubuntu.com/ubuntu/ focal multiverse
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal multiverse
deb http://kr.archive.ubuntu.com/ubuntu/ focal-updates multiverse
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-updates multiverse
## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://kr.archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse
# deb-src http://kr.archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse
## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu focal partner
# deb-src http://archive.canonical.com/ubuntu focal partner
deb http://security.ubuntu.com/ubuntu focal-security main restricted
# deb-src http://security.ubuntu.com/ubuntu focal-security main restricted
deb http://security.ubuntu.com/ubuntu focal-security universe
# deb-src http://security.ubuntu.com/ubuntu focal-security universe
deb http://security.ubuntu.com/ubuntu focal-security multiverse
# deb-src http://security.ubuntu.com/ubuntu focal-security multiverse
# This system was installed using small removable media
# (e.g. netinst, live or single CD). The matching "deb cdrom"
# entries were disabled at the end of the installation process.
# For information about how to configure apt package sources,
# see the sources.list(5) manual.
# kakao
deb http://ftp.daumkakao.com/ubuntu/ bionic main restricted
deb http://ftp.daumkakao.com/ubuntu/ bionic-updates main restricted
deb http://ftp.daumkakao.com/ubuntu/ bionic universe
deb http://ftp.daumkakao.com/ubuntu/ bionic-updates universe
deb http://ftp.daumkakao.com/ubuntu/ bionic multiverse
deb http://ftp.daumkakao.com/ubuntu/ bionic-updates multiverse
deb http://ftp.daumkakao.com/ubuntu/ bionic-backorts main restricted universe multiverse
파일을 덮어씌우고 update와 upgrade를 한번씩 더 해줬다.
이제 python3, pip3, vim, venv를 apt-get install로 설치한다.
$ apt-get install -y python3 python3-pip python3-venv vim