Skip to content

Latest commit

 

History

History
370 lines (258 loc) · 8.01 KB

File metadata and controls

370 lines (258 loc) · 8.01 KB

Docker Development Environment

This Docker setup provides a complete development environment for embedded-ruby-vm without installing tools on your host machine. It uses named volumes for better performance on Windows (avoiding slow bind mounts).

Prerequisites

  • Docker Desktop installed
  • Docker Compose installed

Quick Start

1. Build the Development Container

docker-compose build

2. Sync Source Code to Volume

Copy your source code into the named volume:

docker-compose run --rm source-sync-in

3. Start Development Container

docker-compose up -d dev

4. Enter the Container

docker-compose exec dev bash

5. Build the Project

Inside the container:

# Build for your architecture (detected automatically)
./gradlew build

# Build for specific architecture
./gradlew build -PtargetArch=x86_64
./gradlew build -PtargetArch=arm64

# Build desktop JAR
./gradlew :ruby-vm-kmp:desktopJar

# Run tests
cd build
./bin/test_core
./bin/test_jni

6. Export Build Artifacts

After building, export artifacts to your host machine:

docker-compose run --rm artifact-export

Artifacts will be available in ./docker-output/ on your host machine.

Corporate/Enterprise Environments

If you're working behind a corporate proxy or need custom CA certificates, follow these steps before building the Docker image:

Setup Custom Certificates

  1. Prepare your certificates directory

    Create a directory with your certificates and installation script:

    mkdir -p docker-certs
    # Copy your certificates and install_certs.sh to docker-certs/

    Your docker-certs/ directory should contain:

    • install_certs.sh - Script to process and install certificates
    • Your certificate files (.crt, .pem, etc.)

    Important Notes

    • The directory is gitignored
    • The Dockerfile will copy this directory but only process certs if INSTALL_CUSTOM_CERTS=true
    • If no additional files are present, the build will skip certificate installation
  2. Create local override configuration

    Copy the example override file:

    cp docker-compose.override.yml.example docker-compose.override.yml
  3. Edit docker-compose.override.yml

    Uncomment and set the certificate flag:

    version: '3.8'
    
    services:
      dev:
        build:
          args:
            - INSTALL_CUSTOM_CERTS=true

    That's it! No need to configure build contexts - the Dockerfile automatically looks for ./docker-certs/ directory if INSTALL_CUSTOM_CERTS=true.

  4. Build and run

    The build will automatically detect and install your certificates:

    docker-compose build
    docker-compose run --rm source-sync-in
    docker-compose up -d dev

Proxy Configuration

If you're behind a corporate proxy, add proxy settings to your docker-compose.override.yml:

services:
  dev:
    environment:
      - HTTP_PROXY=http://proxy.company.com:8080
      - HTTPS_PROXY=http://proxy.company.com:8080
      - NO_PROXY=localhost,127.0.0.1

For Android Builds with Custom Certs

The dev-android service is available in docker-compose.override.yml.example. To use it with custom certificates:

  1. Copy the override file if you haven't already:

    cp docker-compose.override.yml.example docker-compose.override.yml
  2. Edit docker-compose.override.yml and set certificates for Android:

    services:
      dev-android:
        build:
          args:
            - INSTALL_CUSTOM_CERTS=true
  3. Build and run:

    docker-compose build dev-android
    docker-compose up -d dev-android

Important Notes

  • docker-compose.override.yml is gitignored and won't be committed
  • docker-certs/ directory is gitignored and won't be committed
  • The base docker-compose.yml works without certificates for external contributors
  • Certificates are installed at build time, not runtime
  • The Dockerfile automatically looks for ./docker-certs/ - no build contexts needed
  • If you update certificates, rebuild the image: docker-compose build --no-cache

Workflow

Initial Setup (One Time)

# Build the Docker image
docker-compose build

# Sync source code to volume
docker-compose run --rm source-sync-in

# Start the container
docker-compose up -d dev

Daily Development

# Make changes on your host machine using your favorite IDE
# ...

# Sync changes to container
docker-compose run --rm source-sync-in

# Enter container and build
docker-compose exec dev bash
./gradlew build

# Export artifacts when done
docker-compose run --rm artifact-export

Re-sync Source Code

If you make changes on your host:

docker-compose run --rm source-sync-in

Volume Management

List Volumes

docker volume ls | grep embedded-ruby

Clean Build Cache

# Remove build artifacts (keeps source and Gradle cache)
docker volume rm embedded-ruby-vm_build-artifacts
docker volume rm embedded-ruby-vm_kmp-artifacts

Clean Gradle Cache

# Remove Gradle cache (forces re-download of dependencies)
docker volume rm embedded-ruby-vm_gradle-cache

Start Fresh

# Stop containers
docker-compose down

# Remove all volumes
docker-compose down -v

# Rebuild
docker-compose build
docker-compose run --rm source-sync-in
docker-compose up -d dev

Android Builds (Optional)

For Android builds with NDK support, use the dev-android service from docker-compose.override.yml.example:

1. Setup Override File

# Copy the example override file
cp docker-compose.override.yml.example docker-compose.override.yml

# The dev-android service is already defined and ready to use!

2. Build Android Image

docker-compose build dev-android

3. Sync Source Code

docker-compose run --rm source-sync-in

4. Start Android Dev Container

docker-compose up -d dev-android

5. Build Android Artifacts

docker-compose exec dev-android bash

# Inside container:
./gradlew :ruby-vm-kmp:assembleDebug -PtargetArch=arm64
./gradlew :ruby-vm-kmp:assembleRelease -PtargetArch=all

Note: The Android image is large (~2GB) due to the Android SDK and NDK. Only build it if you need Android support.

Helpful Commands

View Container Logs

docker-compose logs -f dev

Stop Container

docker-compose down

Restart Container

docker-compose restart dev

Execute One-Off Commands

# Run a Gradle task without entering the container
docker-compose exec dev ./gradlew tasks

# Check CMake version
docker-compose exec dev cmake --version

# Check Java version
docker-compose exec dev java -version

Troubleshooting

Out of Space

# Clean up Docker resources
docker system prune -a --volumes

Gradle Daemon Issues

# Stop Gradle daemon inside container
docker-compose exec dev ./gradlew --stop

CMake Cache Issues

# Clean build directory
docker-compose exec dev rm -rf build kmp/build

Slow Build on Windows

  • Named volumes provide much better performance than bind mounts on Windows
  • First build will be slow (downloading dependencies)
  • Subsequent builds are faster due to Gradle cache volume
  • Consider increasing Docker Desktop memory allocation (Settings → Resources)

Architecture Notes

  • source-code: Named volume containing your project source code
  • gradle-cache: Named volume for Gradle dependencies and build cache
  • build-artifacts: Named volume for root build outputs
  • kmp-artifacts: Named volume for KMP module build outputs

The source-sync-in service copies from your host to the volume. The artifact-export service copies from volumes to ./docker-output/ on your host.

This approach gives you:

  • ✅ Fast builds (no bind mount overhead on Windows)
  • ✅ Isolated environment (no local tool installation)
  • ✅ Persistent caches (Gradle cache survives container restarts)
  • ✅ Easy artifact extraction (dedicated export service)