Files
MetalOS/docs/DOCKER.md
2025-12-28 19:22:36 +00:00

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:

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:

  1. 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
  1. On macOS/Windows: Use VNC or serial console instead

  2. 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:

  1. Review docs/BUILD.md for detailed build instructions
  2. Check docs/DEVELOPMENT.md for development workflow
  3. See docs/TESTING.md for testing procedures
  4. 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