Docker Spaces
Docker Spaces
Spaces는 Streamlit과 Gradio의 범위를 벗어난 앱을 위한 커스텀 Docker 컨테이너를 수용해요. Docker Spaces를 쓰면 표준 SDK로는 불가능했던 한계를 넘어설 수 있습니다.
출처: 문서
본문
Spaces는 Streamlit과 Gradio 범위를 벗어난 앱을 위한 커스텀 Docker 컨테이너를 수용합니다. Docker Spaces는 사용자가 표준 SDK로는 이전에 가능했던 한계를 넘어설 수 있게 해줘요. FastAPI와 Go 엔드포인트부터 Phoenix 앱과 ML Ops 도구까지, Docker Spaces는 다양한 환경에서 도움이 됩니다.
Docker Spaces 설정하기 (Setting up Docker Spaces)
새 Space를 만들 때 SDK로 Docker를 선택하면 README.md 파일의 YAML 블록에 sdk 속성을 docker로 설정해 Space를 초기화합니다. 또는 기존 Space 리포지토리에서 Spaces의 README.md 파일 맨 위의 YAML 블록 안에 sdk: docker를 설정하세요. 기본 노출 포트 7860은 app_port: 7860으로 변경할 수도 있어요. 이후 평소처럼 Dockerfile을 만들면 됩니다.
---
title: Basic Docker SDK Space
emoji: 🐳
colorFrom: purple
colorTo: gray
sdk: docker
app_port: 7860
---
내부적으로는 원하는 만큼 많은 포트를 열 수 있어요. 예를 들어 Space 안에 Elasticsearch를 설치하고 기본 포트 9200으로 내부 호출할 수 있습니다.
여러 포트에서 제공되는 앱을 외부 세계에 노출하려면 Nginx 같은 리버스 프록시를 사용해 외부 인터넷의 요청(단일 포트)을 서로 다른 내부 포트로 분배하는 우회책을 쓸 수 있어요.
시크릿과 변수 관리 (Secrets and Variables Management)
Space 설정에서 Space의 환경 변수를 관리할 수 있어요. 자세한 내용은 여기를 참고하세요.
변수 (Variables)
빌드 타임 (Buildtime)
변수는 Docker Space를 빌드할 때 build-arg로 전달됩니다. Dockerfile에서 이걸 사용하는 완전한 가이드는 Docker 전용 문서를 읽어보세요.
# Declare your environment variables with the ARG directive
ARG MODEL_REPO_NAME
FROM python:latest
# [...]
# You can use them like environment variables
RUN predict.py $MODEL_REPO_NAME
런타임 (Runtime)
변수는 런타임에 컨테이너의 환경에 주입됩니다.
시크릿 (Secrets)
빌드 타임 (Buildtime)
Docker Spaces에서는 보안상 이유로 시크릿 관리가 다릅니다. Settings 탭에서 시크릿을 만들면, Dockerfile에 다음 줄을 추가해 시크릿을 노출할 수 있습니다.
예를 들어 SECRET_EXAMPLE이 Settings 탭에서 만든 시크릿 이름이라면, 이를 파일에 마운트한 뒤 $(cat /run/secrets/SECRET_EXAMPLE)로 읽어서 빌드 타임에 사용할 수 있어요.
아래 예시를 참고하세요:
# Expose the secret SECRET_EXAMPLE at buildtime and use its value as git remote URL
RUN --mount=type=secret,id=SECRET_EXAMPLE,mode=0444,required=true \
git init && \
git remote add origin $(cat /run/secrets/SECRET_EXAMPLE)
# Expose the secret SECRET_EXAMPLE at buildtime and use its value as a Bearer token for a curl request
RUN --mount=type=secret,id=SECRET_EXAMPLE,mode=0444,required=true \
curl test -H 'Authorization: Bearer $(cat /run/secrets/SECRET_EXAMPLE)'
런타임 (Runtime)
공개 변수와 마찬가지로 런타임에 시크릿을 환경 변수로 접근할 수 있어요. 예를 들어 Python에서는 os.environ.get("SECRET_EXAMPLE")을 사용합니다. 시크릿을 사용하는 Docker Space 예시를 확인해 보세요.
권한 (Permissions)
컨테이너는 사용자 ID 1000으로 실행됩니다. 권한 문제를 피하려면 COPY나 다운로드 전에 사용자를 만들고 WORKDIR을 설정해야 합니다.
# Set up a new user named "user" with user ID 1000
RUN useradd -m -u 1000 user
# Switch to the "user" user
USER user
# Set home to the user's home directory
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
# Set the working directory to the user's home directory
WORKDIR $HOME/app
# Try and run pip command after setting the user with `USER user` to avoid permission issues with Python
RUN pip install --no-cache-dir --upgrade pip
# Copy the current directory contents into the container at $HOME/app setting the owner to the user
COPY --chown=user . $HOME/app
# Download a checkpoint
RUN mkdir content
ADD --chown=user https://<SOME_ASSET_URL> content/<SOME_ASSET_NAME>
ADD와 COPY에는 항상 --chown=user를 지정해 새 파일이 사용자 소유가 되도록 하세요.
여전히 권한 문제가 있다면 Dockerfile에서 chmod나 chown으로 올바른 권한을 부여해야 할 수 있어요. 예를 들어 /data 디렉터리를 사용하려면:
RUN mkdir -p /data
RUN chmod 777 /data
불필요한 chown은 항상 피해야 합니다.
[!WARNING] 파일의 메타데이터를 업데이트하면 새 레이어에 저장된 새 복사본이 생깁니다. 따라서 재귀적 chown은 영향을 받는 모든 파일이 복제되어 이미지가 매우 커질 수 있습니다.
chown을 실행해 권한을 수정하는 대신:
COPY checkpoint .
RUN chown -R user checkpoint
항상 이렇게 하세요:
COPY --chown=user checkpoint .
(ADD 명령도 마찬가지)
데이터 영속성 (Data Persistence)
디스크에 쓴 데이터는 Docker Space가 다시 시작할 때마다 사라집니다. 재시작에도 데이터를 유지하려면 Space에 Storage Bucket을 연결할 수 있어요.
현재 /data 볼륨은 런타임에만 사용할 수 있습니다. 즉 Dockerfile의 빌드 단계에서는 /data를 사용할 수 없어요.
특정 경우에는 Datasets Hub를 사용해 상태와 데이터를 git LFS 리포지토리에 저장할 수도 있습니다. 영속성 예시는 여기에서 찾을 수 있으며, huggingface_hub 라이브러리로 데이터셋 리포지토리에 파일을 프로그래밍 방식으로 업로드합니다. 이 Space 예시와 이 가이드는 데이터 유형에 가장 적합한 솔루션을 정하는 데 도움이 됩니다.
마지막으로 어떤 경우에는 외부 호스팅 DB, S3 같은 외부 스토리지 솔루션을 Space 코드에서 사용하고 싶을 수 있어요.
GPU가 있는 Docker 컨테이너 (Docker container with GPU)
GPU 지원 Docker 컨테이너는 GPU 버전 Spaces Hardware 중 하나를 사용해 실행할 수 있어요.
베이스 이미지로 CUDA와 cuDNN이 사전 설치된 Docker Hub의 nvidia/cuda를 권장합니다.
Docker 빌드 타임 동안에는 GPU 하드웨어에 접근할 수 없습니다. 따라서 Dockerfile의 빌드 단계에서 GPU 관련 명령을 실행하려고 해선 안 됩니다. 예를 들어 이미지를 빌드하면서 nvidia-smi나 torch.cuda.is_available()을 실행할 수 없어요. 자세한 내용은 여기를 참고하세요.
더 읽기 (Read More)
더 알아보기 (Learn more)
Docker Spaces는 sdk: docker를 README.md YAML에 설정하고 Dockerfile을 작성하는 방식으로 시작해요. 시크릿·변수는 빌드 타임(build-arg, --mount=type=secret)과 런타임(환경 변수)으로 관리하고, 권한 문제를 피하려면 --chown=user를 쓰세요. 재시작 시 데이터가 사라지므로 Storage Bucket이나 Datasets Hub로 영속화합니다. GPU는 빌드가 아닌 런타임에만 사용할 수 있어요.