https://github.com/migetapp/migetpacks
Zero-config container builds for 14 languages. Auto-detects Node.js, Python, Go, Ruby, Rust, Java, PHP, .NET, Elixir, Kotlin, Scala, Clojure, Deno, Bun. No Dockerfile required.
https://github.com/migetapp/migetpacks
buildpacks cloud-native container devops docker dockerfile golang java kubernetes nodejs paketo-alternative python ruby rust
Last synced: about 1 month ago
JSON representation
Zero-config container builds for 14 languages. Auto-detects Node.js, Python, Go, Ruby, Rust, Java, PHP, .NET, Elixir, Kotlin, Scala, Clojure, Deno, Bun. No Dockerfile required.
- Host: GitHub
- URL: https://github.com/migetapp/migetpacks
- Owner: migetapp
- License: other
- Created: 2026-01-26T09:44:13.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-02-09T23:06:24.000Z (about 2 months ago)
- Last Synced: 2026-02-09T23:49:11.700Z (about 2 months ago)
- Topics: buildpacks, cloud-native, container, devops, docker, dockerfile, golang, java, kubernetes, nodejs, paketo-alternative, python, ruby, rust
- Language: Shell
- Homepage: https://miget.com/packs
- Size: 628 KB
- Stars: 12
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: docs/contributing.mdx
- License: LICENSE
Awesome Lists containing this project
README
# migetpacks
**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](https://miget.com) - Unlimited apps, one price.
[](https://github.com/migetapp/migetpacks/blob/main/LICENSE)
[](https://hub.docker.com/r/miget/migetpacks)
## Features
- **Zero Config** - Automatically detects language, version, and builds your app
- **14 Languages** - Node.js, Deno, Bun, Python, Ruby, Go, Rust, Java, Kotlin, Scala, Clojure, .NET, PHP, Elixir
- **Secure by Default** - Optional [Docker Hardened Images](https://dhi.io) (distroless, CVE-free)
- **Multi-Buildpack** - Combine languages (e.g., Ruby + Node.js for asset compilation)
- **Procfile Support** - Standard process definitions
- **Non-root Runtime** - All containers run as non-root user
- **Fast Builds** - BuildKit layer caching and registry-based caching
## Requirements
- **Docker Desktop** (macOS/Windows) or **Docker Engine** (Linux)
- **BuildKit enabled** (default in Docker Desktop 4.0+)
migetpacks runs Docker-in-Docker using BuildKit for optimized multi-stage builds. It requires access to the Docker socket (`/var/run/docker.sock`).
```bash
# Verify Docker is running
docker info
# Verify BuildKit is available
docker buildx version
```
## Quick Start
### Docker
```bash
# 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
```
### GitHub Actions (GitHub-hosted runners)
For ephemeral `ubuntu-latest` runners, use registry-based caching via `CACHE_IMAGE`:
```yaml
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
```
### GitHub Actions (Self-hosted runners)
For persistent self-hosted runners, use local file cache via `BUILD_CACHE_DIR`:
```yaml
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.
## Supported Languages
| 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` | - |
## Environment Variables
| 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) |
| `TAG_LATEST` | No | `false` | Also tag image with `:latest` in addition to primary tag |
| `RESULT_FILE` | No | - | Path to write build results JSON |
| `STORAGE_DRIVER` | No | `overlay2` | Docker storage driver (e.g., `fuse-overlayfs` for nested DinD) |
### Caching Options
| 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 |
### Docker Hardened Images
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `USE_DHI` | No | `false` | Use Docker Hardened Images from [dhi.io](https://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 |
### Custom Build Environment Variables
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.
```bash
# 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 builds
- `VITE_*` / `NEXT_PUBLIC_*` - Frontend build-time variables
- `RAILS_MASTER_KEY` - Rails credentials key for asset precompilation
- Custom feature flags for conditional compilation
**Note:** Sensitive variables like `AWS_*` credentials and Docker configuration are automatically filtered out and never injected into the Dockerfile.
### LANGUAGE Values
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 |
## Procfile Support
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:
1. `RUN_COMMAND` environment variable
2. `web:` process from Procfile
3. First process in Procfile
4. Language-specific default
## Multi-Buildpack
Build apps with multiple languages:
```bash
# 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
```
## Docker Hardened Images
Use minimal, CVE-free [Docker Hardened Images](https://dhi.io):
```bash
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 (Mac/Windows)
Docker Desktop stores credentials in the system keychain, not in `~/.docker/config.json`. Extract credentials and pass them as environment variables:
```bash
# 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
```
## Dockerfile & Compose Support
### Custom Dockerfile
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`:
```bash
# 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
```
### Docker Compose
Multi-service builds from `compose.yaml`:
```yaml
# compose.yaml
services:
api:
build: ./api
web:
build: ./web
```
```bash
# 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
```
## Monorepo Support
Build a specific subdirectory:
```bash
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
```
## Build Caching
### Package Manager Cache
Mount a cache directory for npm, pip, bundler, cargo, etc.:
```bash
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
```
### Registry Cache
Use BuildKit's registry-based caching for Docker layer caching:
```bash
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
```
## Private Registry Authentication
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.
### Docker
```bash
# 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
```
### GitHub Actions
```yaml
- 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:**
- Mount `config.json` file only (buildx needs to create state in `.docker/buildx/`)
- Use `:ro` (read-only) for the config file
- On GitHub-hosted runners, the path is `/home/runner/.docker/config.json`
- On self-hosted runners, use `$HOME/.docker/config.json`
## Build Results
Get structured JSON output for CI/CD pipelines:
```bash
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
```
```json
{
"status": "success",
"images": [{"name": "my-app:latest", "ports": ["5000/tcp"]}],
"processes": {"web": "node server.js"},
"language": "nodejs",
"build_time": 45
}
```
## Examples
Working examples for all languages in [`examples/`](https://github.com/migetapp/migetpacks/tree/main/examples):
- `nodejs-example`, `deno-example`, `bun-example`
- `python-example`, `ruby-example`, `php-hello-world`
- `go-hello-world`, `rust-example`
- `java-hello-world`, `kotlin-example`, `scala-example`
- `dotnet-hello-world`, `elixir-example`
- `dockerfile-example`, `compose-example`
## Development
```bash
# 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
```
## About
migetpacks is built by [miget.com](https://miget.com) - unlimited apps, one price. We use migetpacks to build customer apps with zero configuration.
## License
O'Saasy License (Modified for Cloud/PaaS) - see [LICENSE](https://github.com/migetapp/migetpacks/blob/main/LICENSE) for details.