본문 바로가기
IT Study/Docker

[Docker] 현업에 사용하는 문법 총 정리

by 하람 Haram 2026. 3. 13.
728x90

이 글 하나로 Docker를 모두 정리할 수는 없지만

최소한 "Docker 사용해서 작업하세요" 에 대한 대응은 할 수 있을 정도로 구성하였다

 

1. Docker 기본

도커 이미지를 만드는 방법은 두가지가 있는데

1. Dockerfile을 통해 직접 만들어 Build 하기
2. 이미 있는 Docker Image 를 가져와서 Commit 하기

 

이미 있는 Docker Image를 가져와서 Commit 하는 경우는 다음과 같은 절차를 거친다

# 이미지 가져오고
docker pull python:3.10.19

# 이미지 실행하고
docker run -it --name my-python python:3.10.19 bash

''' 어떠한 작업 '''

# Container 밖에서 commit
docker commit python:3.10.19 harams:custom_python

이렇게 만들 수 있다

 

1-1 Docker 설치

물론 Docker 환경에서 작업하세요 라는 요청을 받았다는 것은

이미 Docker가 깔려있는 환경에서 작업하고 있을 확률이 높지만 굳이굳이 설치 법을 말하자면

https://www.docker.com/

 

Docker: Accelerated Container Application Development

Docker is a platform designed to help developers build, share, and run container applications. We handle the tedious setup, so you can focus on the code.

www.docker.com

위에 링크에서 본인에게 맞는 OS를 다운로드 받고

아래의 명령 프롬포트에서 다음 cmd를 쳐주면

이런식으로 command 똑바로 치라고 하는 창이 나오면 정상 다운로드 된것이다

 

1-2 . VSC Extension 설치

Docker를 시작하겠다 하면 묻지도 따지지도 말고 아래 세 개는 받고 시작하자.

나도 모르는 사이 도움을 받고 있을 것이다

 

특히, Remote Development 같은 경우는

이런식으로 SSH 연결하듯이 Container를 연결할 수 있어서 삶의 질이 향상 된다

 

2. 원하는 이미지 다운 받기

처음 Docker를 설치하였으면

docker images

를 치면 아무것도 나오질 않는다

그러면 Docker hub에 들어가서 원하는 환경을 pull 해주면 된다

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Software supply chain Secure Your Supply Chain with Docker Hardened Images Use Docker's enterprise-grade base images: secure, stable, and backed by SLAs for Ubuntu, Debian, Java, and more. Regularly scanned and maintained with CVE remediation and long-term

hub.docker.com

 

Dockerhub에 들어가 나의 프로젝트에 맞는 image를 찾고

docker pull [찾은 이미지명]:[태그]

 

그럼 어떤 이미지를 다운 받아야 하나? 라고 하면

2-1. GPU를 사용할 경우 (CUDA 기반)

nvidia/cuda:12.8.1-cudnn-runtime-ubuntu22.04

https://hub.docker.com/layers/nvidia/cuda/12.8.1-cudnn-runtime-ubuntu22.04/images/sha256-59e0e4376a0f16d10b03d3a14344b80a866a1674cb4948cb318291387ac05010

 

Image Layer Details - nvidia/cuda:12.8.1-cudnn-runtime-ubuntu22.04

 

hub.docker.com

참고로 12.8 뿐만 아니라 다른 것도 있으니 Torch 고려해서 다운 받자

 

2-2. Python 을 사용할 경우

python:3.12.13

https://hub.docker.com/layers/library/python/3.12.13/images/sha256-14e0d671c72ff5801dbb8c382fea331a953af090d5aa211222752fa90320605e

 

Image Layer Details - python:3.12.13

 

hub.docker.com

그냥 예시 몇개를 들은 것이지

직접 Hub들어가서 찾아보는 것을 추천한다


3. Dockerfile 

Base 로 사용할 (From 으로 사용할) 이미지를 가져왔다면

Dockerfile을 통해 만들어 줘야 한다

 

Dockerfile의 표준이 있는 것은 아니지만

case 별로 자주 쓰는 Dockerfile을 정리해보고자 한다

 

3-1. 기본 문법

가장 기본적인 명령어를 서두에 설명하면

    -  RUN : 명령어 실행 (예: 패키지 설치)
    -  COPY : 파일을 이미지에 목사
    -  CMD : 컨테이너 시작 시 실행할 명령어 (1개만 가능)
    -  ENTRYPOINT : 컨테이너 실행 시 실행할 명령어 (CMD와 함께 사용 가능)
    -  WORKDIR : 작업 디렉토리 설정
    -  ENV : 환경변수 설정
    - EXPOSE : 컨테이너에서 노출할 포트

 

