A CLI tool for scaffolding new Laravel projects with Docker-driven local development and AI-assisted development conventions. Clone this repo, run the installer, and use the skeleton command to bootstrap new projects — no need to install specific versions of PHP, MySQL, or web servers on your local machine.
git clone https://github.com/wetfish/skeleton.git
cd skeleton
./install.shThis creates a symlink in ~/.local/bin/skeleton so the command is available everywhere. No root access required.
Then, to start a new project:
mkdir ~/projects/my-new-app && cd ~/projects/my-new-app
skeletonThe interactive wizard walks you through project name, port configuration, license, README generation, and optionally installs Laravel for you.
Running skeleton in a directory will:
- Prompt for a project name (used for Docker container names, database, and network)
- Let you choose Nginx and MySQL host ports (default, random, or custom)
- Generate a random 32-character database password (stored in
.env, never committed) - Preserve or generate a README and LICENSE file
- Copy a Dockerized development environment (PHP 8.5-FPM, Nginx, MySQL 8.0)
- Generate
.env(gitignored, contains secrets) and.env.example(committed, documents expected variables) - Generate a
.gitignorethat protects secrets from being committed - Copy AI development convention docs
- Optionally install Laravel, generate an app key, configure the database, and run migrations
skeleton Start the interactive setup wizard
skeleton --help Show usage information
skeleton --version Show version number
git clone https://github.com/wetfish/skeleton.git
cd skeleton
./install.shThe installer symlinks the skeleton command to ~/.local/bin/. If that directory isn't in your PATH, the installer will print the export line you need to add to your shell profile.
Since it's a symlink, updating is just:
cd ~/path/to/skeleton
git pullcd ~/path/to/skeleton
./install.sh --uninstallThis removes the ~/.local/bin/skeleton symlink.
Each project created by skeleton gets a three-container Docker setup:
| Container | Image | Purpose |
|---|---|---|
| {name}-app | php:8.5-fpm (custom) | PHP-FPM with Laravel extensions and Composer |
| {name}-nginx | nginx:alpine | Serves laravel/public/, proxies PHP to app |
| {name}-db | mysql:8.0 | MySQL database |
All artisan commands run through the app container during local development:
docker compose exec app php artisan migrate
docker compose exec app php artisan make:model Example -mOn production servers where Laravel runs directly, drop the Docker prefix:
php artisan migrateDocker Compose reads the root .env file for container configuration (database credentials, port mappings, project name). This file is generated by skeleton and gitignored by default — secrets never touch the repo.
A .env.example file is committed alongside it to document the expected variables with placeholder values. New developers clone the repo, copy .env.example to .env, and fill in their own values (or re-run skeleton to generate fresh ones).
Laravel's own laravel/.env is also gitignored by Laravel's default .gitignore.
Every project includes a docs/05-ai-development-notes.md file with conventions for building Laravel apps with Claude, refined across multiple production projects. These cover: reviewing docs before starting work, keeping documentation current, providing full file artifacts, code block formatting, file path references, migration ordering, schema conventions, database connection tips, validation patterns, and more.
skeleton/
├── install.sh # Installer — symlinks CLI to ~/.local/bin
├── skeleton.sh # The main CLI script
├── VERSION # Version string
├── templates/
│ ├── .gitignore # Protects .env from being committed
│ ├── Dockerfile
│ ├── docker-compose.yml # Uses ${VARIABLE} refs, reads from .env
│ ├── docker/
│ │ ├── nginx/
│ │ │ └── default.conf
│ │ └── php/
│ │ └── custom.ini
│ ├── docs/
│ │ ├── 01-database-schema.md
│ │ ├── 02-services-and-commands.md
│ │ ├── 03-routes-and-controllers.md
│ │ ├── 04-frontend.md
│ │ ├── 05-ai-development-notes.md
│ │ └── 06-planned-features.md
│ └── licenses/
│ ├── AGPL-3.0
│ ├── BSD-3-Clause
│ ├── GPL-3.0
│ └── MIT
├── README.md
└── LICENSE
The templates/ directory contains the files that get copied to new projects. Everything outside templates/ belongs to the skeleton tool itself and is never copied.
To add a new license option, drop a text file into templates/licenses/. Use {{YEAR}} and {{COPYRIGHT_HOLDER}} as placeholders — they'll be replaced during setup. The license menu is built dynamically from whatever files exist in that directory, so no code changes are needed.
- Andon Alert — Factory notification system for reporting issues to supervisors
- EzTaxes — S-Corp tax management dashboard with Gusto, Coinbase, and CashApp integrations
- Success — Tool for helping job-seekers build their resumes, ace interviews, and stay on task at work