Zero-config buildpacks for 14 languages. No Dockerfile needed.
10K+
Auto-detecting buildpacks for container images - automatically detects your language, version, and builds optimized container images using official upstream Docker images.
Built by miget.com - Unlimited apps, one price.
migetpacks runs Docker-in-Docker using BuildKit for optimized multi-stage builds. It requires access to the Docker socket (/var/run/docker.sock).
# Verify Docker is running
docker info
# Verify BuildKit is available
docker buildx version
# Build your app
docker run --rm \
-v /path/to/your/app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
miget/migetpacks:latest
# Run your app
docker run -p 5000:5000 my-app:latest
For ephemeral ubuntu-latest runners, use registry-based caching via CACHE_IMAGE:
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Required for CACHE_IMAGE support
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push with migetpacks
run: |
docker run --rm \
-v ${{ github.workspace }}:/workspace/source:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/runner/.docker/config.json:/root/.docker/config.json:ro \
-e OUTPUT_IMAGE=ghcr.io/${{ github.repository }}:${{ github.sha }} \
-e CACHE_IMAGE=ghcr.io/${{ github.repository }}:cache \
miget/migetpacks:latest
For persistent self-hosted runners, use local file cache via BUILD_CACHE_DIR:
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: registry.example.com
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push with migetpacks
run: |
docker run --rm \
-v ${{ github.workspace }}:/workspace/source:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/.docker/config.json:/root/.docker/config.json:ro \
-v /var/cache/migetpacks:/cache \
-e OUTPUT_IMAGE=registry.example.com/my-app:${{ github.sha }} \
-e BUILD_CACHE_DIR=/cache \
miget/migetpacks:latest
Cache options:
CACHE_IMAGE - Registry-based BuildKit layer cache. Requires docker/setup-buildx-action. Works on ephemeral runners.BUILD_CACHE_DIR - Local directory for package manager caches (npm, pip, bundler, etc.). Best for persistent self-hosted runners.| Language | Detection | Version Source |
|---|---|---|
| Node.js | package.json | .nvmrc, .node-version, package.json |
| Deno | deno.json, deno.jsonc | deno.json |
| Bun | bun.lockb, bunfig.toml | package.json |
| Python | requirements.txt, Pipfile, pyproject.toml | .python-version, runtime.txt |
| Ruby | Gemfile | .ruby-version, Gemfile |
| Go | go.mod | go.mod |
| Rust | Cargo.toml | Cargo.toml |
| PHP | composer.json, index.php | composer.json |
| Java | pom.xml, build.gradle | pom.xml, .java-version, system.properties |
| Kotlin | build.gradle.kts | system.properties |
| Scala | build.sbt | system.properties |
| Clojure | project.clj, deps.edn | system.properties |
| .NET | *.csproj, *.fsproj | global.json, *.csproj |
| Elixir | mix.exs | mix.exs, .elixir-version |
| Dockerfile | Dockerfile | - |
| Compose | compose.yaml, docker-compose.yml | - |
| Variable | Required | Default | Description |
|---|---|---|---|
OUTPUT_IMAGE | Yes | - | Target image name (e.g., ghcr.io/user/app:tag) |
SOURCE_DIR | No | /workspace/source | Source code directory |
LANGUAGE | No | auto-detected | Force language (see values below) |
RUN_COMMAND | No | from Procfile | Override the run command |
PORT | No | 5000 | Application port |
ARCH | No | x86_64 | Target architecture (x86_64, arm64) |
PROJECT_PATH | No | - | Subdirectory for monorepo builds |
BUILDPACKS | No | auto-detected | Explicit buildpack order (e.g., ruby,nodejs) |
DOCKERFILE_PATH | No | - | Custom Dockerfile path (forces dockerfile language) |
COMPOSE_FILE | No | - | Custom compose file path (forces compose language) |
RESULT_FILE | No | - | Path to write build results JSON |
STORAGE_DRIVER | No | overlay2 | Docker storage driver (e.g., fuse-overlayfs for nested DinD) |
| Variable | Required | Default | Description |
|---|---|---|---|
CACHE_IMAGE | No | - | Registry image for BuildKit cache |
CACHE_MODE | No | min | BuildKit cache export mode: min (final layer) or max (all layers) |
CACHE_FROM | No | - | Additional read-only cache sources (comma-separated registry refs) |
CACHE_REGISTRY_INSECURE | No | false | Set to true for HTTP registries |
NO_CACHE | No | false | Force fresh build, skips cache-from |
BUILD_CACHE_DIR | No | - | Directory for package manager cache |
REGISTRY_MIRROR | No | - | Docker registry mirror URL |
| Variable | Required | Default | Description |
|---|---|---|---|
USE_DHI | No | false | Use Docker Hardened Images from dhi.io |
DHI_USERNAME | No | - | DHI registry username (alternative to mounting docker config) |
DHI_PASSWORD | No | - | DHI registry password/token |
DHI_MIRROR | No | - | DHI registry mirror URL |
Any environment variable passed to migetpacks that is not a known configuration variable will be automatically injected into the generated Dockerfile as ENV statements. This allows you to pass custom build-time settings without modifying migetpacks.
# Pass NODE_OPTIONS to increase heap size for large builds
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e NODE_OPTIONS="--max-old-space-size=4096" \
miget/migetpacks:latest
# Pass multiple custom variables
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e NODE_OPTIONS="--max-old-space-size=4096" \
-e VITE_API_URL="https://api.example.com" \
-e MY_BUILD_FLAG="true" \
miget/migetpacks:latest
Common use cases:
NODE_OPTIONS="--max-old-space-size=4096" - Increase Node.js heap for large buildsVITE_* / NEXT_PUBLIC_* - Frontend build-time variablesRAILS_MASTER_KEY - Rails credentials key for asset precompilationNote: Sensitive variables like AWS_* credentials and Docker configuration are automatically filtered out and never injected into the Dockerfile.
Force a specific language by setting LANGUAGE:
| Value | Description |
|---|---|
nodejs | Node.js (npm, yarn, pnpm) |
deno | Deno runtime |
bun | Bun runtime |
python | Python (pip, uv) |
ruby | Ruby (bundler) |
go | Go |
rust | Rust (cargo) |
php | PHP (FrankenPHP + Composer) |
java | Java (Maven or Gradle) |
kotlin | Kotlin (Gradle) |
scala | Scala (sbt) |
clojure | Clojure (Leiningen) |
.net or dotnet | .NET / C# |
elixir | Elixir (Mix) |
dockerfile | Use project's Dockerfile directly |
compose | Build all services from compose.yaml |
Define processes in a Procfile:
web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq
release: bundle exec rails db:migrate
Priority order:
RUN_COMMAND environment variableweb: process from ProcfileBuild apps with multiple languages:
# Ruby app with Node.js for asset compilation
docker run --rm \
-v ./my-rails-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-rails-app:latest \
-e BUILDPACKS=ruby,nodejs \
miget/migetpacks:latest
Use minimal, CVE-free Docker Hardened Images:
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e USE_DHI=true \
miget/migetpacks:latest
DHI images are distroless (no shell, no apt-get) with minimal attack surface.
Docker Desktop stores credentials in the system keychain, not in ~/.docker/config.json. Extract credentials and pass them as environment variables:
# Extract credentials from Docker Desktop keychain
DHI_USERNAME=$(echo "dhi.io" | docker-credential-desktop get | jq -r '.Username')
DHI_PASSWORD=$(echo "dhi.io" | docker-credential-desktop get | jq -r '.Secret')
# Build with DHI
docker run --rm \
-v "$(pwd):/workspace/source:ro" \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:local \
-e ARCH=arm64 \
-e USE_DHI=true \
-e DHI_USERNAME="$DHI_USERNAME" \
-e DHI_PASSWORD="$DHI_PASSWORD" \
miget/migetpacks:latest
migetpacks prioritizes its optimized builds for known languages. A Dockerfile is only used as a fallback when no supported language is detected. To force your Dockerfile, use LANGUAGE=dockerfile:
# Force Dockerfile mode (recommended when you have both language files and Dockerfile)
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e LANGUAGE=dockerfile \
miget/migetpacks:latest
# Fallback behavior (uses Dockerfile only if no language detected)
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
miget/migetpacks:latest
# Use custom Dockerfile path
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e DOCKERFILE_PATH=docker/Dockerfile.prod \
miget/migetpacks:latest
Multi-service builds from compose.yaml:
# compose.yaml
services:
api:
build: ./api
web:
build: ./web
# Auto-detect compose file
docker run --rm \
-v ./my-project:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=ghcr.io/user/myproject:latest \
miget/migetpacks:latest
# Builds: ghcr.io/user/myproject-api:latest, ghcr.io/user/myproject-web:latest
# Force compose mode
docker run --rm \
-v ./my-project:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=ghcr.io/user/myproject:latest \
-e LANGUAGE=compose \
miget/migetpacks:latest
Build a specific subdirectory:
docker run --rm \
-v ./monorepo:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e PROJECT_PATH=services/api \
-e OUTPUT_IMAGE=my-api:latest \
miget/migetpacks:latest
Mount a cache directory for npm, pip, bundler, cargo, etc.:
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /path/to/cache:/cache \
-e OUTPUT_IMAGE=my-app:latest \
-e BUILD_CACHE_DIR=/cache \
miget/migetpacks:latest
Use BuildKit's registry-based caching for Docker layer caching:
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=ghcr.io/user/my-app:latest \
-e CACHE_IMAGE=ghcr.io/user/my-app-cache \
miget/migetpacks:latest
When pushing to private registries, migetpacks needs access to your Docker credentials. Since migetpacks runs inside a container, you must mount the Docker config directory.
# Log in to your registry first
docker login registry.example.com
# Mount the docker config so migetpacks can push
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.docker/config.json:/root/.docker/config.json:ro \
-e OUTPUT_IMAGE=registry.example.com/my-app:latest \
miget/migetpacks:latest
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: registry.example.com
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push with migetpacks
run: |
docker run --rm \
-v ${{ github.workspace }}:/workspace/source:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/runner/.docker/config.json:/root/.docker/config.json:ro \
-e OUTPUT_IMAGE=registry.example.com/my-app:${{ github.sha }} \
-e CACHE_IMAGE=registry.example.com/my-app:cache \
miget/migetpacks:latest
Key points:
config.json file only (buildx needs to create state in .docker/buildx/):ro (read-only) for the config file/home/runner/.docker/config.json$HOME/.docker/config.jsonGet structured JSON output for CI/CD pipelines:
docker run --rm \
-v ./my-app:/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /tmp/results:/output \
-e OUTPUT_IMAGE=my-app:latest \
-e RESULT_FILE=/output/result.json \
miget/migetpacks:latest
cat /tmp/results/result.json
{
"status": "success",
"images": [{"name": "my-app:latest", "ports": ["5000/tcp"]}],
"processes": {"web": "node server.js"},
"language": "nodejs",
"build_time": 45
}
Working examples for all languages in examples/:
nodejs-example, deno-example, bun-examplepython-example, ruby-example, php-hello-worldgo-hello-world, rust-examplejava-hello-world, kotlin-example, scala-exampledotnet-hello-world, elixir-exampledockerfile-example, compose-example# Run detection tests
make test-detect
# Build the container locally
make build
# Test a language build
make test-nodejs
make test-python
make test-go
migetpacks is built by miget.com - unlimited apps, one price. We use migetpacks to build customer apps with zero configuration.
O'Saasy License (Modified for Cloud/PaaS) - see LICENSE for details.
Content type
Image
Digest
sha256:965dcc1ee…
Size
288.7 MB
Last updated
10 days ago
docker pull miget/migetpacks