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).
- Docker Desktop installed
- Docker Compose installed
docker-compose buildCopy your source code into the named volume:
docker-compose run --rm source-sync-indocker-compose up -d devdocker-compose exec dev bashInside 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_jniAfter building, export artifacts to your host machine:
docker-compose run --rm artifact-exportArtifacts will be available in ./docker-output/ on your host machine.
If you're working behind a corporate proxy or need custom CA certificates, follow these steps before building the Docker image:
-
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.)
- 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
-
Create local override configuration
Copy the example override file:
cp docker-compose.override.yml.example docker-compose.override.yml
-
Edit
docker-compose.override.ymlUncomment 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 ifINSTALL_CUSTOM_CERTS=true. -
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
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.1The dev-android service is available in docker-compose.override.yml.example.
To use it with custom certificates:
-
Copy the override file if you haven't already:
cp docker-compose.override.yml.example docker-compose.override.yml
-
Edit
docker-compose.override.ymland set certificates for Android:services: dev-android: build: args: - INSTALL_CUSTOM_CERTS=true
-
Build and run:
docker-compose build dev-android docker-compose up -d dev-android
docker-compose.override.ymlis gitignored and won't be committeddocker-certs/directory is gitignored and won't be committed- The base
docker-compose.ymlworks 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
# 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# 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-exportIf you make changes on your host:
docker-compose run --rm source-sync-indocker volume ls | grep embedded-ruby# Remove build artifacts (keeps source and Gradle cache)
docker volume rm embedded-ruby-vm_build-artifacts
docker volume rm embedded-ruby-vm_kmp-artifacts# Remove Gradle cache (forces re-download of dependencies)
docker volume rm embedded-ruby-vm_gradle-cache# 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 devFor Android builds with NDK support, use the dev-android service from docker-compose.override.yml.example:
# 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!docker-compose build dev-androiddocker-compose run --rm source-sync-indocker-compose up -d dev-androiddocker-compose exec dev-android bash
# Inside container:
./gradlew :ruby-vm-kmp:assembleDebug -PtargetArch=arm64
./gradlew :ruby-vm-kmp:assembleRelease -PtargetArch=allNote: The Android image is large (~2GB) due to the Android SDK and NDK. Only build it if you need Android support.
docker-compose logs -f devdocker-compose downdocker-compose restart dev# 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# Clean up Docker resources
docker system prune -a --volumes# Stop Gradle daemon inside container
docker-compose exec dev ./gradlew --stop# Clean build directory
docker-compose exec dev rm -rf build kmp/build- 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)
- 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)