Laravel Sail project setup tool with automatic port assignment, SSL certificates, and local domain configuration.
- 🚢 Automatic Port Assignment - Intelligent port allocation across multiple Sail projects
- 🔍 Port Conflict Detection - Prevents conflicts with running services and other projects
- 🌐 Local Domain Registration - Seamless integration with Valet/Herd
- 🔒 SSL Certificate Management - Automatic SSL setup and symlinking
- 📦 Composer Installation - Handles private repository authentication
- 🧙 Interactive Setup Wizard - Collects all input upfront, then runs unattended
- 🔄 Self-Updating - Built-in update mechanism via
--updateflag
- OS: macOS, Linux, or Windows (with Git Bash or WSL)
- Docker: Docker Desktop installed and running
- Project: Laravel Sail project with
docker-compose.yml - Optional: Laravel Valet or Laravel Herd (for domain registration features)
One-line installation for all platforms:
curl -fsSL https://raw.githubusercontent.com/wotzebra/shipyard/main/install.sh | bashAfter installation, restart your terminal or run:
source ~/.bashrc # or ~/.zshrc depending on your shell-
Download the latest release:
curl -fsSL http://github.com/wotzebra/shipyard/releases/latest/download/shipyard.sh -o ~/.local/bin/shipyard chmod +x ~/.local/bin/shipyard
-
Ensure
~/.local/binis in your PATH:export PATH="$HOME/.local/bin:$PATH"
Navigate to your Laravel Sail project directory and run:
shipyard initThe wizard will guide you through:
- Composer Authentication - Provide credentials for private repositories
- Port Assignment - Automatic detection and conflict resolution
- Domain Registration (Optional) - Register a
.testdomain via Valet/Herd - Protocol Selection (If domain registered) - Choose between HTTPS (secure) or HTTP
- SSL Certificates (If HTTPS selected) - Automatic certificate setup
- Post-Setup Commands (Optional) - Start containers and run Laravel setup
shipyard init # Initialize project setup
shipyard list # Show all registered projects
shipyard cleanup # Clean up stale projects from registry
shipyard --version # Show version
shipyard --update # Update to latest version
shipyard --help # Show helpShipyard maintains a global registry at ~/.config/shipyard/projects.conf that tracks project configurations including port assignments, domains, and proxy services across all your Sail projects. This prevents port conflicts when running multiple projects simultaneously.
Registry format:
[project-name]
path=/path/to/project
domain=my-project.test
proxy_service=valet
proxy_secure=true
APP_PORT=8000
VITE_PORT=5100
FORWARD_DB_PORT=3300The domain, proxy_service, and proxy_secure fields are optional and only present if you registered a local domain through Valet or Herd. The proxy_secure field indicates whether HTTPS (true) or HTTP (false) was configured.
-
Conversion - Converts standard ports to 4-digit ports ending in 00
80→80003306→33005173→5100
-
Availability Check - Verifies port is not:
- In the global registry (used by another project)
- In use on the system (checked via
/dev/tcpandlsof)
-
Auto-Increment - If port is taken, increments by 1 until available port is found
-
Environment Configuration - Writes port assignments to
.envfile:# Auto-assigned Docker Ports (via shipyard.sh) COMPOSE_PROJECT_NAME=project_name APP_URL=http://localhost:8000 VITE_SERVER_HOST=localhost ASSET_URL="${APP_URL}" APP_PORT=8000 VITE_PORT=5100 FORWARD_DB_PORT=3300
If you have Valet or Herd installed, Shipyard can:
- Register Proxy - Creates a proxy:
myproject.test→http://localhost:8000 - Choose Protocol - Select between HTTPS (with SSL) or HTTP (without SSL)
When you choose HTTPS:
- SSL Certificates - Automatically generates SSL certificate via
--secureflag - Symlink Certificates - Creates symlinks in
certificates/directory:certificates/cert.crt→ Valet/Herd certificatecertificates/cert.key→ Valet/Herd private key
- Update APP_URL - Sets
APP_URL=https://myproject.testin.env - Update .gitignore - Adds
/certificatesto.gitignore
Result: Access your app via https://myproject.test with valid SSL certificate.
When you choose HTTP:
- Non-Secure Proxy - Creates proxy without SSL certificates
- Create Empty Certificates - Creates empty
cert.keyandcert.crtfiles incertificates/directory - Update APP_URL - Sets
APP_URL=http://myproject.testin.env - Update .gitignore - Adds
/certificatesto.gitignore
Result: Access your app via http://myproject.test (no SSL certificate needed).
When you choose not to register a domain:
- Create Empty Certificates - Creates empty
cert.keyandcert.crtfiles incertificates/directory - Update .gitignore - Adds
/certificatesto.gitignore
Result: Empty certificate files are created to prevent Docker mount errors. Access your app via http://localhost:8000.
When you register a domain with HTTPS mode, Shipyard creates certificate symlinks in the certificates/ directory and automatically adds /certificates to your .gitignore file. To use these certificates with Vite's dev server inside your Sail container:
Add the certificates volume mounts to your docker-compose.yml:
services:
laravel.test:
volumes:
- type: bind
source: './certificates/cert.key'
target: /var/www/certificates/cert.key
read_only: true
- type: bind
source: './certificates/cert.crt'
target: /var/www/certificates/cert.crt
read_only: trueNote: The read_only: true flag prevents accidental modification of your SSL certificates.
Important: The certificates/ directory is automatically added to your .gitignore file by Shipyard, as these are symlinks to your local Valet/Herd certificates and should not be committed to version control.
Update your vite.config.js to use the certificates when running in HTTPS mode:
import tailwindcss from '@tailwindcss/vite';
import laravel from 'laravel-vite-plugin';
import {defineConfig, loadEnv} from 'vite';
import fs from 'fs';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
build: {
sourcemap: true,
},
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
tailwindcss(),
],
...(env.VITE_SERVER_HOST !== 'localhost' && {
server: {
host: env.VITE_SERVER_HOST,
hmr: {
host: env.VITE_SERVER_HOST,
},
...(fs.existsSync('/var/www/certificates/cert.key') && fs.existsSync('/var/www/certificates/cert.crt') && fs.statSync('/var/www/certificates/cert.key').size > 0 && fs.statSync('/var/www/certificates/cert.crt').size > 0 && {
https: {
key: fs.readFileSync('/var/www/certificates/cert.key'),
cert: fs.readFileSync('/var/www/certificates/cert.crt'),
},
}),
},
}),
};
});When Shipyard registers a domain (with or without HTTPS mode), it automatically updates your .env file:
APP_URL=https://myproject.test
VITE_SERVER_HOST=myproject.test
ASSET_URL="${APP_URL}"How it works:
- When
VITE_SERVER_HOSTis set to your domain (notlocalhost), Vite uses that domain as its host - When SSL certificates are available, Vite uses HTTPS with the mounted certificates
- Hot Module Replacement (HMR) connects via
wss://myproject.test - Assets are served on the correct domain (with valid SSL certificates)
# Start Sail containers
sail up -d
# Start Vite dev server (with HTTPS)
sail npm run devYour app will be accessible at https://myproject.test with:
- Valid SSL certificate (no browser warnings)
- Hot Module Replacement working over WSS
- All assets served securely
Shipyard automatically checks for updates when you run it and will prompt you to update if a newer version is available.
To manually update to the latest version:
shipyard --updateThis will:
- Check GitHub for the latest release
- Download and replace the current script
- Preserve executable permissions
- Show version change information
Note: The automatic update check has a 5-second timeout and fails silently if GitHub is unreachable, so it won't block your workflow.
Remove the script:
rm ~/.local/bin/shipyardRemove the port registry (optional):
rm -rf ~/.config/shipyardRemove PATH entry from shell config (optional):
# Edit ~/.bashrc or ~/.zshrc and remove:
export PATH="$HOME/.local/bin:$PATH"Cause: ~/.local/bin is not in your PATH.
Solution:
- Restart your terminal, or
- Run:
source ~/.bashrc(or~/.zshrc), or - Manually add to PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc
Cause: Docker Desktop is not started.
Solution:
- Start Docker Desktop
- Verify with:
docker info
Cause: Docker has run out of available IP address ranges due to too many unused networks.
Solution:
Shipyard will automatically detect this issue and offer to clean up unused networks. You can also manually clean up:
docker network prune -fOr remove specific networks:
docker network ls
docker network rm <network-id>Prevention: Regularly clean up stopped containers and unused networks:
docker system prune -fCause: Port is in use by another service or project.
Solution: Shipyard automatically handles this by incrementing to the next available port. No action needed.
Cause: Project already has port assignments in the registry.
Solution:
- To re-assign ports: Remove the project section from
~/.config/shipyard/projects.conf - Or: Use the existing port assignments (check your
.envfile)
Cause: The domain is already proxied to another project.
Solution:
- Choose a different domain name, or
- Remove the existing proxy:
valet unproxy domain-name # or: herd unproxy domain-name
Requirement: Shipyard requires bash to run.
Solutions:
- Git Bash (Recommended) - Comes with Git for Windows
- Install Git for Windows: https://git-scm.com/download/win
- Run shipyard from Git Bash terminal
- WSL (Windows Subsystem for Linux)
- Install WSL: https://docs.microsoft.com/en-us/windows/wsl/install
- Run shipyard from WSL terminal
Not Supported:
- PowerShell (requires bash)
- Command Prompt (requires bash)
shipyard/
├── README.md # This file
├── CHANGELOG.md # Version history
├── LICENSE # MIT license
├── shipyard.sh # Main script
└── install.sh # Installation script
git clone http://github.com/wotzebra/shipyard.git
cd shipyard
chmod +x shipyard.sh
./shipyard.sh --help-
Update version in
shipyard.sh:readonly VERSION="0.2.0"
-
Update
CHANGELOG.md:## [0.2.0] - 2025-XX-XX ### Added - New feature
-
Commit and tag:
git add . git commit -m "Release v0.2.0" git tag -a v0.2.0 -m "Version 0.2.0" git push origin main git push origin v0.2.0
-
Create GitHub Release:
- Go to: http://github.com/wotzebra/shipyard/releases/new
- Select tag:
v0.2.0 - Upload
shipyard.shas release asset - Publish release
MIT License - see LICENSE file for details.
Issues and pull requests are welcome!
- Bug Reports: http://github.com/wotzebra/shipyard/issues
- Feature Requests: http://github.com/wotzebra/shipyard/issues
- Pull Requests: http://github.com/wotzebra/shipyard/pulls
Built by the team at Who Owns The Zebra for streamlined Laravel Sail project setup.