PHPackages                             mwguerra/docker-local - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. mwguerra/docker-local

ActiveLibrary[Database &amp; ORM](/categories/database)

mwguerra/docker-local
=====================

Complete Docker development environment for Laravel - PHP 8.4, MySQL 9.1, PostgreSQL 17, Redis 8, Traefik 3.6

0.4.0(2mo ago)936↓87.5%MITShellPHP ^8.2

Since Dec 31Pushed 2mo agoCompare

[ Source](https://github.com/mwguerra/docker-local)[ Packagist](https://packagist.org/packages/mwguerra/docker-local)[ Docs](https://github.com/mwguerra/docker-local)[ RSS](/packages/mwguerra-docker-local/feed)WikiDiscussions main Synced yesterday

READMEChangelogDependencies (4)Versions (8)Used By (0)

docker-local
============

[](#docker-local)

Complete Docker development environment for Laravel with a powerful CLI.

[![Packagist Version](https://camo.githubusercontent.com/6fbf54aa2a5a904d2bb42bd8df2519cbc10957571bfde6d3a3cac1fd3d0a73c3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d776775657272612f646f636b65722d6c6f63616c2e737667)](https://packagist.org/packages/mwguerra/docker-local)[![PHP Version](https://camo.githubusercontent.com/0f16581d1180dbfd4c0e13166ec1267d4ad2f2fab8281ea6d6b284cf5c65d921/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d626c75652e737667)](https://www.php.net/)[![License](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

> **Global Composer Package** — Install once, use everywhere. No per-project Docker configuration needed.

Quick Install
-------------

[](#quick-install)

**For experienced developers** — get up and running in 60 seconds:

```
# Install globally via Composer
composer global require mwguerra/docker-local

# Add to PATH (add this line to ~/.bashrc or ~/.zshrc for persistence)
export PATH="$HOME/.composer/vendor/bin:$PATH"

# Initialize the environment
docker-local init

# Create your first Laravel project
docker-local make:laravel my-app

# Open in browser (https://my-app.test)
docker-local open
```

**Need prerequisites first?** See [Installation](#installation) for platform-specific setup guides.

---

Features
--------

[](#features)

- **PHP 8.4** with Xdebug 3.4, FFmpeg, and all Laravel extensions
- **MySQL 9.1** and **PostgreSQL 17 with pgvector** (AI embeddings)
- **Redis 8** for cache, sessions, and queues
- **MinIO** S3-compatible object storage
- **Traefik 3.6** reverse proxy with automatic SSL
- **Mailpit** for email testing
- **RTMP Server** (optional) for live streaming with HLS
- **Whisper AI** (optional) for audio transcription
- **Node.js 20** (optional) standalone container for asset builds
- **50+ CLI commands** for rapid development
- **Multi-project support** with automatic isolation
- **Cross-platform** - Linux, macOS, and Windows (WSL2)

Table of Contents
-----------------

[](#table-of-contents)

- [Quick Install](#quick-install)
- [Requirements](#requirements)
- [Installation](#installation)
    - [Linux](#linux)
    - [macOS](#macos)
    - [Windows (WSL2)](#windows-wsl2)
- [Quick Start](#quick-start)
    - [New Project](#new-project)
    - [Existing Project](#existing-project)
- [CLI Commands](#cli-commands)
- [Configuration](#configuration)
    - [Directory Structure](#directory-structure)
    - [Package Structure (Source Code)](#package-structure-source-code)
    - [User Configuration](#user-configuration-configdocker-local)
    - [Projects Directory](#projects-directory-projects)
    - [Understanding Environment Files](#understanding-environment-files)
- [Services](#services)
- [Optional Services](#optional-services)
- [Multi-Project Support](#multi-project-support)
    - [What Gets Created Automatically](#what-gets-created-automatically)
    - [Automatic Isolation Details](#automatic-isolation-details)
    - [Redis Database Allocation](#redis-database-allocation)
    - [Running Multiple Projects Simultaneously](#running-multiple-projects-simultaneously)
- [Migrating from Project-Specific Docker](#migrating-from-project-specific-docker)
- [IDE Integration](#ide-integration)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)

Requirements
------------

[](#requirements)

### All Platforms

[](#all-platforms)

SoftwareMinimum VersionCheck CommandDocker24.0+`docker --version`Docker Compose2.20+`docker compose version`PHP8.2+`php --version`Composer2.6+`composer --version`### System Requirements

[](#system-requirements)

- **RAM:** 8GB minimum, 16GB recommended
- **Disk:** 20GB free space
- **CPU:** 64-bit processor with virtualization support

Installation
------------

[](#installation)

### Linux

[](#linux)

Tested on Ubuntu 22.04+, Debian 12+, Fedora 38+, and Arch Linux.

```
# 1. Install Docker (if not already installed)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker

# 2. Install PHP and Composer (Ubuntu/Debian)
sudo apt update
sudo apt install php8.3 php8.3-{cli,curl,mbstring,xml,zip} unzip
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# 3. Install docker-local
composer global require mwguerra/docker-local

# 4. Add Composer bin to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.composer/vendor/bin:$PATH"

# 5. Reload shell and run setup
source ~/.bashrc  # or source ~/.zshrc
docker-local init

# 6. (Optional) Configure DNS for *.test domains
sudo "$(which docker-local)" setup:dns
```

### macOS

[](#macos)

Tested on macOS 12 (Monterey) and later.

```
# 1. Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 2. Install Docker Desktop
brew install --cask docker
# Launch Docker Desktop from Applications

# 3. Install PHP and Composer
brew install php composer

# 4. Install docker-local
composer global require mwguerra/docker-local

# 5. Add Composer bin to PATH (add to ~/.zshrc)
export PATH="$HOME/.composer/vendor/bin:$PATH"

# 6. Reload shell and run setup
source ~/.zshrc
docker-local init

# 7. (Optional) Configure DNS for *.test domains
sudo "$(which docker-local)" setup:dns
```

### Windows (WSL2)

[](#windows-wsl2)

**Important:** docker-local requires WSL2 on Windows. Native Windows is not supported.

#### Step 1: Install WSL2

[](#step-1-install-wsl2)

```
# Run in PowerShell as Administrator
wsl --install -d Ubuntu
```

Restart your computer when prompted.

#### Step 2: Install Docker Desktop

[](#step-2-install-docker-desktop)

1. Download [Docker Desktop for Windows](https://www.docker.com/products/docker-desktop/)
2. During installation, ensure "Use WSL 2 based engine" is checked
3. After installation, go to Settings &gt; Resources &gt; WSL Integration
4. Enable integration with your Ubuntu distribution

#### Step 3: Install docker-local (in WSL2 Ubuntu)

[](#step-3-install-docker-local-in-wsl2-ubuntu)

```
# Open Ubuntu from Start Menu, then run:

# Install PHP and Composer
sudo apt update
sudo apt install php8.3 php8.3-{cli,curl,mbstring,xml,zip} unzip
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Install docker-local
composer global require mwguerra/docker-local

# Add to PATH (add to ~/.bashrc)
echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# Run setup
docker-local init

# (Optional) Configure DNS
sudo "$(which docker-local)" setup:dns
```

#### Accessing Projects from Windows

[](#accessing-projects-from-windows)

Your WSL2 projects are accessible in Windows Explorer at:

```
\\wsl$\Ubuntu\home\\projects

```

Or in VS Code:

```
# From WSL2 terminal
code ~/projects/my-project
```

Quick Start
-----------

[](#quick-start)

### New Project

[](#new-project)

```
# Create a new Laravel project (everything is configured automatically)
docker-local make:laravel my-app

# With PostgreSQL instead of MySQL
docker-local make:laravel my-app --postgres

# Navigate to project
cd ~/projects/my-app

# Open in browser (https://my-app.test)
docker-local open

# Run artisan commands
docker-local tinker
docker-local new:model Post -mcr

# View logs
docker-local logs
docker-local logs:laravel

# Stop environment
docker-local down
```

### Existing Project

[](#existing-project)

If you have an existing Laravel project, copy it to `~/projects/` and configure it:

```
# 1. Copy your project to the projects directory
cp -r /path/to/existing-project ~/projects/my-existing-app

# 2. Navigate to the project
cd ~/projects/my-existing-app

# 3. Create the database
docker-local db:create my_existing_app

# 4. Update your .env file with docker-local settings
```

**Required `.env` changes for existing projects:**

```
# Database - use Docker service names, not localhost
DB_HOST=mysql                    # or 'postgres' for PostgreSQL
DB_PORT=3306                     # or 5432 for PostgreSQL
DB_DATABASE=my_existing_app      # your project's database name
DB_USERNAME=laravel
DB_PASSWORD=secret

# Redis - use Docker service name
REDIS_HOST=redis
REDIS_PORT=6379

# IMPORTANT: Unique isolation values (prevent conflicts with other projects)
CACHE_PREFIX=my_existing_app_
REDIS_CACHE_DB=0                 # Use different numbers if you have multiple projects
REDIS_SESSION_DB=1               # Project 1: 0-2, Project 2: 3-5, etc.
REDIS_QUEUE_DB=2

# Mail - use Mailpit
MAIL_HOST=mailpit
MAIL_PORT=1025

# MinIO/S3 (optional)
AWS_ENDPOINT=http://minio:9000
AWS_ACCESS_KEY_ID=minio
AWS_SECRET_ACCESS_KEY=minio123
AWS_BUCKET=my_existing_app
AWS_USE_PATH_STYLE_ENDPOINT=true
```

**Quick setup script for existing projects:**

```
# Create database
docker-local db:create my_existing_app

# Create MinIO bucket (optional)
docker exec minio mc mb local/my_existing_app --ignore-existing

# Install dependencies
docker exec -w /var/www/my-existing-app php composer install

# Generate key if needed
docker exec -w /var/www/my-existing-app php php artisan key:generate

# Run migrations
docker exec -w /var/www/my-existing-app php php artisan migrate

# Open in browser
docker-local open my-existing-app
```

**Checklist for existing projects:**

- Project copied to `~/projects//`
- Database created (`docker-local db:create `)
- `.env` updated with Docker service names (`mysql`, `redis`, `mailpit`)
- Unique `CACHE_PREFIX` set (e.g., `myproject_`)
- Unique `REDIS_*_DB` numbers assigned (if running multiple projects)
- Dependencies installed (`composer install`)
- Migrations run (`php artisan migrate`)
- Host added to `/etc/hosts` or dnsmasq configured

CLI Commands
------------

[](#cli-commands)

### Setup &amp; Diagnostics

[](#setup--diagnostics)

```
docker-local init              # Complete initial setup
docker-local doctor            # Full system health check
docker-local fix [options]     # Diagnose and auto-fix common issues
docker-local config            # View current configuration
docker-local setup:hosts       # Add Docker hostnames to /etc/hosts (sudo)
docker-local setup:dns         # Configure dnsmasq for *.test (sudo)
docker-local update            # Update Docker images
```

**Fix command options:**

```
docker-local fix               # Run all checks, auto-fix what's possible
docker-local fix --dns         # Only check/fix DNS issues
docker-local fix --docker      # Only check/fix Docker daemon
docker-local fix --services    # Only check/fix container services
docker-local fix --hosts       # Only check/fix /etc/hosts
docker-local fix --verbose     # Show detailed diagnostic info
docker-local fix --dry-run     # Show what would be fixed without making changes
```

The `fix` command automatically detects and resolves issues like:

- Docker daemon not running
- Stopped containers
- Missing systemd-resolved configuration for \*.test DNS
- Missing dnsmasq configuration
- /etc/hosts not configured

### Environment Management

[](#environment-management)

```
docker-local up                # Start all containers
docker-local down              # Stop all containers
docker-local restart           # Restart all containers
docker-local status            # Show service status
docker-local logs [service]    # View logs (all or specific service)
docker-local clean             # Clean caches and unused Docker resources
```

### Project Commands

[](#project-commands)

```
docker-local list              # List all Laravel projects
docker-local make:laravel NAME # Create new Laravel project (MySQL, full isolation)
docker-local make:laravel NAME --postgres  # Create with PostgreSQL + pgvector
docker-local clone REPO        # Clone and setup existing project
docker-local open [name]       # Open project in browser
docker-local open --mail       # Open Mailpit
docker-local open --minio      # Open MinIO Console
docker-local open --traefik    # Open Traefik Dashboard
docker-local ide [editor]      # Open in IDE (code, phpstorm)
```

**`make:laravel` creates everything automatically:**

- Laravel project via Composer
- Database (MySQL or PostgreSQL) + testing database
- MinIO bucket for file storage
- Unique Redis DB numbers for cache/session/queue
- Unique cache prefix and Reverb credentials
- Configured `.env` with all Docker service connections

### Development Commands

[](#development-commands)

```
docker-local tinker            # Laravel Tinker REPL
docker-local test [options]    # Run tests (supports --coverage, --parallel)
docker-local require PACKAGE   # Install Composer package with suggestions
docker-local logs:laravel      # Tail Laravel logs
docker-local shell             # Open PHP container shell
```

### Artisan Shortcuts

[](#artisan-shortcuts)

```
docker-local new:model NAME [-mcr]       # make:model (with migration, controller, resource)
docker-local new:controller NAME [--api] # make:controller
docker-local new:migration NAME          # make:migration
docker-local new:seeder NAME             # make:seeder
docker-local new:factory NAME            # make:factory
docker-local new:request NAME            # make:request
docker-local new:resource NAME           # make:resource
docker-local new:middleware NAME         # make:middleware
docker-local new:event NAME              # make:event
docker-local new:job NAME                # make:job
docker-local new:mail NAME               # make:mail
docker-local new:command NAME            # make:command
```

### Database Commands

[](#database-commands)

```
docker-local db:mysql          # Open MySQL CLI
docker-local db:postgres       # Open PostgreSQL CLI
docker-local db:redis          # Open Redis CLI
docker-local db:create NAME    # Create new database
docker-local db:dump [name]    # Export database to SQL
docker-local db:restore FILE   # Import SQL file
docker-local db:fresh          # migrate:fresh --seed
```

### Queue Commands

[](#queue-commands)

```
docker-local queue:work        # Start queue worker
docker-local queue:restart     # Restart queue workers
docker-local queue:failed      # List failed jobs
docker-local queue:retry ID    # Retry failed job (or 'all')
docker-local queue:clear       # Clear all queued jobs
```

### Xdebug Commands

[](#xdebug-commands)

```
docker-local xdebug on         # Enable Xdebug
docker-local xdebug off        # Disable Xdebug (better performance)
docker-local xdebug status     # Show Xdebug status
```

### Startup Commands

[](#startup-commands)

Configure docker-local to start automatically when your computer boots:

```
docker-local startup enable    # Start on OS boot
docker-local startup disable   # Disable startup on boot
docker-local startup status    # Show startup status
```

**Platform-specific behavior:**

PlatformMethodLocationLinuxsystemd service`~/.config/systemd/user/docker-local.service`macOSLaunchAgent`~/Library/LaunchAgents/com.mwguerra.docker-local.plist`WSL2bashrc scriptEntry in `~/.bashrc`### Environment Verification

[](#environment-verification)

```
docker-local env:check         # Verify current project .env
docker-local env:check --all   # Audit ALL projects for conflicts
docker-local make:env          # Generate new .env with unique IDs
docker-local update:env        # Update existing .env
```

Configuration
-------------

[](#configuration)

Configuration is stored in `~/.config/docker-local/config.json`:

```
{
  "version": "2.0.0",
  "projects_path": "~/projects",
  "editor": "code",
  "mysql": {
    "version": "9.1",
    "port": 3306,
    "root_password": "secret",
    "database": "laravel",
    "user": "laravel",
    "password": "secret"
  },
  "postgres": {
    "version": "17",
    "port": 5432,
    "database": "laravel",
    "user": "laravel",
    "password": "secret"
  },
  "redis": {
    "version": "8",
    "port": 6379
  },
  "minio": {
    "api_port": 9000,
    "console_port": 9001,
    "root_user": "minio",
    "root_password": "minio123"
  },
  "mailpit": {
    "smtp_port": 1025,
    "web_port": 8025
  },
  "xdebug": {
    "enabled": true,
    "mode": "develop,debug"
  }
}
```

### Directory Structure

[](#directory-structure)

docker-local operates across three locations:

```
~/.composer/vendor/mwguerra/docker-local/   # Package source (Composer managed)
~/.config/docker-local/                     # User configuration (persistent)
~/projects/                                 # Your Laravel projects

```

### Package Structure (Source Code)

[](#package-structure-source-code)

```
docker-local/
├── bin/
│   └── docker-local              # CLI entry point (symfony/console)
│
├── src/                          # PHP application code
│   ├── Commands/                 # CLI command classes
│   ├── Config/
│   │   ├── ConfigManager.php     # Loads/saves config.json
│   │   ├── ConfigValidator.php   # Validates configuration
│   │   └── PathResolver.php      # Resolves ~ and relative paths
│   ├── DockerLocal.php           # Main application class
│   └── cli-helper.php            # Helper functions for CLI
│
├── lib/
│   └── config.sh                 # Bash helper functions
│
├── scripts/                      # Shell scripts for operations
│   ├── setup.sh                  # Initial environment setup
│   ├── new-project.sh            # Create new Laravel project
│   ├── generate-certs.sh         # SSL certificate generation
│   ├── setup-dns.sh              # Configure dnsmasq for *.test
│   ├── setup-hosts.sh            # Add entries to /etc/hosts
│   ├── create-database.sh        # Create MySQL/PostgreSQL databases
│   ├── make-env.sh               # Generate .env files
│   ├── artisan.sh                # Run artisan commands in container
│   ├── composer.sh               # Run composer in container
│   ├── status.sh                 # Show service status
│   ├── test-connections.sh       # Test database/redis connections
│   ├── add-host.sh               # Add single host entry
│   └── install-cli.sh            # Install CLI globally
│
├── stubs/                        # Templates with placeholders
│   ├── .env.stub                 # Docker environment template
│   ├── laravel.env.stub          # Laravel .env template ({{PROJECT_NAME}})
│   ├── config.json.stub          # Default configuration
│   └── docker-compose.override.yml.stub  # Override template
│
├── templates/
│   ├── install.sh                # Installation script template
│   └── hooks/
│       ├── pre-install.sh        # Runs before project install
│       └── post-install.sh       # Runs after project install
│
├── tests/                        # Pest PHP tests
│   ├── Pest.php                  # Pest configuration
│   ├── Unit/
│   │   ├── ConfigManagerTest.php
│   │   ├── ConfigValidatorTest.php
│   │   └── PathResolverTest.php
│   └── Feature/                  # (Integration tests)
│
├── docs/                         # Extended documentation
│   ├── README.md                 # Docs index
│   ├── architecture.md           # System architecture
│   ├── cli-reference.md          # Full CLI documentation
│   ├── getting-started.md        # Quick start guide
│   ├── services.md               # Service configuration
│   ├── templates.md              # Template system docs
│   └── troubleshooting.md        # Common issues
│
├── resources/docker/             # Alternative/reference Docker files
│   └── docker-compose.yml        # Reference compose file
│
│── Docker Service Configurations ─────────────────────────────
│
├── docker-compose.yml            # Main orchestration file
├── .env.example                  # Docker environment template
├── laravel.env.example           # Laravel .env template (manual use)
│
├── php/                          # PHP-FPM container
│   ├── Dockerfile                # PHP 8.4 with extensions
│   ├── php.ini                   # PHP configuration
│   └── xdebug.ini                # Xdebug settings
│
├── php-ai/                       # PHP + AI tools container
│   ├── Dockerfile                # PHP with Whisper/FFmpeg
│   └── php-ai.ini                # AI container PHP config
│
├── nginx/
│   └── default.conf              # Dynamic multi-project routing
│
├── mysql/
│   ├── my.cnf                    # MySQL configuration
│   └── init/
│       └── 01-create-databases.sql  # Runs on first start
│
├── postgres/
│   └── init/
│       └── 01-create-databases.sql  # Creates DBs + pgvector
│
├── redis/
│   └── redis.conf                # Redis configuration
│
├── traefik/
│   └── dynamic/
│       └── tls.yml               # TLS/SSL configuration
│
├── rtmp/
│   └── nginx-rtmp.conf           # RTMP streaming config
│
│── Root Files ─────────────────────────────────────────────────
│
├── composer.json                 # PHP dependencies
├── composer.lock                 # Locked versions
├── LICENSE                       # MIT License
├── README.md                     # This file
└── PRD.md                        # Product requirements document

```

### User Configuration (~/.config/docker-local/)

[](#user-configuration-configdocker-local)

Created by `docker-local init`, persists across updates:

```
~/.config/docker-local/
├── config.json                   # Your custom settings (ports, paths, etc.)
├── .env                          # Active Docker environment variables
├── certs/                        # SSL certificates (mkcert generated)
│   ├── localhost.pem
│   └── localhost-key.pem
└── docker-compose.override.yml   # Optional: your custom services

```

### Projects Directory (~/projects/)

[](#projects-directory-projects)

Each Laravel project is automatically accessible via HTTPS:

```
~/projects/
├── blog/                         → https://blog.test
│   ├── .env                      # Project-specific Laravel config
│   ├── app/
│   └── ...
├── api/                          → https://api.test
└── shop/                         → https://shop.test

```

### Understanding Environment Files

[](#understanding-environment-files)

docker-local uses **two separate `.env` files** for different purposes:

FileScopeUsed ByLocation`.env.example`Docker infrastructure`docker-compose.yml``~/.config/docker-local/.env``laravel.env.example`Laravel applicationLaravel framework`~/projects//.env`#### `.env.example` (Docker/Infrastructure)

[](#envexample-dockerinfrastructure)

Controls **how Docker containers are built and connected**:

```
PROJECTS_PATH=~/projects       # Where your projects live
MYSQL_PORT=3306               # Port exposed to your host machine
MYSQL_ROOT_PASSWORD=secret    # Container MySQL password
XDEBUG_ENABLED=true           # PHP container configuration
```

This file is copied to `~/.config/docker-local/.env` and read by `docker-compose.yml` via `${VARIABLE}` syntax.

#### `laravel.env.example` (Application)

[](#laravelenvexample-application)

Controls **how Laravel connects to services from inside the container**:

```
DB_HOST=mysql                 # Docker service name (NOT localhost!)
DB_PORT=3306                  # Internal container port
REDIS_HOST=redis              # Docker service name
MAIL_HOST=mailpit             # Docker service name
```

This file is copied to each project's `.env` (`~/projects/my-app/.env`) and read by Laravel via `env()` and `config()`.

#### Why Both Files Exist

[](#why-both-files-exist)

**Key insight:** The same service has different addresses depending on where you're accessing it from:

Accessing FromMySQL AddressWhyYour host (TablePlus, DBeaver)`localhost:3306`Uses exposed portInside PHP container (Laravel)`mysql:3306`Uses Docker DNSThe Docker `.env` configures what ports are **exposed to your machine**, while the Laravel `.env` configures how to reach services **via Docker's internal network**.

#### Related Files

[](#related-files)

```
docker-local/
├── .env.example              # Docker infrastructure template
├── laravel.env.example       # Laravel application template (manual use)
└── stubs/
    ├── .env.stub             # Docker template (for CLI automation)
    └── laravel.env.stub      # Laravel template with {{PLACEHOLDERS}}

```

The `stubs/` versions contain placeholders like `{{PROJECT_NAME}}` for automated project creation via `docker-local make:laravel`.

Services
--------

[](#services)

### URLs

[](#urls)

ServiceURLYour Projects`https://.test`Traefik Dashboard`https://traefik.localhost`Mailpit`https://mail.localhost`MinIO Console`https://minio.localhost`Ollama API`https://ollama.localhost`Whisper ASR`https://whisper.localhost`tusd (resumable uploads)`https://tusd.localhost`### Ports

[](#ports)

ServicePortPurposeTraefik HTTP80HTTP (redirects to HTTPS)Traefik HTTPS443HTTPSMySQL3306DatabasePostgreSQL5432DatabaseRedis6379Cache/QueueMinIO API9000S3 APIMinIO Console9001Web UIMailpit SMTP1025EmailMailpit Web8025Email UIOllama11434Local LLM inference APIWhisper ASR9501OpenAI-compatible STT APItusd1080Resumable uploads (TUS)### Default Credentials

[](#default-credentials)

ServiceUsernamePasswordMySQL (root)rootsecretMySQL (user)laravelsecretPostgreSQLlaravelsecretMinIOminiominio123All Included Services
---------------------

[](#all-included-services)

All services are now enabled by default. Simply run:

```
docker-compose up -d
```

### RTMP Server (Live Streaming)

[](#rtmp-server-live-streaming)

The RTMP server provides live streaming with HLS delivery:

**RTMP Configuration:**

EndpointURLRTMP Ingest`rtmp://localhost:1935/live/`HLS Playback`http://localhost:8088/hls/.m3u8`HLS (via Traefik)`https://stream.localhost/hls/.m3u8`Stats`http://localhost:8088/stat`**Customizing RTMP:**

To add project-specific webhooks (e.g., on\_publish callbacks), create a custom config:

```
# docker-compose.override.yml
services:
  rtmp:
    volumes:
      - ./docker/rtmp/nginx-rtmp.conf:/etc/nginx/nginx.conf:ro
      - ./storage/app/hls:/var/www/hls
      - ./storage/app/recordings:/var/www/recordings
```

### Node.js Container

[](#nodejs-container)

A dedicated Node.js 20 container for long-running build processes:

```
# Run npm commands
docker-compose exec node npm install
docker-compose exec node npm run dev
```

### PostgreSQL with pgvector

[](#postgresql-with-pgvector)

PostgreSQL 17 now includes the pgvector extension for AI embeddings:

```
-- Enabled automatically, just use it
CREATE TABLE items (
  id SERIAL PRIMARY KEY,
  embedding vector(1536)
);

-- Similarity search
SELECT * FROM items ORDER BY embedding  '[...]' LIMIT 10;
```

### AI/Whisper Transcription

[](#aiwhisper-transcription)

Two options for speech-to-text transcription:

#### Option 1: Whisper API Container (Recommended)

[](#option-1-whisper-api-container-recommended)

A dedicated Whisper ASR webservice with OpenAI-compatible HTTP API (using [faster-whisper-server](https://github.com/fedirz/faster-whisper-server)):

```
# API endpoint (internal Docker network)
http://whisper:8000/v1/audio/transcriptions

# API endpoint (from host machine)
http://localhost:9501/v1/audio/transcriptions

# Health check
curl http://localhost:9501/health
```

**Laravel Configuration (.env):**

```
WHISPER_API_URL=http://whisper:8000
WHISPER_TIMEOUT=300
WHISPER_MODEL=base
```

**Example API Call:**

```
curl -X POST http://localhost:9501/v1/audio/transcriptions \
  -F "file=@audio.mp3" \
  -F "model=base" \
  -F "language=en" \
  -F "response_format=json"
```

**Web UI:**

#### Option 2: PHP-AI Container (CLI)

[](#option-2-php-ai-container-cli)

For direct CLI access to Whisper:

```
# Run transcription via CLI
docker-compose exec php-ai whisper audio.mp3 --model base --language en

# Or from your Laravel app
docker-compose exec php-ai php artisan transcribe:audio path/to/audio.mp3
```

**Whisper Models:**

ModelSizeMemorySpeedAccuracytiny39M~1GBFastestLowerbase74M~1GBFastGoodsmall244M~2GBMediumBettermedium769M~5GBSlowHighlarge1550M~10GBSlowestBestConfigure the model in `.env`:

```
WHISPER_MODEL=base
WHISPER_LANGUAGE=en
WHISPER_PORT=9501
```

### tusd — Resumable uploads (TUS protocol)

[](#tusd--resumable-uploads-tus-protocol)

`tusd` is the reference TUS server (Go) for [resumable uploads](https://tus.io/). It accepts chunked HTTP uploads from browsers (Uppy.js, TusUpload, etc.) and streams them directly to MinIO/S3 — no PHP worker in the hot path, safe for GB-scale files on flaky connections.

**Endpoints:**

```
# Upload endpoint (internal Docker network)
http://tusd:1080/files/

# Upload endpoint (host / browser)
http://localhost:1080/files/
https://tusd.localhost/files/
```

**Configuration (`.env`):**

```
TUSD_PORT=1080
TUSD_S3_BUCKET=laravel       # or a per-project bucket
```

`tusd` reads S3 credentials from `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` and writes directly to the MinIO container at `http://minio:9000`. On upload completion, the file lives under `s3://$TUSD_S3_BUCKET/` and `.info`.

**Example upload (Uppy.js on the client, nothing server-side):**

```
import Uppy from '@uppy/core'
import Tus from '@uppy/tus'

new Uppy()
  .use(Tus, { endpoint: 'http://localhost:1080/files/' })
  .on('upload-success', (file, { uploadURL }) => { /* save key in your app */ })
```

For authorized uploads in production, configure tusd hooks (`-hooks-http`) to call a Laravel endpoint that validates the user and allowed bucket prefix before accepting a new upload.

### Laravel Workers (Horizon, Reverb, Scheduler)

[](#laravel-workers-horizon-reverb-scheduler)

For Laravel-specific services, use the override stub as a template:

```
# Copy the stub
cp ~/.composer/vendor/mwguerra/docker-local/stubs/docker-compose.override.yml.stub \
   ~/.config/docker-local/docker-compose.override.yml

# Uncomment the services you need and customize
```

Available templates:

- **Horizon** - Queue worker with Laravel Horizon
- **Reverb** - WebSocket server for real-time features
- **Scheduler** - Cron-like task scheduler
- **Elasticsearch/Meilisearch** - Full-text search
- **Soketi** - Open-source Pusher alternative

Multi-Project Support
---------------------

[](#multi-project-support)

docker-local supports multiple Laravel projects sharing the same Docker services. Each project gets **complete automatic isolation** to prevent data leakage between projects.

### What Gets Created Automatically

[](#what-gets-created-automatically)

When you create a project with `docker-local make:laravel myapp`, everything is set up automatically:

```
Creating Laravel project: myapp
Database: MySQL
Redis DBs: cache=0, session=1, queue=2

✓ Project created successfully!
✓ MySQL database 'myapp' created
✓ MySQL database 'myapp_testing' created
✓ MinIO bucket 'myapp' created
✓ .env configured with complete isolation

Isolation settings (multi-project):
  ✓ Database: myapp (MySQL)
  ✓ Redis Cache DB: 0
  ✓ Redis Session DB: 1
  ✓ Redis Queue DB: 2
  ✓ Cache Prefix: myapp_
  ✓ MinIO Bucket: myapp
  ✓ Reverb App ID: 847291

```

### Automatic Isolation Details

[](#automatic-isolation-details)

ResourceHow It's IsolatedExample Value**Database**Unique DB per project`myapp`, `myapp_testing`**Redis Cache**Separate Redis DB number`REDIS_CACHE_DB=0`**Redis Session**Separate Redis DB number`REDIS_SESSION_DB=1`**Redis Queue**Separate Redis DB number`REDIS_QUEUE_DB=2`**Cache Prefix**Unique prefix per project`CACHE_PREFIX=myapp_`**MinIO Bucket**Separate S3 bucket`AWS_BUCKET=myapp`**Reverb/WebSockets**Unique credentialsRandom `REVERB_APP_ID/KEY/SECRET`**Horizon Prefix**Unique queue prefix`HORIZON_PREFIX=myapp_horizon:`### Redis Database Allocation

[](#redis-database-allocation)

Redis has 16 databases (0-15). Each project uses 3 databases:

ProjectCache DBSession DBQueue DB1st project0122nd project3453rd project6784th project910115th project121314This allows up to 5 fully isolated projects. Beyond that, DB numbers wrap around (with a warning).

### PostgreSQL vs MySQL

[](#postgresql-vs-mysql)

Both database engines are available. Use the `--postgres` flag:

```
# MySQL (default)
docker-local make:laravel myapp

# PostgreSQL with pgvector
docker-local make:laravel myapp --postgres
```

PostgreSQL projects automatically get these extensions:

- `uuid-ossp` - UUID generation
- `pgcrypto` - Cryptographic functions
- `vector` - pgvector for AI embeddings

### Conflict Detection

[](#conflict-detection)

```
# Check current project
docker-local env:check

# Audit ALL projects for conflicts
docker-local env:check --all
```

Example conflict output:

```
┌─ Cross-Project Conflicts ─────────────────────────────────────────┐
  ⚠ CACHE_PREFIX conflict with 'other-project'
    Both projects use: laravel_cache_

  Why: Cache data will be shared/corrupted between projects
  Fix: Change CACHE_PREFIX in one of the projects' .env files

```

### Running Multiple Projects Simultaneously

[](#running-multiple-projects-simultaneously)

All projects can run at the same time without conflicts:

```
# Terminal 1 - Work on blog
cd ~/projects/blog
docker-local tinker

# Terminal 2 - Work on api
cd ~/projects/api
docker-local test

# Terminal 3 - Work on admin
cd ~/projects/admin
docker-local queue:work
```

Each project has its own:

- Database (no shared tables)
- Cache (no key collisions)
- Sessions (users stay logged in to their project)
- Queues (jobs don't mix between projects)
- File storage (separate MinIO buckets)

Migrating from Project-Specific Docker
--------------------------------------

[](#migrating-from-project-specific-docker)

If your project has its own Docker configuration, you can migrate to docker-local for a shared, centralized environment.

### What docker-local Provides

[](#what-docker-local-provides)

ServiceIncludedNotesPHP 8.4 FPMYesWith FFmpeg, ImageMagick, 50+ extensionsPostgreSQL 17YesWith pgvector for AI embeddingsMySQL 9.1YesInnovation releaseRedis 8YesWith persistenceMinIOYesS3-compatible storageMailpitYesEmail testingNginxYesDynamic multi-project routingTraefikYesReverse proxy with SSLRTMP ServerYesLive streaming with HLSWhisper APIYesHTTP API for speech-to-textPHP-AIYesPHP with Whisper CLINode.js 20YesFrontend build tooling### What Stays Project-Specific

[](#what-stays-project-specific)

These should remain in your project's `docker-compose.override.yml`:

ServiceReasonLaravel HorizonUses app container, just different commandLaravel ReverbWebSocket server specific to your appSchedulerCron jobs specific to your appE2E Testing (Playwright)Test infrastructure is project-specificCustom AI ModelsSpecialized ML models beyond Whisper### Migration Steps

[](#migration-steps)

1. **Copy your project's custom services to an override file:**

```
# Create override in project root
touch ~/projects/your-app/docker-compose.override.yml
```

2. **Add Laravel-specific services:**

```
# docker-compose.override.yml
services:
  horizon:
    image: php  # Uses docker-local's PHP image
    container_name: your-app-horizon
    working_dir: /var/www/your-app
    volumes:
      - ${PROJECTS_PATH:-../projects}:/var/www:cached
    networks:
      - laravel-dev
    command: php artisan horizon
    depends_on:
      - redis
      - postgres

  reverb:
    image: php
    container_name: your-app-reverb
    working_dir: /var/www/your-app
    volumes:
      - ${PROJECTS_PATH:-../projects}:/var/www:cached
    ports:
      - "8080:8080"
    networks:
      - laravel-dev
    command: php artisan reverb:start --host=0.0.0.0 --port=8080

  scheduler:
    image: php
    container_name: your-app-scheduler
    working_dir: /var/www/your-app
    volumes:
      - ${PROJECTS_PATH:-../projects}:/var/www:cached
    networks:
      - laravel-dev
    command: sh -c "while true; do php artisan schedule:run; sleep 60; done"

networks:
  laravel-dev:
    external: true
```

3. **Update your .env for docker-local:**

```
# Database (uses docker-local's PostgreSQL)
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=your_app
DB_USERNAME=laravel
DB_PASSWORD=secret

# Redis
REDIS_HOST=redis
REDIS_PORT=6379

# MinIO
FILESYSTEM_DISK=s3
AWS_ENDPOINT=http://minio:9000
AWS_ACCESS_KEY_ID=minio
AWS_SECRET_ACCESS_KEY=minio123
AWS_BUCKET=your-app
AWS_USE_PATH_STYLE_ENDPOINT=true

# Mail
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
```

4. **For RTMP/streaming features:**

```
# RTMP is included by default, just start docker-local
cd ~/projects/docker-environment
docker-compose up -d

# Create custom RTMP config with your callbacks (optional)
mkdir -p ~/projects/your-app/docker/rtmp
# Edit nginx-rtmp.conf with on_publish webhooks
```

5. **Remove old Docker files from your project:**

```
cd ~/projects/your-app
rm -rf docker/
rm docker-compose.yml
rm docker-compose.test.yml
# Keep docker-compose.override.yml for project-specific services
```

6. **Start using docker-local:**

```
docker-local up
docker-local open your-app
```

### Example: pcast Migration

[](#example-pcast-migration)

For a complex streaming application like pcast:

**Before (project-specific):**

```
pcast/
├── docker/
│   ├── app/Dockerfile          # Custom PHP with Whisper
│   ├── nginx/                  # nginx configs
│   ├── playwright/             # E2E testing
│   ├── rtmp-tester/            # Test tools
│   └── webrtc-tester/          # Test tools
├── docker-compose.yml          # 12 services
├── docker-compose.test.yml     # Testing
└── docker-compose.testing.yml  # E2E testing

```

**After (docker-local):**

```
pcast/
├── docker/
│   └── rtmp/nginx-rtmp.conf    # Only: Custom RTMP callbacks
├── docker-compose.override.yml # Horizon, Reverb, Scheduler
└── .env                        # Updated for docker-local

```

**Start docker-local (all features included):**

```
cd ~/projects/docker-environment
docker-compose up -d
```

**Benefits:**

- Shared services across all projects
- Centralized updates and maintenance
- Consistent development environment
- Smaller project footprint

IDE Integration
---------------

[](#ide-integration)

### VS Code

[](#vs-code)

1. Install PHP Debug extension
2. Create `.vscode/launch.json`:

```
{
  "version": "0.2.0",
  "configurations": [{
    "name": "Listen for Xdebug",
    "type": "php",
    "request": "launch",
    "port": 9003,
    "pathMappings": {
      "/var/www/my-project": "${workspaceFolder}"
    }
  }]
}
```

3. Start debugging: F5

### PhpStorm

[](#phpstorm)

1. Settings → PHP → Debug → Port: `9003`
2. Settings → PHP → Servers:
    - Name: `docker`
    - Host: `localhost`, Port: `443`
    - Path mappings: `/var/www/project` → `~/projects/project`
3. Click "Start Listening for PHP Debug Connections"

Troubleshooting
---------------

[](#troubleshooting)

### General Diagnostics

[](#general-diagnostics)

```
docker-local fix               # Auto-diagnose and fix common issues
docker-local fix --dns -v      # Detailed DNS troubleshooting
docker-local doctor            # Full health check (read-only)
docker-local status            # Service status
docker-local logs              # View all logs
docker-local logs mysql        # View specific service logs
```

The `fix` command is the recommended first step when troubleshooting - it automatically diagnoses issues and attempts to fix them where possible.

### Common Issues

[](#common-issues)

#### "Docker daemon is not running"

[](#docker-daemon-is-not-running)

```
# Linux
sudo systemctl start docker

# macOS
open -a Docker

# Windows (WSL2)
# Start Docker Desktop from Windows
```

#### "Port already in use"

[](#port-already-in-use)

```
# Find what's using the port
lsof -i :3306  # or :5432, :6379, etc.

# Or change the port in config
# Edit ~/.config/docker-local/config.json
```

#### "Permission denied" errors

[](#permission-denied-errors)

```
# Linux: Add user to docker group
sudo usermod -aG docker $USER
newgrp docker

# Or fix project permissions
sudo chown -R $USER:$USER ~/projects
```

#### "\*.test domains not resolving"

[](#test-domains-not-resolving)

```
# Quick fix - run the fix command
docker-local fix --dns

# Follow the suggested commands (requires sudo)
sudo "$(which docker-local)" setup:dns

# Manual verification
dig test.test @127.0.0.1     # Should return 127.0.0.1 (dnsmasq working)
ping test.test               # Should resolve to 127.0.0.1 (full system working)
```

If dnsmasq is working but system DNS isn't:

```
# Check systemd-resolved configuration (Linux)
cat /etc/systemd/resolved.conf.d/docker-local.conf

# Should contain:
# [Resolve]
# DNS=127.0.0.1#53
# Domains=~test. ~localhost.
```

#### SSL Certificate Issues

[](#ssl-certificate-issues)

```
# Regenerate certificates
docker-local init --certs

# Or manually with mkcert
mkcert -install
mkcert "*.test" "*.localhost"
```

### Cleaning Up

[](#cleaning-up)

```
# Clean caches and logs
docker-local clean

# Full cleanup (removes volumes)
docker-local clean --all

# Reset everything
docker-local down
docker system prune -af
docker volume prune -f
docker-local init
```

Using Local PHP
---------------

[](#using-local-php)

If you prefer using your local PHP installation with Docker services:

```
# 1. Configure hostnames
sudo "$(which docker-local)" setup:hosts

# 2. Now use standard PHP commands
cd ~/projects/my-app
php artisan migrate
php artisan serve
composer require laravel/sanctum
```

The `setup:hosts` command adds to `/etc/hosts`:

```
127.0.0.1 mysql postgres redis minio mailpit

```

Shell Completion
----------------

[](#shell-completion)

### Bash

[](#bash)

```
# Add to ~/.bashrc
eval "$(docker-local completion bash)"
```

### Zsh

[](#zsh)

```
# Add to ~/.zshrc
eval "$(docker-local completion zsh)"
```

Updating
--------

[](#updating)

```
# Update docker-local CLI
composer global update mwguerra/docker-local

# Update Docker images
docker-local update

# Or combined
docker-local self-update
```

Extending
---------

[](#extending)

### Adding Custom Services

[](#adding-custom-services)

Create `~/.config/docker-local/docker-compose.override.yml`:

```
services:
  elasticsearch:
    image: elasticsearch:8.11.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    networks:
      - laravel-dev
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  elasticsearch_data:
```

Then restart:

```
docker-local restart
```

### Custom PHP Configuration

[](#custom-php-configuration)

Create `~/.config/docker-local/php/custom.ini`:

```
memory_limit = 512M
upload_max_filesize = 100M
post_max_size = 100M
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

```
# Clone the repository
git clone https://github.com/mwguerra/docker-local.git
cd docker-local

# Install dependencies
composer install

# Run tests
./vendor/bin/pest

# Run tests with coverage
./vendor/bin/pest --coverage
```

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

---

Made with ❤️ for Laravel developers.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance85

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Recently: every ~26 days

Total

7

Last Release

79d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/27717982?v=4)[Marcelo Guerra](/maintainers/MWGuerra)[@mwguerra](https://github.com/mwguerra)

---

Top Contributors

[![mwguerra](https://avatars.githubusercontent.com/u/27717982?v=4)](https://github.com/mwguerra "mwguerra (63 commits)")

---

Tags

phplaravelmysqlpostgresqlredisXdebugenvironmentdevelopmentdockerollamawhispertraefikminiotusd

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/mwguerra-docker-local/health.svg)

```
[![Health](https://phpackages.com/badges/mwguerra-docker-local/health.svg)](https://phpackages.com/packages/mwguerra-docker-local)
```

###  Alternatives

[vcian/laravel-db-auditor

Database DB Auditor provide leverage to audit your MySql,sqlite, PostgreSQL database standards and also provide options to add constraints in table.

28638.1k1](/packages/vcian-laravel-db-auditor)[maikealame/laravel-auto

Laravel helper to make almost everything for your project

414.7k](/packages/maikealame-laravel-auto)[watheqalshowaiter/model-fields

Get model fields fast — required, nullable, or default

402.1k](/packages/watheqalshowaiter-model-fields)[matthew-p/docker-server

Universal docker server, Nginx, PHP-FPM, MySql, Redis

115.1k](/packages/matthew-p-docker-server)[moharrum/laravel-adminer

Adminer database management tool for your Laravel application.

451.0k](/packages/moharrum-laravel-adminer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
