# syntax=docker/dockerfile:1.7-labs # --------------------------------------------------------------------------- # vkgs-sim 개발 이미지 — 로컬 micromamba 환경 `vkgs` 를 그대로 옮긴 것 # # 로컬 개발(scripts/local_setup.sh)과 같은 스택을 같은 버전으로 넣는다: # conda docker/conda-lock.txt (micromamba env export -n vkgs --explicit) # gcc 12 · CUDA 12.1 nvcc · Vulkan 로더/헤더 · glslc · cmake · Tracy 의존성 # pip torch 2.4.1+cu121 · gsplat 1.4.0 · docker/requirements.lock.txt (pip freeze) # 잠금 파일을 다시 뽑는 법은 docker/README.md. # # 저장소 전체(소스 · 설정 · third_party · assets · docs · cache · outputs)를 실제 파일로 담는다 — 심볼릭 링크는 # 빌드 컨텍스트를 tar -h 로 넘겨 원본 파일로 풀어 넣는다 (docker/build_image.sh). 경로는 호스트와 같은 # /home/mm/Downloads/vkgs-sim — outputs/ 의 segments.txt 등이 절대 경로를 담고 있다. # nuScenes 원본(67 TB NFS)은 넣지 않는다 — 실행 때 읽기 전용으로 마운트 (docker/README.md). # 호스트: Ubuntu 20.04 / NVIDIA 535 (최대 CUDA 12.2) / RTX 3060 Ti (sm_86). # --------------------------------------------------------------------------- FROM nvidia/cuda:12.1.1-base-ubuntu22.04 ARG CUDA_ARCH="8.6" ARG USERNAME=dev ARG UID=1000 ARG GID=1000 ENV DEBIAN_FRONTEND=noninteractive \ TZ=Asia/Seoul \ LANG=C.UTF-8 \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ MAMBA_ROOT_PREFIX=/opt/conda \ TORCH_CUDA_ARCH_LIST=${CUDA_ARCH} # Vulkan 은 graphics,display 가 있어야 컨테이너에 NVIDIA ICD 가 들어온다 (없으면 장치 0개). ENV NVIDIA_VISIBLE_DEVICES=all \ NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics,display # --------------------------------------------------------------- 1. 시스템 (최소) # 컴파일러·CUDA·Vulkan 은 전부 conda 가 넣는다. 여기는 conda 가 못 주는 것과 셸 도구만. # libegl1 · libgl1 · libx11-6 등은 NVIDIA 드라이버 라이브러리(컨테이너 툴킷이 주입)가 링크한다. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ rm -f /etc/apt/apt.conf.d/docker-clean && \ apt-get update && apt-get install -y --no-install-recommends \ ca-certificates curl bzip2 git git-lfs sudo locales tzdata \ less vim tmux htop tree jq rsync \ libegl1 libgl1 libglvnd0 libx11-6 libxext6 libxrandr2 libxinerama1 libxcursor1 libxi6 \ libxkbcommon0 libxkbcommon-x11-0 libwayland-client0 libxxf86vm1 \ fonts-noto-cjk \ && rm -rf /var/lib/apt/lists/* # --------------------------------------------------------------- 2. conda 환경 (잠금 그대로) # 버전 고정 단일 바이너리 (micro.mamba.pm 의 latest tar 는 빌드 중 깨진 응답을 준 적이 있다) ARG MICROMAMBA_VERSION=2.0.5-0 RUN curl -fsSL --retry 5 -o /usr/local/bin/micromamba \ https://github.com/mamba-org/micromamba-releases/releases/download/${MICROMAMBA_VERSION}/micromamba-linux-64 && \ chmod +x /usr/local/bin/micromamba && micromamba --version COPY docker/conda-lock.txt /tmp/conda-lock.txt RUN --mount=type=cache,target=/opt/conda/pkgs \ micromamba create -y -n vkgs -f /tmp/conda-lock.txt # 이후 RUN 은 전부 활성화된 환경에서 (conda 컴파일러는 activate.d 가 CC/CXX 로 건다 — 없으면 CMake 가 컴파일러를 못 찾는다) COPY docker/activate.sh /usr/local/bin/vkgs-activate RUN echo 'source /usr/local/bin/vkgs-activate' >> /etc/bash.bashrc ENV BASH_ENV=/usr/local/bin/vkgs-activate SHELL ["/bin/bash", "-c"] # --------------------------------------------------------------- 3. Python (local_setup.sh 3~4단계와 같은 순서) # torch 를 단독 레이어로 — 2 GB 가 넘어 아래가 바뀔 때마다 다시 받으면 감당이 안 된다. RUN --mount=type=cache,target=/root/.cache/pip \ python -m pip install --index-url https://download.pytorch.org/whl/cu121 \ torch==2.4.1 torchvision==0.19.1 COPY docker/requirements.lock.txt /tmp/requirements.lock.txt RUN --mount=type=cache,target=/root/.cache/pip \ python -m pip install --no-deps -r /tmp/requirements.lock.txt && \ python -m pip install --no-deps nuscenes-devkit==1.1.11 lpips==0.1.4 piq==0.8.0 # gsplat CUDA 확장을 설치 시점에 빌드 (첫 학습의 JIT 10분 방지). GPU 없이 nvcc 만으로 된다. RUN --mount=type=cache,target=/root/.cache/pip \ MAX_JOBS=8 python -m pip install --no-build-isolation gsplat==1.4.0 && \ python -c "import gsplat, torch; print('gsplat', gsplat.__version__, 'torch', torch.__version__)" # --------------------------------------------------------------- 4. 사용자 (호스트 uid/gid 와 맞춘다 — outputs/ 소유권) # /opt/conda 는 root 소유 그대로 둔다 — chown -R 은 overlay 에서 환경 수 GB 를 통째로 복사한 층을 하나 더 만든다. # 패키지를 더 넣으려면 sudo pip (사용자는 비밀번호 없는 sudo). RUN groupadd -g ${GID} ${USERNAME} && useradd -m -u ${UID} -g ${GID} -s /bin/bash ${USERNAME} && \ echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && chmod 0440 /etc/sudoers.d/${USERNAME} # NVIDIA Vulkan ICD — 컨테이너 툴킷(1.20, --gpus all)은 libGLX_nvidia 등 라이브러리는 넣어 주지만 이 JSON 은 # 넣지 않는다 (없으면 vulkaninfo 장치 0개). 라이브러리 이름만 가리키므로 드라이버 버전과 무관. RUN mkdir -p /etc/vulkan/icd.d /usr/share/glvnd/egl_vendor.d && \ printf '{"file_format_version":"1.0.0","ICD":{"library_path":"libGLX_nvidia.so.0","api_version":"1.3.242"}}\n' > /etc/vulkan/icd.d/nvidia_icd.json && \ printf '{"file_format_version":"1.0.0","ICD":{"library_path":"libEGL_nvidia.so.0"}}\n' > /usr/share/glvnd/egl_vendor.d/10_nvidia.json COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh # --------------------------------------------------------------- 5. 작업 공간 (호스트와 같은 경로) ARG WORKSPACE=/home/mm/Downloads/vkgs-sim ENV VKGS_WORKSPACE=${WORKSPACE} \ CCACHE_DIR=${WORKSPACE}/cache/ccache \ NUSCENES_ROOT=/home/mm/nas2/nuscenes_original_junhan/nuscenes/original/full RUN mkdir -p ${WORKSPACE} && chown ${UID}:${GID} ${WORKSPACE} /home/mm WORKDIR ${WORKSPACE} # 데이터를 먼저, 소스를 나중에 — 소스만 고쳐 다시 구울 때 수백 GB 층을 다시 복사하지 않게. # outputs 는 큰 폴더마다 층을 나눈다 (한 층이 수백 GB 면 내보내기 · 푸시가 다루기 어렵다). COPY --chown=${UID}:${GID} outputs/gs_day ${WORKSPACE}/outputs/gs_day COPY --chown=${UID}:${GID} outputs/aug ${WORKSPACE}/outputs/aug COPY --chown=${UID}:${GID} outputs/gs ${WORKSPACE}/outputs/gs COPY --chown=${UID}:${GID} outputs/artifixer ${WORKSPACE}/outputs/artifixer COPY --chown=${UID}:${GID} --exclude=gs_day --exclude=aug --exclude=gs --exclude=artifixer outputs ${WORKSPACE}/outputs COPY --chown=${UID}:${GID} cache ${WORKSPACE}/cache COPY --chown=${UID}:${GID} third_party ${WORKSPACE}/third_party COPY --chown=${UID}:${GID} assets ${WORKSPACE}/assets COPY --chown=${UID}:${GID} docs ${WORKSPACE}/docs COPY --chown=${UID}:${GID} --exclude=outputs --exclude=cache --exclude=third_party --exclude=assets --exclude=docs \ . ${WORKSPACE} RUN python -m pip install --no-deps --no-build-isolation -e src/nusim && chown -R ${UID}:${GID} src/nusim USER ${USERNAME} # 뷰어 · 도구 빌드 (호스트 build/ 는 컨텍스트에서 빠진다 — 호스트 conda 경로를 담은 CMake 캐시라서) RUN cmake -S src/vkgs -B build -GNinja -DCMAKE_BUILD_TYPE=Release && cmake --build build && ls build/vkgs_viewer # gsplat CUDA 확장 미리 컴파일 (pip 휠은 첫 사용 때 JIT — 컨테이너에서 처음 학습이 10분 멈추지 않게). GPU 없이 nvcc 만. RUN MAX_JOBS=4 python -c "from gsplat.cuda._backend import _C; print('gsplat ext', _C is not None)" # 10병렬은 학습과 같이 돌 때 cc1plus 가 메모리 부족으로 ICE (2026-10-17) ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["bash"]