How to Deploy PHP to Docker Without Writing a Dockerfile
You can containerize any PHP application without writing a Dockerfile using migetpacks. It uses FrankenPHP (a modern PHP application server built on Go and Caddy), auto-detects your PHP version and extensions from composer.json, and produces an optimized production image. One command, zero configuration.
Why Is Writing a Dockerfile for PHP So Complicated?
A production-ready PHP Dockerfile requires:
- Choosing between Apache, nginx+PHP-FPM, or modern alternatives
- Installing PHP extensions (
pdo_pgsql,gd,intl, etc.) - Configuring opcache for production
- Setting up Composer for dependency management
- Detecting the web root (
public/,web/,html/) - Production PHP settings (
display_errors=Off,memory_limit, etc.)
Most tutorials use outdated Apache configurations or manual nginx setups. You end up with slow, bloated images.
How Do I Containerize a PHP App Without a Dockerfile?
Open your terminal, navigate to your PHP project, and run:
cd ~/projects/my-laravel-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-laravel-app:latest \
miget/migetpacks:latest
That's it. migetpacks will:
- Detect PHP from
composer.jsonorindex.php - Read version from
.php-versionorcomposer.json - Detect and install required extensions
- Run
composer installwith caching - Detect the web root automatically
- Output a production-ready FrankenPHP image
What Is FrankenPHP?
FrankenPHP is a modern PHP application server built on Go and Caddy. It's:
- Faster than nginx+PHP-FPM (no FastCGI overhead)
- Simpler than Apache (single binary, no modules)
- Modern with HTTP/2, HTTP/3, and automatic HTTPS
- Production-ready with worker mode for long-running processes
How Does migetpacks Detect My PHP Version?
Version is resolved in this order:
| Source | Example |
|---|---|
.php-version | 8.3 |
composer.json (require.php) | "php": ">=8.2" |
| Default | 8.3 |
Version constraints from composer.json (e.g., >=8.2, ^8.3) are normalized for Docker.
FrankenPHP supports PHP 8.2, 8.3, and 8.4. Older versions fall back to PHP 8.2 with a warning.
How Does PHP Extension Detection Work?
Extensions declared in composer.json under require with the ext- prefix are automatically installed:
{
"require": {
"ext-pdo_pgsql": "*",
"ext-gd": "*",
"ext-intl": "*"
}
}
migetpacks reads your composer.json and installs all required extensions in the Docker image.
What Does the Generated Dockerfile Look Like?
# Build stage
FROM dunglas/frankenphp:builder-php8.3 AS builder
WORKDIR /build
# Install PHP extensions detected from composer.json
RUN apt-get update && apt-get install -y ... \
&& docker-php-ext-install pdo_pgsql gd ...
# Composer install with caching
COPY composer.json composer.lock* ./
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& composer install --no-dev --optimize-autoloader --no-scripts
COPY . .
# Runtime stage
FROM dunglas/frankenphp:php8.3
WORKDIR /app
COPY --from=builder --chown=1000:1000 /build /app
You never write or maintain this file - migetpacks handles it automatically.
How Does Web Root Detection Work?
migetpacks automatically detects the web root by checking for these directories (in order):
web/public/html/www/.(project root, fallback)
Laravel apps use public/, Symfony uses public/, and WordPress often uses the root.
What PHP Settings Are Applied for Production?
| Setting | Default |
|---|---|
memory_limit | 256M |
max_execution_time | 30 |
upload_max_filesize | 32M |
opcache.enable | 1 |
display_errors | Off |
session.cookie_secure | 1 |
Override at runtime with PHP_INI_* environment variables:
docker run -e PHP_INI_MEMORY_LIMIT=512M my-laravel-app:latest
How Do I Build a Laravel App?
Laravel works out of the box:
cd ~/projects/my-laravel-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-laravel:latest \
miget/migetpacks:latest
Run the container:
docker run -p 8000:8000 \
-e APP_KEY=base64:your-app-key \
my-laravel:latest
Next Steps
- Full PHP documentation - version detection, extensions, FrankenPHP
- Deploy on Miget - unlimited apps, one price
- Star on GitHub - migetpacks is open source
- Related guides: Ruby, Python, Node.js