Docker Development#
ACloudViewer provides comprehensive Docker support for development, testing, and deployment.
Overview#
Docker images are available for:
Documentation Building: Generate docs in isolated environment
CI/CD Testing: Automated builds and tests
Wheel Building: Create Python wheels for distribution
Development: Consistent development environment
GPU Support: CUDA-enabled builds and testing
Prerequisites#
Docker Installation#
Install Docker Engine:
# Ubuntu
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Verify installation
docker run --rm hello-world
Post-installation (Linux):
# Add user to docker group (run without sudo)
sudo usermod -aG docker $USER
newgrp docker
# Verify
docker run --rm hello-world # Should work without sudo
NVIDIA Docker (GPU Support)#
Required for CUDA builds and GPU testing:
# Install NVIDIA Container Toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
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/$distribution/libnvidia-container.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
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
# Verify GPU access
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
ARM64 Support (Optional)#
For building ARM64 images on x86-64 hosts:
# Install QEMU
sudo apt-get install -y qemu binfmt-support qemu-user-static
# Register ARM64 interpreter
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# Verify ARM64 support
docker run --rm arm64v8/ubuntu:22.04 uname -m
# Should output: aarch64
Available Docker Images#
Documentation Build Image#
Dockerfile: docker/Dockerfile.docs
Purpose: Build comprehensive documentation (Sphinx + Doxygen) in an isolated environment.
Features:
Ubuntu 22.04 base
Python 3.11 with all doc dependencies
Qt5 support (for GUI documentation)
CloudViewer-ML integration
Doxygen, Pandoc, Sphinx
Automatic Python module detection and build
Build:
# Development build (with git hash)
docker build \
--build-arg DEVELOPER_BUILD=ON \
-t acloudviewer-ci:docs \
-f docker/Dockerfile.docs .
# Release build (with version number)
docker build \
--build-arg DEVELOPER_BUILD=OFF \
-t acloudviewer-ci:docs \
-f docker/Dockerfile.docs .
Extract Documentation:
# Extract documentation tarball
docker run -v $(pwd):/opt/mount --rm acloudviewer-ci:docs \
bash -c "cp /root/ACloudViewer/acloudviewer-*-docs.tar.gz /opt/mount/"
# Unpack and preview
mkdir -p docs-preview
tar -xzf acloudviewer-*-docs.tar.gz -C ./docs-preview/
cd docs-preview && python3 -m http.server 8080
# Open http://localhost:8080
What It Builds:
Python module (if not present)
C++ API documentation (Doxygen)
Python API documentation (Sphinx autodoc)
Jupyter notebook tutorials (nbsphinx)
Unified HTML documentation
CI/CD Build Image#
Dockerfile: docker/Dockerfile.ci
Purpose: Automated CI/CD builds and testing.
Variants:
Variant |
Base Image |
Use Case |
|---|---|---|
CPU Static |
|
Static libraries, minimal dependencies |
CPU Shared |
|
Shared libraries with ML support |
CUDA Shared |
|
GPU-accelerated builds |
Qt6 CPU |
|
Qt6-based GUI builds |
Qt6 CUDA |
|
Qt6 + GPU builds |
Build Examples:
# CPU static build
docker build \
-f docker/Dockerfile.ci \
--build-arg BASE_IMAGE=ubuntu:22.04 \
--build-arg DEVELOPER_BUILD=ON \
--build-arg BUILD_SHARED_LIBS=OFF \
-t acloudviewer-ci:cpu-static .
# CUDA shared build with ML
docker build \
-f docker/Dockerfile.ci \
--build-arg BASE_IMAGE=nvidia/cuda:12.1.0-devel-ubuntu22.04 \
--build-arg DEVELOPER_BUILD=ON \
--build-arg BUILD_SHARED_LIBS=ON \
--build-arg BUILD_CUDA_MODULE=ON \
--build-arg BUILD_PYTORCH_OPS=ON \
-t acloudviewer-ci:cuda-ml .
Using Build Scripts:
cd docker
# See all available configurations
./docker_build.sh --help
# Build CPU variant
./docker_build.sh cpu-static
# Build CUDA variant with ML
./docker_build.sh cuda-ml-shared-jammy
# Build Qt6 variant
./docker_build_qt6.sh qt6-cpu-static
Qt6 Build Image#
Dockerfile: docker/Dockerfile.ci.qt6
Purpose: Build with Qt6 support (Ubuntu 24.04+).
Features:
Qt6 base libraries
Qt6 WebSockets
Qt6 networking
Modern CMake (3.28+)
Build:
docker build \
-f docker/Dockerfile.ci.qt6 \
--build-arg BASE_IMAGE=ubuntu:24.04 \
--build-arg DEVELOPER_BUILD=ON \
-t acloudviewer-ci:qt6 .
Wheel Building Image#
Dockerfiles:
docker/Dockerfile.wheel(Qt5, Ubuntu 20.04/22.04)docker/Dockerfile.wheel.qt6(Qt6, Ubuntu 24.04)
Purpose: Build manylinux-compatible Python wheels.
Python Versions: 3.10, 3.11, 3.12, 3.13
Build:
# Build wheel with CUDA support
docker build \
-f docker/Dockerfile.wheel \
--build-arg BASE_IMAGE=ubuntu:22.04 \
--build-arg PYTHON_VERSION=3.11 \
--build-arg BUILD_CUDA_MODULE=ON \
--build-arg BUILD_PYTORCH_OPS=ON \
-t acloudviewer-wheel:cuda-py311 .
# Extract wheel
docker run -v $(pwd):/opt/mount --rm acloudviewer-wheel:cuda-py311 \
bash -c "cp /root/ACloudViewer/build/lib/python_package/pip_package/*.whl /opt/mount/"
Using Build Scripts:
cd docker
# Build wheel for Python 3.11
./build_cloudviewer_whl.sh 3.11
# Build all Python versions
./build-all.sh
# Build release wheels
./build-release.sh
Using Docker Images#
Interactive Development#
Launch an interactive shell for development:
# CPU environment
docker run -it --rm \
-v $(pwd):/workspace \
-w /workspace \
acloudviewer-ci:cpu-static \
bash
# Inside container
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
ctest --output-on-failure
With GPU support:
docker run -it --rm --gpus all \
-v $(pwd):/workspace \
-w /workspace \
acloudviewer-ci:cuda-ml \
bash
# Build with CUDA
mkdir build && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_CUDA_MODULE=ON \
-DBUILD_PYTORCH_OPS=ON
make -j$(nproc)
Running Tests#
Run the complete test suite in Docker:
C++ Unit Tests:
docker run --rm \
-v $(pwd):/workspace \
-w /workspace/build \
acloudviewer-ci:cpu-static \
bash -c "ctest --output-on-failure"
Python Tests:
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
acloudviewer-ci:cpu-static \
bash -c "source util/ci_utils.sh && run_python_tests path/to/wheel.whl"
GPU Tests:
docker run --rm --gpus all \
-v $(pwd):/workspace \
-w /workspace/build \
acloudviewer-ci:cuda-ml \
bash -c "ctest --output-on-failure -R GPU"
Using Test Script:
cd docker
# Test CPU build
./docker_test.sh cpu-static
# Test CUDA build
./docker_test.sh cuda-ml-shared-jammy
# Test Qt6 build
./docker_test.sh qt6-cpu-static
Building Wheels#
Build Python wheels inside Docker:
# Using ci_utils.sh
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
acloudviewer-wheel:cuda-py311 \
bash -c "source util/ci_utils.sh && build_pip_package"
# Extract wheel
docker cp $(docker ps -lq):/root/ACloudViewer/dist ./
Test wheel installation:
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
python:3.11-slim \
bash -c "pip install dist/*.whl && python -c 'import cloudViewer; print(cloudViewer.__version__)'"
Build Arguments#
Common Build Arguments#
Argument |
Default |
Description |
|---|---|---|
|
|
Base Docker image |
|
|
Enable dev features (git hash in version) |
|
|
Python version (3.10-3.13) |
|
|
CMake version |
|
|
Build shared libraries |
|
|
Enable CUDA support |
|
|
Build PyTorch operators |
|
|
Build TensorFlow operators |
|
|
Build GUI components |
|
(none) |
ccache archive for faster rebuilds |
Example with all arguments:
docker build \
--build-arg BASE_IMAGE=nvidia/cuda:12.1.0-devel-ubuntu22.04 \
--build-arg DEVELOPER_BUILD=OFF \
--build-arg PYTHON_VERSION=3.11 \
--build-arg CMAKE_VERSION=3.28.1 \
--build-arg BUILD_SHARED_LIBS=ON \
--build-arg BUILD_CUDA_MODULE=ON \
--build-arg BUILD_PYTORCH_OPS=ON \
--build-arg BUILD_TENSORFLOW_OPS=OFF \
--build-arg BUILD_GUI=ON \
-t acloudviewer:custom \
-f docker/Dockerfile.ci .
Dockerfile Structure#
Typical Multi-Stage Dockerfile#
ACloudViewer Dockerfiles use multi-stage builds for efficiency:
# Stage 1: Base dependencies
FROM ubuntu:22.04 AS base
RUN apt-get update && apt-get install -y \
build-essential cmake git
# Stage 2: Build stage
FROM base AS builder
COPY . /workspace
WORKDIR /workspace
RUN mkdir build && cd build && \
cmake .. -DCMAKE_BUILD_TYPE=Release && \
make -j$(nproc)
# Stage 3: Runtime stage (smaller)
FROM ubuntu:22.04 AS runtime
COPY --from=builder /workspace/build/lib /usr/local/lib
COPY --from=builder /workspace/build/bin /usr/local/bin
RUN ldconfig
Benefits:
Smaller final image (no build tools)
Faster subsequent builds (cached layers)
Reproducible builds
Layer Optimization#
Order Dockerfile commands from least to most frequently changing:
# 1. System packages (rarely change)
RUN apt-get update && apt-get install -y \
build-essential cmake git
# 2. Python dependencies (occasional changes)
COPY requirements.txt .
RUN pip install -r requirements.txt
# 3. Third-party dependencies (infrequent changes)
COPY 3rdparty/ /workspace/3rdparty/
RUN cd /workspace/3rdparty && ./build_deps.sh
# 4. Source code (frequent changes)
COPY . /workspace
Caching Strategies#
BuildKit Cache#
Use Docker BuildKit for advanced caching:
# Enable BuildKit
export DOCKER_BUILDKIT=1
# Build with cache
docker build \
--cache-from acloudviewer-ci:cpu-static \
-t acloudviewer-ci:cpu-static \
-f docker/Dockerfile.ci .
# Use GitHub Actions cache
docker build \
--cache-from type=gha \
--cache-to type=gha,mode=max \
-t acloudviewer-ci:cpu-static \
-f docker/Dockerfile.ci .
ccache Integration#
Leverage ccache for C++ compilation:
# Create ccache volume
docker volume create ccache-vol
# Run with ccache volume
docker run --rm \
-v ccache-vol:/root/.cache/ccache \
-v $(pwd):/workspace \
acloudviewer-ci:cpu-static \
bash -c "ccache -M 5G && cd /workspace/build && make -j$(nproc)"
# Check ccache statistics
docker run --rm \
-v ccache-vol:/root/.cache/ccache \
acloudviewer-ci:cpu-static \
ccache -s
Benefits:
First build: ~45 min
Cached build: ~8 min (5.6x speedup)
Docker Compose#
For multi-container development setups:
docker-compose.yml:
version: '3.8'
services:
acloudviewer-dev:
build:
context: .
dockerfile: docker/Dockerfile.ci
args:
BASE_IMAGE: ubuntu:22.04
DEVELOPER_BUILD: 'ON'
BUILD_SHARED_LIBS: 'OFF'
volumes:
- .:/workspace
- ccache-vol:/root/.cache/ccache
working_dir: /workspace
command: bash
stdin_open: true
tty: true
acloudviewer-cuda:
build:
context: .
dockerfile: docker/Dockerfile.ci
args:
BASE_IMAGE: nvidia/cuda:12.1.0-devel-ubuntu22.04
DEVELOPER_BUILD: 'ON'
BUILD_CUDA_MODULE: 'ON'
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
volumes:
- .:/workspace
working_dir: /workspace
command: bash
stdin_open: true
tty: true
volumes:
ccache-vol:
Usage:
# Start services
docker-compose up -d
# Enter CPU container
docker-compose exec acloudviewer-dev bash
# Enter CUDA container
docker-compose exec acloudviewer-cuda bash
# Stop services
docker-compose down
Testing with Docker#
Complete Test Suite#
The docker_test.sh script runs comprehensive tests:
cd docker
# List available test configurations
./docker_test.sh
# Run CPU tests
./docker_test.sh cpu-static
# Run CUDA tests
./docker_test.sh cuda-ml-shared-jammy
# Run Qt6 tests
./docker_test.sh qt6-cpu-static
Test Workflow:
Build C++ unit tests
Run C++ tests with gtest
Build Python package
Install Python package
Run Python tests with pytest
Test command-line tools
Test CMake integration
Test uninstall process
Custom Test Runs#
Run specific test suites:
# C++ tests only
docker run --rm acloudviewer-ci:cpu-static \
bash -c "cd build && ./bin/tests"
# Python tests only
docker run --rm acloudviewer-ci:cpu-static \
bash -c "cd python/test && pytest -v"
# Specific test file
docker run --rm acloudviewer-ci:cpu-static \
bash -c "cd python/test && pytest test_pointcloud.py -v"
# With GPU
docker run --rm --gpus all acloudviewer-ci:cuda-ml \
bash -c "cd build && ./bin/tests --gtest_filter=*CUDA*"
Troubleshooting#
Permission Issues#
Run Docker as current user to avoid permission issues:
docker run --rm \
--user $(id -u):$(id -g) \
-v $(pwd):/workspace \
acloudviewer-ci:cpu-static
Fix existing permission issues:
# Fix ownership of build artifacts
docker run --rm \
-v $(pwd):/workspace \
ubuntu:22.04 \
chown -R $(id -u):$(id -g) /workspace/build
Out of Memory#
Limit parallel builds and memory usage:
# Limit to 4 parallel jobs
docker run --rm \
-m 8g \
--cpus 4 \
-v $(pwd):/workspace \
acloudviewer-ci:cpu-static \
bash -c "make -j4"
# Monitor memory usage
docker stats
Out of Disk Space#
Clean up Docker resources:
# Remove unused containers
docker container prune -f
# Remove unused images
docker image prune -a -f
# Remove build cache
docker builder prune -a -f
# Remove volumes
docker volume prune -f
# Clean everything
docker system prune -a --volumes -f
Check disk usage:
# Docker disk usage
docker system df
# Detailed breakdown
docker system df -v
Network Issues#
Use host network for better connectivity:
docker build --network=host \
-t acloudviewer-ci:cpu-static \
-f docker/Dockerfile.ci .
Proxy configuration:
docker build \
--build-arg http_proxy=$http_proxy \
--build-arg https_proxy=$https_proxy \
--build-arg no_proxy=$no_proxy \
-t acloudviewer-ci:cpu-static \
-f docker/Dockerfile.ci .
GPU Not Available#
Verify NVIDIA Docker:
# Check NVIDIA driver
nvidia-smi
# Check NVIDIA Docker runtime
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
# Restart Docker daemon
sudo systemctl restart docker
Common fixes:
# Update NVIDIA Container Toolkit
sudo apt-get update
sudo apt-get install --reinstall nvidia-container-toolkit
sudo systemctl restart docker
# Configure runtime
sudo tee /etc/docker/daemon.json <<EOF
{
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
}
}
EOF
sudo systemctl restart docker
Best Practices#
Use Specific Base Images
Pin versions for reproducibility:
FROM ubuntu:22.04 # Good # FROM ubuntu:latest # Bad (unpredictable)
Minimize Layers
Combine related RUN commands:
# Good RUN apt-get update && \ apt-get install -y pkg1 pkg2 && \ rm -rf /var/lib/apt/lists/* # Bad RUN apt-get update RUN apt-get install -y pkg1 RUN apt-get install -y pkg2
Clean Up in Same Layer
Remove temporary files before layer commit:
RUN apt-get update && \ apt-get install -y build-essential && \ # ... build steps ... && \ apt-get purge -y build-essential && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/*
Use .dockerignore
Exclude unnecessary files from build context:
# .dockerignore **/.git **/build **/build_* **/__pycache__ **/*.pyc **/.pytest_cache **/docs/_out **/node_modules **/.vscode **/.idea
Multi-Stage Builds
Separate build and runtime stages:
FROM ubuntu:22.04 AS builder # ... build steps ... FROM ubuntu:22.04 AS runtime COPY --from=builder /build/output /usr/local
Health Checks
Add health checks for long-running containers:
HEALTHCHECK --interval=30s --timeout=3s \ CMD python -c "import cloudViewer" || exit 1
Non-Root User
Run as non-root for security:
RUN useradd -m -s /bin/bash acloudviewer USER acloudviewer
Resources#
Docker Documentation: https://docs.docker.com/
Best Practices: https://docs.docker.com/develop/dev-best-practices/
BuildKit: https://github.com/moby/buildkit
NVIDIA Container Toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/
CI/CD Pipeline - CI/CD integration
Contributing to ACloudViewer - Contributing guidelines
docker/ Directory - Docker scripts and Dockerfiles
Quick Reference#
Build Images:
# Documentation
docker build -t acloudviewer-ci:docs -f docker/Dockerfile.docs .
# CPU CI
docker build -t acloudviewer-ci:cpu -f docker/Dockerfile.ci .
# CUDA CI
docker build -t acloudviewer-ci:cuda \
--build-arg BASE_IMAGE=nvidia/cuda:12.1.0-devel-ubuntu22.04 \
-f docker/Dockerfile.ci .
# Qt6
docker build -t acloudviewer-ci:qt6 -f docker/Dockerfile.ci.qt6 .
# Wheel
docker build -t acloudviewer-wheel:py311 \
--build-arg PYTHON_VERSION=3.11 \
-f docker/Dockerfile.wheel .
Run Tests:
# Using test script
cd docker && ./docker_test.sh cpu-static
# Manual
docker run --rm acloudviewer-ci:cpu \
bash -c "cd build && ctest --output-on-failure"
Build Wheels:
# Using build script
cd docker && ./build_cloudviewer_whl.sh 3.11
# Manual
docker run --rm -v $(pwd):/opt/mount acloudviewer-wheel:py311 \
bash -c "cp /root/ACloudViewer/dist/*.whl /opt/mount/"
Clean Up:
# Remove all
docker system prune -a --volumes -f
# Check space
docker system df