3-2. 기본 python IMAGE Dockerfile

누군가가 아 됐고, 휘뚜루 마뚜루  쓸 수 있는 기본 python Dockerfile 주소하면

아래와 같이 작성한다

FROM python:3.10.19

WORKDIR /app
COPY . /app

ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONPATH=/app

# 대화형 방식의 terminal 방지
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y && rm -rf /var/lib/apt/lists/*
RUN python3 -m pip install --upgrade pip

RUN python3 -m pip install --no-cache-dir --ignore-installed -r requirements.txt

RUN python3 --version && pip --version
CMD ["python","main.py"]

자세한 설명은 아래 3-2 GPU IMAGE에서 하는 걸로 하자

 

 

3-3. GPU IMAGE Dockerfile

※ GPU 를 사용하기 위해서는 nvidia-docker가 필요하다

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html

 

Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit

Note There is a known issue on systems where systemd cgroup drivers are used that cause containers to lose access to requested GPUs when systemctl daemon reload is run. Refer to the troubleshooting documentation for more information.

docs.nvidia.com

 

여기서 명령어를 찾거나

아래의 명령어를 순차적으로 실행하자

# 1. Install the prerequisites for the instructions below:
sudo apt-get update && sudo apt-get install -y --no-install-recommends \
   ca-certificates \
   curl \
   gnupg2

# 2. Configure the production repository:
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# 3.Update the packages list from the repository:
sudo apt-get update

# 4. Install the NVIDIA Container Toolkit packages:
export NVIDIA_CONTAINER_TOOLKIT_VERSION=1.19.0-1
sudo apt-get install -y \
    nvidia-container-toolkit=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
    nvidia-container-toolkit-base=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
    libnvidia-container-tools=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
    libnvidia-container1=${NVIDIA_CONTAINER_TOOLKIT_VERSION}

 

이제 준비가 끝났으면 Dockerfile을 살펴보자

 

아래는 CUDA 12.8 기준으로 작성 되었으나

nvidia-smi

결과가 아래와 같이 12.2 이면 최대 12.2를 지원하므로 CUDA12.2 이하의 이미지를 다운받아야 한다

Container 도 결국 호스트 최대 CUDA의 영향을 받음

(근데 torch 자체가 12.2 는 없고 12.1 이 있으니 이런 예외 사항들을 찾아보고 하자)

 

즉, 반드시 실행환경의 CUDA 버전을 확인한 후 해당 이미지를 다운 받자

#FROM nvidia/cuda:12.1.0-cudnn8-runtime-ubuntu22.04
FROM nvidia/cuda:12.8.1-cudnn-runtime-ubuntu22.04

#어떤 GPU INDEX를 쓸건지 지정할 때 필요할 줄 알지만
# docker run --gpus '"device=0"' 와 같이 run 할 때 지정하는 게 맞음
# ENV NVIDIA_VISIBLE_DEVICES=0

#EXPOSE 8501 도 추가하면 Docker가 포트 매핑을 인식하기 쉬움
EXPOSE 8501

COPY . /app
WORKDIR /app


ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONPATH=/app

# 대화형 방식의 terminal 방지
ENV DEBIAN_FRONTEND=noninteractive
# Set environment variables for configuration
ENV PYTHON_VERSION=3.10

#>>>>>>>>>>>>>>>>>>>>>>>
RUN apt-get update && \
    apt-get install -y \
        sudo \
        nano \
        curl \
        software-properties-common && \
    add-apt-repository ppa:deadsnakes/ppa -y && \
    apt-get update && \
    apt-get install -y \
        python${PYTHON_VERSION} \
        python${PYTHON_VERSION}-dev \
        python3-pip \
        python3-venv && \
    rm /usr/bin/python3 && ln -s /usr/bin/python${PYTHON_VERSION} /usr/bin/python3 && \
    #심볼릭 링크 달기
    ln -sf /usr/bin/python3 /usr/bin/python && \
    rm -rf /var/lib/apt/lists/*
#>>>>>>>>>>>>>>>>>>>>>>>>

# 패키지 목록 업데이트
RUN apt-get update
# pip 업그레이드
RUN python3 -m pip install --upgrade pip

# pytorch  cuda 12.8 설치
RUN pip install torch torchvision --index-url https://download.pytorch.org/whl/cu128
# requirements.txt 설치 --ignore-installed 옵션 : 기존 시스템 패키지를 무시하고 새 버전을 덮어씀
RUN python3 -m pip install --no-cache-dir --ignore-installed -r requirements.txt

RUN python3 --version && pip --version

#CMD 컨테이너가 실행될 때 기본으로 실행할 명령을 지정(docker run 명령 뒤에 다른 명령을 주면, CMD는 덮어쓰기(overwrite))
#ENTRYPOINT 컨테이너가 실행될 때 항상 실행되어야 하는 명령을 지정합니다. (docker run 뒤에 추가 인자를 주면, 그것이 ENTRYPOINT의 인자로 전달)
CMD ["streamlit","run","Web_ui.py", "--server.address=0.0.0.0", "--server.port=8501"]

 

FROM nvidia/cuda:12.8.1-cudnn-runtime-ubuntu22.04

베이스 이미지를 FROM 명령어를 사용해서 가져온다

 

ENV NVIDIA_VISIBLE_DEVICES=0

어떤 GPU INDEX를 쓸건 지 지정 할 때 사용하는 줄 알지만

이렇게 지정하는 것이 아닌 run 을 할 때 --gbus ' "device=0" '와 같이 쓰는 게 맞다

 

EXPOSE 8501

이거 또한 안써도 정상 작동한다 왜냐하면 실제 포트 개방은 run에서 -p 옵션을 통해 하기 때문이다

- 하지만 EXPOSE를 해주면 이 컨테이너는 8501 포트를 사용합니다 라는 문서역활로 docker ps 에서 힌트를 주기 때문에

    -P 옵션 시 자동 매핑을 해준다

 

 

COPY . /app
WORKDIR / app

이거는 작업디렉토리를 설정해주는 명령어로 (현재의 디렉토리를 컨테이너 내부로 옮겨 줌)

COPY {COPY할 디렉토리(로컬)} {붙여넣을 디렉토리(Container)}

COPY {로컬 경로} {컨테이너 경로} 이다

그리고나서 WORKDIR {컨테이너 경로}를 해주면 이후 모든 명령어가 {컨테이너 경로} 기준으로 실행된다

(CLI 기준으로 cd WORKDIR 까지 들어왔다고 생각하면 된다)

 

ENV PYTHONUNBUFFERED=1

로그를 즉시 출력 시키는 코드이다

 

ENV PYTHONDONTWRITEBYTECODE=1

BYTECODE(.pyc) 가 생성되는 것을 방지한다

import 같은 거 할 때 .pyc 파일이 생기는데 이건 다음 코드를 실행할 때 더 빠르게 import 해줄 수 있도록

하는 것인데 성능이 미미하고 image 크기만 들려서 뺀다

PYTHONPATH=/app

import 경로에 /app을 추가해줘서 /app 하위에 있는 클래스/함수를 import 할 수 있게 한다

 

ENV PYTHONPATH, PYTHONUNBUFFERED, PYTHONDONTWRITEBYTECODE =1 는

어떤 의미냐고 생각보다는 그냥 붙여 넣자!

  • ENV 는 도커의 환경변수를 만드는데 사용하는 명령어 이다
  • PYTHONPATH는 Python의 모듈 검색 경로를 지정하는 변수
    • 여기서 모듈이란 python 코드에서 import 뒤에 붙는 것들 처럼 쓰게 해주는 것이다
      • ex) math, torch, my_module (<-my_module.py를 가져온 것)
      • 기본 적으로 제공되는 라이브러리는 모듈(.py)형태로 한 디렉토리에 모여 있음

 

PYTHON_VERSION=3.10

그냥 여기의 변수의 버전만 바꿔줘서 설치 과정 코드를 바꾸지 않고 사용하기 위한 변수

어떤 버전을 받건 무관하지만 pytorch 쓸 거면 엥간해서는 3.9 버전 이상을 받도록 하자

 

RUN apt-get update && \
    apt-get install -y sudo nano curl software-properties-common && \
    add-apt-repository ppa:deadsnakes/ppa -y && \
    apt-get update && \
    apt-get install -y \
        python${PYTHON_VERSION} \
        python${PYTHON_VERSION}-dev \
        python3-pip \
        python3-venv && \
    rm /usr/bin/python3 && \
    ln -s /usr/bin/python${PYTHON_VERSION} /usr/bin/python3 && \
    rm -rf /var/lib/apt/lists

 

본격적으로 python을 다운 받는 코드 이다

- deadsnakes PPA : Ubuntu 기본 python 대신 원하는 버전을 설치할 수 있게 해준다

     → 기본적으로 우분투가 제공하는 python 버전은 몇 개없다

     → 그래서 ppa:deadsnakes/ppa를 다운받아 줘야 한다 (Python의 다양한 버전을 제공하는 PPA)

     → 근데 이게 repository 여서 apt-get을 할 수 가 없어서

     → 먼저 software-properties-common 을 다운로드 받은 다음에 이걸 이용해서 ppa:deadsnakes/ppa를 다운로드 받는 거다.

 

- rm /usr/bin/python3 : 기존 시스템 기본 python 3 삭제

    → 이거 안쓰면 "어? 나는 3.9버전 받았는데 왜 3.8이 돌아가지?" 소리 나온다.

        우분투에 기본적으로 python3 파일이 있는데 이게 우리가 python을 실행할 때

        python3 train.py 이렇게 하면 호출이 되어서

        3.9 버전을 다운로드 받아도 적용이 안되는 문제가 생길 수도 있으니 꼭 적어 주도록하자

 

- ln -s : 심볼릭 링크 생성 (ln -sf는 강제로 생성)

  ln -s [파일 1] [파일2] : 심볼릭 링크(소프트 링크)

    → 파일1을 파일2처럼 사용하도록 해준다

    → 즉, ln -s ......python3.10 .......python3 의 의미는

         python3 -> python3.10으로 연결하는거

    → ln -sf ......python3 .......python

    → python -> python3로 연결하는 코드로 python -> python3 -> python3.10 으로 연결시켜서

         python main.py 같은 명령어를 수행 할 수 있게 해주는 것이다

 

만약 진짜 사람 구실 못하는 이미지 가져왔으면 vim 도 설치해 줘야 한다

 

rm -rf /var/lib/apt/lists 

var/libs/apt/lists는 python을 깔때 설치 가능한 패키지 목록 캐시이기 때문에 다운로드 받은 이후에는 사용하지 않고 수십MB를 사용하기 때문에 이미지 크기를 줄이기 위해 삭제한다

RUN apt-get update
RUN python3 -m pip install --upgrade pip

apt-get 패키지 목록을 업데이트하고 pip를 업데이트 한다

 

RUN pip install torch torchvision --index-url https://download.pytorch.org/whl/cu128

Pytorch를 설치해 준다(이 예시는 CUDA 12.8)

 

※여기서 중요한 것은 requirements.txt 를 freeze 명령어로 두었다면

torch, torchvision torchaudio 을 직접 삭제하고

아래와 같이 nvidia 관련 패키지가 적혀있으면 삭제하고 위의 명령어 들로 노는 것이 정신 건강에 편하다

 

그러면 저 url을 어떻게 받냐 라고 하면 pytorch 공식 페이지 에 들어가서 (https://pytorch.org/get-started/locally/)

여기 뒤에 index-url 부분을 기입해주면 된다.

 

RUN python3 -m pip install --no-cache-dir --ignore-installed -r requirements.txt

이거는 우리가 자주보던 pip install -r requiremets.txt 명령어가 맞고

딱봐도 엄청 많은 라이브러리 들이 다운로드 되는데 캐시가 남으면 이미지가 너무 무거워져 --no-cache-dir 옵션을 준다

(캐시는 다운로드 받았다가 삭제후 재 다운로드 받을 때 네트워크 사용없이 받기 이런거에 사용된다)

--ignore-installed 의 경우 이미 설치 되어 있는 패키지도 덮어쓰기 해서 받겠다라는 옵션이다

 

RUN python3 --version && pip --verision

python 이라도 해도 되지만 그냥 안전 빵으로 python3 를 적음

python과 pip가 제대로된 버전이 깔렸는지를 출력해보는 용도 있고

test로 python을 실행해보는 목적도 있다

 

CMD ["streamlit","run","Web_ui.py", "--server.address=0.0.0.0", "--server.port=8501"]

이거는 shell에서 우리가 실제 명령어를 날리는 부분을 나타낸 것으로

만약 이걸 bash에서 실행한다면

streamlit run Web_ui.py --server.address=0.0.0.0 --server.port=8501

가 된다

 

여기서

CMD 말고 ENTRYPOINT 를 쓸 수 있는데

가장 큰 차이는

CMD : docker run에서 명령어를 추가하면 CMD는 덮어쓰기 된다

    Container 실행 시 기본 실행 명령어

    CMD 컨테이너가 실행될 때 기본으로 실행할 명령을 지정(docker run 명령 뒤에 다른 명령을 주면, CMD는 덮어쓰기(overwrite)

 

ENTRYPOINT : docker run에서 인자를 추가하면 ENTRYPOINT 뒤에 붙는다

    Container 실행 시 고정 실행 명령어

    → --entrypoint 이렇게 명령어를 날리지 않는 이상 사라지지 않는다

    ENTRYPOINT 컨테이너가 실행될 때 항상 실행되어야 하는 명령을 지정합니다. 

    (docker run 뒤에 추가 인자를 주면, 그것이 ENTRYPOINT의 인자로 전달)

 

4. Docker Image Build

이제 dockerfile 이 준비되었으니 Build를 해주면 된다

docker build "Dockerfile이 위치한 경로" -t "이미지 이름:태그"

태그는 미 지정시 "latest"로 채워진다

현재 경로에 Dockerfile이 Docker file 이름으로 있다면 있다면

docker build . -t my_fastapi

 

이름도 Dockerfile도 아니고 경로가 다른 경로에 있다면

docker build /home/my_docker -t my_fastapi

 

이렇게 빌드 되는 걸 볼 수 있다

이거 다 끝나면

이렇게 FINISHED가 뜨는 걸 볼 수 있고

docker images

를 통해 방금 빌드한 이미지를 확인할 수 있다

 

만약 기존에 build하다가 실패 했으면 캐시가 남아 그대로 사용할 수 있으므로

docker build --no-cache -t anomaly_dashboard_image:cu128 .


이런 식으러 --no-cache 옵션을 줄 수 있다

 

 

5. 컨테이너 실행

sudo docker run -d \
  -p [내부포트]:[외부포트]\
  -v [컨테이너 외부 디렉토리]:[컨테이너 내부디렉토리]\
  --name [컨테이너 이름]\
  [실행한 이미지]\
  tail -f /dev/null

이것 저것 고민하지 말고 그냥 위에를 구문처럼 실행하기로 하자

-d : detached mode : 백그라운드 실행 (터미널 점유하지 x)

    이거 없이 실행하면 로그가 터미널에 계속 출력되고

    터미널이 컨테이너에 붙잡힌다

        → 붙잡히는 거에 가장 큰 문제는 Ctrl+c 를 누르면 컨테이너가 종료된다는 것이다

 

-p {호스트 port} {컨테이너 port}

자 이거는 조금헷갈릴 수 있어서 위의 docker file 예시 같이 

streamlit을 컨테이너에서 8501로 실행 했다고 하고 컨테이너를 실행시킨 서버 IP가 10.12.12.12 라고 가정하자

참고로 streamlit은 --server.port=7501 이런 식으로 port 를 지정할 수 있다

만약 streamlit run main.py --server.port=7501로 실행시켰고

-p 9981:7501 이라고 옵션을 주게 되면 호스트9981포트가 컨테이너 7501에 연결되고 그건 streamlit 과 연결되어

10.12.12.12:9981 을 URL에 적으면 streamlit 화면을 볼 수 있는 것이다

 

여기서 냅따 아무 포트나 잡지 말고

아래의 command를 통해 사용 중인 Port를 확인 하자

netstat -tnlp
  • -l : netstat에 대한 모든 수신 소켓 표시
  • -t : TCP 연결을 확인
  • -u : UDP 연결 확인
  • -p : 포트에서 수신하는 이름을 표기
  • -n : 서비스 이름 대신 port 번호 표기

 

 

-v [호스트 디렉토리] [컨테이너 디렉토리]

호스트 디렉토리를 컨테이너 디렉토리에 마운트 시켜서 해당 디렉토리에 변화를 컨테이너 내부에도 반영하여

굳이 container 안에 들어가서 수정하지 않고도 호스트 단에서 수정가능하도록 해준다

 

tail -f /dev/null

/dev/null 은 아무것도 없는 내용이고  -f => follow 계속지켜봄

즉, 아무 일도 안하면서 무한 대기하는 프로세스이다

이걸 하는 이유는

CMD를 썻을 때 CMD ["python","main.py"] 이고 main.py 가 단순 print("Hello world") 여서

출력하고 python이 종료되면 컨테이너도 바로 종료된다

근데 이 옵션을 주면 컨테이너가 계속 살아있게 된다

 

예시 1 (이미지 실행)

sudo docker run -d -p 9501:9501 -v /home/SL_Trouble_Shooting:/app --name trouble_shooting_edit_program python:3.15-rc-alpine tail -f /dev/null

 

예시 2 (GPU 연동 + Azure 연동)

sudo docker run -d --gpus '"device=0"' -p 8501:9501 -v ~/project_anomaly:/app --add-host {리소스명}.openai.azure.com:{endpoint-ip} --name anomaly_dashboard_program {이미지명}

추가로 어떤 GPU index를 사용하던 상관 없다면 --gpus all 옵션을 주면된다

 

예시 3 (기본 이미지 실행)

# docker run [이미지 이름]:[태그]    /    latest의 경우 태그 생략 가능
docker run --name mysql_tutorial -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:8.0.22

--name [컨테이너 이름] : 컨테이너 이름을 지정해주는 명령어(지정하지 않으면 랜덤으로 생성)

-e : 컨테이너 내에서 사용될 환경 변수를 정의 (environment의 약자) -> 사용하는 이미지에 따라 다름

        - 컨테이너 내부에서 ENV 썼다고 생각하면 쉽다

        - MySQL인 경우 root 계정의 비밀번호가 필요해서 설정한 것임

-d : 백그라운드 모드 (컨테이너를 백그라운드 형태로 실행 demon mode)

         - 이 설정을 하지 않으면, 실행 중인 셀 위에서 컨테이너가 실행(컨테이너 나가면 실행 종료) -> nohup와 비슷

-p : 포트를 지정(port) : 로컬 호스트 포트:컨테이너 포트

         로컬 포트 3306으로 접근하면 컨테이너 포트 3306으로 연결되도록 설정

         로컬 호스트 : 우리의 컴퓨터 / 컨테이너 : 컨테이너 이미지 내부

         (mysql은 기본적으로 3306 포트를 통해 통신)

         -> 어느 경로로 접근했을 때 컨테이너를 띄워줄 것인가

         (이거 연결 안해주면 로컬 포트 3306에 연결을 해도 컨테이너까지 닿지 않음)

mysql:8.0.22 : mysql 이미지를 가져오겠다

 

예시 4 (Container 안꺼지게 실행)

docker run -it --gpus all [Docker Imaege 이름] bash

-d 옵션으로 안꺼지게 유지하는 것

 

예시 5 (현재 폴더를 마운트 폴더로 지정)

docker run -it --gpus '"device=1"' -v $(pwd):/app/insp_db_agent -p 8501:8501 --name insp_db_agent insp_db_agent-image:latest

-- v : 볼륨 옵션 (마운트를 연결, 즉 container와 내 로컬의 공유 폴더를 만든다고 생각하면 된다)

    해당 코드는 $(pwd) : 현재 디렉터리의 절대경로와 컨테이너 내부의 /app/insp_db_agent를 연결하겠다는 뜻이다

 

6. Container 관련 명령어들

사실 위에서 받은 VSC Extension을 이용하면

필요 없는 명령어 들이긴 하지만 그래도 한번 적어보면

6-1. 컨테이너 stop/kill

실행을 멈추고 싶으면

docker stop [컨테이너 이름(혹은 ID)]

근데 Stop이 안 먹는다?? 비추하지만 방법이 있긴하다

docker kill [컨테이너 이름(혹은 ID)]

 

6-2. 실행 중인 컨테이너 확인

docker ps
docker ps -a

 

컨테이너가 실행 중인지 확인하려면 (특히 demon 모드는 보이지도 않음)

docker ps

 

을 치면

와 같이 mysql_tutorial이 실행되고 있음을 알 수 있다

아니 그러면 작동을 안하고 있는 컨테이너는???

docker ps -a

로 확인할 수 있다

 

근데 OK.. 실행되고 있는 건 알겠는데 어떻게 접근을 하는데

 

6-3. 컨테이너에 접근하기

컨테이너에 접근하기 위해서는 아래의 명령어를 실행하면 된다

(Compute Engine에서 SSH와 접속하는 것과 유사)

docker exec -it [컨테이너 이름(혹은 ID)] /bin/bash

exec : execute

-it : -i (interactive) + -t(tty)

        -i : 상호작용 모드 : 표준 입력(stdin)을 활성화하여 터미널로 부터 입력을 받을 수 있게 해줌

         -t : tty : TTY(가상 터미널)을 활성화 -> 터미널에서 실행 되는 것처럼 보이기 위해 가상 터미널을 할당

/bin/bash : 컨테이너 내에서 Bash 쉘을 실행

         (컨테이너에 Bash가 설치되어 있지 않다면 /bin/sh 와 같이 다른 쉟을 실행 할 수 있다)

         즉, 컨테이너 내부에서 실행할 프로그램(쉘)을 지정하는 부분

 

이론은 이렇지만 그냥 구문 같이 외우는 게 편하다

 

이렇게 하거나

근데 쳐보면 알다시피 ID로 접근하는 건 매우 빡센 일이기 때문에 컨테이너 이름을 지정하는 게 좋다

나올때는

Ctrl + D 를 하거나

exit

 

을 치면 나가진다

 

 

7. Docker Push and Pull

이미지를 다 만들었는데 서버에 옮겨서 작업하라는 요청들을 받을 수 있다.

이럴 때는 docker hub를 이용하면 되는데 쉽게 github docker 버전이라 생각하면 된다

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Software supply chain Secure Your Supply Chain with Docker Hardened Images Use Docker's enterprise-grade base images: secure, stable, and backed by SLAs for Ubuntu, Debian, Java, and more. Regularly scanned and maintained with CVE remediation and long-term

hub.docker.com

먼저 docker hub에 회원 가입을 해주자

 

그런 다음 push를 해주기 위해서는 반드시 login을 해야 한다.

docker login

을 통해서

 

이런 화면이 나올 텐데

쉽게 Website에서 로그인을 하던지

docker login -u <username>

을 통해서 로그인을 하던지 하라는 이야기이다.

 

나는 CLI 환경이 편해서 터미널을 이용하였고 Login Suceeded가 뜨면 성공이다

이제 push를 해주면 되는데 사전 작업으로 Image tag 및 이름 변경을 해줘야 한다

 

Image tag 및 이름 변경

 

기존에는

이렇게 이름을 짓고 tag로 GPU와 CPU 라는 이름을 지었다

하지만 이 상태로 docker push를 하게 된다면

denied: requested access to the resource is denied

거절 당한다

 

그 이유는

Docker 이미지를 push 할 때는

반드시 Image 이름을 {username}/{repository}:{tag} 형식으로 변경해야 한다

 

아래 코드를 통해서 바꿀 수 있다

docker tag {기존 image 이름}:{기존 image tag} {username}/{repository}:{tag}
docker tag insp_db_agent-image:GPU Agent/insp_db_agent-image:GPU

이렇게 이름을 변경하면

이렇게 image가 다른 이름으로 저장이 된다

이제 이걸 push 해주면 된다

docker push {username}/{Repository}:{tag}
docker push harams/insp_db_agent-image:GPU

이런거 뜨면 정상처리 된 거다

 

추가로 확인하고 싶으면

docker hub에 들어가서

이렇게 Repository가 생기고 해당 tag가 정상으로 저장된 것을 볼 수 있다

 

이제 옮길려고 하는 서버로 가서

마찬가지로 로그인을 해주고

docker pull {username}/{Repository}:{tag}
docker pull harams/insp_db_agent-image:GPU

pull 을 땡겨 주면 정상적으로 옮겨진다

docker images

 


8. Trouble Shooting

별로 코드 회고를 좋아하지 않는데 이걸 적어주었다

그 이유는 위에 주석까지 첨부한 이유인데

왜 이게 되고 왜 이게 안되는 지를 적어보자


8-1. 가상환경 (pyenv, conda) 다운받고 적용하려 했던 것

사실 상 Docker는 가상환경 보다는 상위 단계 가상 머신보다는 하위 단계라고 볼 수 있다 (내 생각)

근데 왜 굳이굳이 pyenv를 사용하려고 하냐

더 웃긴 건 막상 구현을 하려고 하면 아래 두 가지 때문에 답답해진다

(주석들 보면 나의 고민들이 보일 것이다)

    1.  Docker RUN 만으로 .bashrc 어떻게 수정하지?

    2. Shell 재실행 (exec "$SHELL")은 어떻게 하지?

- 이거 실제로 container 접속해서 재실행 해야한다

그냥 굳이굳이 하고 싶으면 pyenv 다운로드 받는 것 까지만 해 놓자

 

8-2. pytorch를 어떻게 받지?

pytorch는 보통 아래와 같이

RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

이런 식으로 받는다

근데 나는 requirements.txt로 다운로드 받고 싶었고

torch==2.4.0+cu118
torchaudio==2.4.0+cu118
torchvision==0.19.0+cu118

위와 같이 되어 있으면 오류가 나온다

 

해결 방법 1 : --extra-index-url 이용하기

requirements.txt를 수기로 다음과 같이 바꿨다

toolz==0.12.1
--extra-index-url https://download.pytorch.org/whl/cu118
torch==2.4.0+cu118
--extra-index-url https://download.pytorch.org/whl/cu118
torchaudio==2.4.0+cu118
--extra-index-url https://download.pytorch.org/whl/cu118
torchvision==0.19.0+cu118
tornado==6.4.1
tqdm==4.66.5

해결.

 

그럼 여기서 궁금한거 저 url 을 어떻게 받냐

예시로 쉽게 보면 cuda 12.8을 쓰고 싶다!

여기 뒤에 index-url 부분을 기입해주면 된다

(url 찾는 곳 : Pytorch 공식 페이지 : https://pytorch.org/get-started/locally/ )

 

해결 방법 2 : Dockerfile 이용하기

위에 는 requirements.txt에 넣는 방법이고

사실 Dockerfile을 이용하는 것이 제일 깔끔하다

근데 기존 프로젝트를 옮기는 경우가 많으니 이미 requirements 에

torchaudio, torch, torchvision 이 있으면 삭제 후

Dockerfile에 아래 명령어를 추가하자

# pytorch  cuda 12.8 설치
RUN pip install torch torchvision --index-url https://download.pytorch.org/whl/cu128

(url 찾는 곳 : Pytorch 공식 페이지 : https://pytorch.org/get-started/locally/ )

추가로

pytorch를 할 때 다운 받아지는

이 cuda 패키지 들도 삭제해주자

 

8-3. Docker Container가 잠깐 실행되고 꺼지는 문제

처음에는 당황했지만

문제는 내가 이미지가 잘 build되었는지 확인하려고 만든

CMD ["python3", "Hello_world.py"]

 

이게 문제 였다

 

Docker는 가상 머신이 아니다 (주어진 임무를 하고 종료하는 아이이다)

 

저걸 적으니깐 CMD를 실행하고 나서 "아 나는 할 일 다했으니 종료할게" 하고 꺼지는 것이다

저거는 이미지로 서버를 띄우거나 할 때만 사용하고

컨테이너를 계속 켜놓고 놀고 싶으면 사용하지 말도록 하자

 

8-4. permission denied while trying to connect to the Docker daemon socket 

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.48/images/create?fromImage=harams%2Finsp_db-image&tag=latest": dial unix /var/run/docker.sock: connect: permission denied

Docker 를 하다 보면 갑자기 다음과 같은 문구가 뜨면서 안될 때가 있다

 

이거는 사용자가 docker 권한이 없어서 생기는 문제로

groups

위와 같이 docker 가 보이지 않을 것이다

해결 방법 1. 권한 부여 후 newgrp 이용

계정에 로그인 이 된 상태로

sudo usermod -a -G docker $USER

권한을 부여해주고

newgrp docker

변경사항을 적용해주면

다음과 같이 docker가 생긴다

귀찮으면 sudo 앞에다 붙이면서 써도 된다

 

해결 방법 2. 권한 부여 후 getent 이용

위에 방법 말고 아래 방법으로도 가능한데

sudo usermod -a -G docker seungjong.yoo
getent group docker

 

 

usermod 로 그룹을 추가한다음

바로 적용하는 cmd getent 를 먹이면

 

생겨난다

해결 방법 3. sudo 이용

그냥 단순히 docker 앞에 sudo를 붙여도 해당 문제가 사라진다

 

8-5. GPU Project에서 주의 점

GPU를 사용하는 프로젝트에서

무작정

pip freeze > requirements.txt

때려버리면

 

충돌이 나서 이런 메세지가 나온다

ERROR: Cannot install -r requirements.txt (line 187) and nvidia-nccl-cu11==2.21.5 because these package versions have conflicting dependencies.

그러므로 해당 부분을 삭제하고

cuda 나 GPU 이미지를 사용하면 해결 된다

 

 

 

 

참고자료

https://dream2reality.tistory.com/20

 

Docker 이미지 만들기

Docker 명령어가 익숙하지 않다면2024.09.20 - [Programming/Docker] - Docker 설치 및 사용법 Docker 설치 및 사용법이 글에서는 Docker 명령어를 실습해보며 Docker에 대한 이해를 깊이 있게 넓혀간다.Docker가 무

dream2reality.tistory.com

 

https://cdchan.tistory.com/260

 

docker hub 사용하는 방법

Docker Hub 사용법: 이미지 Push & Pull 1. Docker Hub 계정 생성먼저 Docker 공식 홈페이지에 접속하여 계정을 생성합니다. 제가 사용하고 있는 계정 ID는 charliekorean입니다. 2. 로컬 환경에서 Docker 로그인터

cdchan.tistory.com

 

https://ikcoo.tistory.com/33#google_vignette

 

03. Docker Hub에 image push 하기

Docker Hub에 image push 하기 [ 과정 설명 ] docker hub 에서 원본 이미지를 받아온 뒤 사용하고자 하는 container image로 변경한 뒤 다시 docker hub로 push 하기 [ Docker image 받아오기 ] docker pull [ docker hub id ] / [ i

ikcoo.tistory.com

728x90