7.4 KiB
Docker Build Environment for MetalOS
This document explains how to use Docker to build MetalOS with all required dependencies pre-configured.
Why Docker?
Building MetalOS natively requires:
- Cross-compiler toolchain setup
- QEMU and UEFI firmware installation
- Dependency management (firmware blobs, Mesa RADV, QT6)
- Platform-specific configurations
Docker simplifies this by providing a pre-configured build environment that works consistently across:
- Linux (various distributions)
- macOS (with Docker Desktop)
- Windows (with Docker Desktop + WSL2)
Prerequisites
Install Docker:
- Linux: Docker Engine
- macOS/Windows: Docker Desktop
Verify installation:
docker --version
# Should output: Docker version 20.10.x or later
Quick Start
1. Build the Docker Image
From the MetalOS repository root:
./scripts/docker-build.sh
This creates a metalos-builder:latest image with:
- Ubuntu 22.04 base
- Build tools (gcc, nasm, make, cmake, meson)
- QEMU with UEFI support
- OVMF firmware
- Python3 for build scripts
Build time: ~5-10 minutes (one-time setup)
2. Setup Dependencies
Download required firmware and dependencies:
# Setup all dependencies
./scripts/docker-run.sh scripts/setup-deps.sh all
# Or setup individually
./scripts/docker-run.sh scripts/setup-deps.sh firmware # AMD GPU firmware
./scripts/docker-run.sh scripts/setup-deps.sh ovmf # UEFI firmware
This downloads:
- AMD GPU firmware blobs (dimgrey_cavefish_*.bin) from linux-firmware repository
- OVMF UEFI firmware for QEMU testing
3. Build MetalOS
Build the bootloader and kernel:
./scripts/docker-run.sh make all
4. Test in QEMU
Run MetalOS in QEMU with UEFI firmware:
# Headless mode (serial console only)
./scripts/docker-run.sh make qemu
# With debug output
./scripts/docker-run.sh make qemu-debug
# Test UEFI firmware setup
./scripts/docker-run.sh make qemu-uefi-test
Common Tasks
Interactive Shell
Get a bash shell inside the container:
./scripts/docker-run.sh /bin/bash
From the shell, you can run any commands:
# Inside container
make all
make test
make qemu
scripts/setup-deps.sh firmware
Exit with exit or Ctrl+D.
Clean Build
./scripts/docker-run.sh make clean
Run Unit Tests
./scripts/docker-run.sh make test
View Dependency Status
./scripts/docker-run.sh ls -la deps/firmware/
./scripts/docker-run.sh cat deps/firmware/VERSION
Advanced Usage
Custom Docker Image Name
Edit scripts/docker-build.sh and scripts/docker-run.sh to change:
IMAGE_NAME="my-custom-name"
IMAGE_TAG="v1.0"
Rebuild Docker Image
After updating Dockerfile:
./scripts/docker-build.sh
Docker will cache layers and only rebuild changed parts.
Running Specific Commands
The docker-run.sh script accepts any command:
# Run specific make target
./scripts/docker-run.sh make kernel
# Check QEMU version
./scripts/docker-run.sh qemu-system-x86_64 --version
# List files
./scripts/docker-run.sh ls -la build/
# Run a script
./scripts/docker-run.sh ./scripts/create_image.sh
Volume Mounts
The source directory is mounted at /metalos inside the container:
- Changes made in the container are reflected on the host
- Build artifacts created in the container are accessible on the host
- No need to copy files in/out of the container
GPU Access (Future)
For testing with host GPU (when GPU driver is implemented):
docker run --rm -it \
--device=/dev/dri \
-v "$(pwd):/metalos" \
metalos-builder:latest \
/bin/bash
Troubleshooting
Docker Permission Denied
On Linux, add your user to the docker group:
sudo usermod -aG docker $USER
# Log out and back in
Cannot Connect to Docker Daemon
Ensure Docker daemon is running:
sudo systemctl start docker # Linux
# Or start Docker Desktop # macOS/Windows
Build Fails with "No Space Left"
Docker has run out of disk space. Clean up:
docker system prune -a
Container Files Owned by Root
This is normal. To change ownership:
sudo chown -R $USER:$USER build/
Or use Docker with user mapping:
docker run --rm -it \
--user $(id -u):$(id -g) \
-v "$(pwd):/metalos" \
metalos-builder:latest \
/bin/bash
QEMU Display Issues
Docker containers run headless by default. For graphical QEMU:
- On Linux with X11:
docker run --rm -it \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v "$(pwd):/metalos" \
metalos-builder:latest \
make qemu QEMU_DISPLAY=gtk
-
On macOS/Windows: Use VNC or serial console instead
-
For now, use headless mode:
./scripts/docker-run.sh make qemu QEMU_DISPLAY=none
CI/CD Integration
GitHub Actions
Example workflow:
name: Docker Build
on: [push, pull_request]
jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: ./scripts/docker-build.sh
- name: Setup dependencies
run: ./scripts/docker-run.sh scripts/setup-deps.sh all
- name: Build MetalOS
run: ./scripts/docker-run.sh make all
- name: Run tests
run: ./scripts/docker-run.sh make test
GitLab CI
build:
image: docker:latest
services:
- docker:dind
script:
- ./scripts/docker-build.sh
- ./scripts/docker-run.sh make all
- ./scripts/docker-run.sh make test
Docker Image Contents
The metalos-builder image includes:
Build Tools
- gcc, g++, make, cmake, ninja, meson
- nasm (assembler)
- binutils (ld, as, objcopy, etc.)
- pkg-config
Testing Tools
- qemu-system-x86_64
- OVMF UEFI firmware
- mtools, xorriso (image creation)
Utilities
- git, wget, curl
- Python3
- vim, less, file
Directory Structure
/metalos/
├── deps/ # Dependencies (mounted from host)
│ ├── firmware/ # AMD GPU firmware blobs
│ ├── ovmf/ # UEFI firmware
│ ├── mesa-radv/ # Mesa RADV driver
│ └── qt6/ # QT6 framework
├── bootloader/ # UEFI bootloader source
├── kernel/ # Kernel source
├── scripts/ # Build scripts
└── build/ # Build artifacts
Next Steps
After setting up the Docker environment:
- Review docs/BUILD.md for detailed build instructions
- Check docs/DEVELOPMENT.md for development workflow
- See docs/TESTING.md for testing procedures
- Read deps/README.md for dependency details
Comparison: Docker vs Native Build
| Aspect | Docker Build | Native Build |
|---|---|---|
| Setup Time | 5-10 minutes (one-time) | 1-2 hours (toolchain setup) |
| Platform Support | Linux, macOS, Windows | Linux (primary), macOS (limited) |
| Consistency | Identical across platforms | Platform-dependent |
| Isolation | Complete isolation | Uses system tools |
| Disk Space | ~2GB for image | ~500MB for tools |
| Performance | Slight overhead | Native speed |
| CI/CD | Easy integration | Platform-specific config |
Getting Help
- Documentation: Check docs/ directory
- Issues: GitHub Issues
- Discussions: Use GitHub Discussions for questions