Phase 1: Language Detection
Thebin/detect script scans your source directory for language-specific marker files. It checks each language in priority order and returns the first match.
- Detection Rules
- Override
| File Present | Detected Language |
|---|---|
Dockerfile | dockerfile |
compose.yaml / docker-compose.yml | compose |
Gemfile | ruby |
package.json | nodejs |
deno.json / deno.jsonc | deno |
bun.lockb / bunfig.toml | bun |
requirements.txt / pyproject.toml / setup.py | python |
go.mod | go |
Cargo.toml | rust |
pom.xml / build.gradle | java |
build.gradle.kts | kotlin |
build.sbt | scala |
project.clj | clojure |
*.csproj / *.sln / *.slnx | dotnet |
mix.exs | elixir |
composer.json | php |
If a
Dockerfile is present, migetpacks uses it directly instead of generating one. Set LANGUAGE explicitly to override this behavior.Phase 2: Version Detection
Thebin/detect-version script reads language-specific version files and normalizes them for Docker image tags.
- Version Sources
- Normalization
| Language | Version Sources (priority order) |
|---|---|
| Node.js | .node-version → .nvmrc → package.json engines.node |
| Ruby | .ruby-version → Gemfile ruby declaration |
| Python | .python-version → runtime.txt → uv.lock → pyproject.toml |
| Go | .go-version → go.mod go directive |
| Rust | rust-toolchain → rust-toolchain.toml channel |
| Java | .java-version → system.properties → pom.xml |
| .NET | global.json → *.csproj TargetFramework |
| Elixir | .elixir-version → .tool-versions (asdf) |
| Deno | .deno-version → .dvmrc → deno.json version |
| Bun | .bun-version → bunfig.toml version |
| PHP | .php-version → composer.json require.php |
Phase 3: Dockerfile Generation
Thebin/build script generates an optimized multi-stage Dockerfile using the detected language and version. The generated Dockerfile follows best practices for layer caching.
Example: Node.js Application
For a Node.js app with version20 detected from .nvmrc, migetpacks generates:
Layer Caching Strategy
The key optimization is separating dependency installation from source code copying:Custom Environment Variables
Any environment variable not in the known builder vars list is automatically injected into the generated Dockerfile:ENV statements in the generated Dockerfile, available at both build time and runtime.
Phase 4: Build and Push
The final phase uses Docker-in-Docker with BuildKit to build and push the image.1
Start Docker daemon
A Docker-in-Docker daemon starts inside the builder container with BuildKit enabled.
2
Configure registry access
Registry credentials and mirrors are configured in the daemon. If
REGISTRY_MIRROR is set, it is added as a pull-through cache.3
Build with BuildKit
The generated Dockerfile is built with
docker buildx build. Cache is read from and written to CACHE_IMAGE if configured.4
Push or load
If
OUTPUT_IMAGE contains a registry prefix, the image is pushed. Otherwise, it is loaded into the local Docker daemon.5
Write results
If
RESULT_FILE is set, build metadata (status, ports, processes, timing) is written as JSON for downstream CI/CD steps.Build Cache Options
Runtime Container
The built container follows these conventions:| Property | Value |
|---|---|
| User | miget (uid 1000) |
| Working directory | /app |
| Default port | 5000 |
| Process manager | None (single process) |
| Init system | None (PID 1 is your app) |
USE_DHI=true, the runtime container is distroless (no shell, no package manager) and runs as the nonroot user instead.