Skip to content

Instantly share code, notes, and snippets.

@mariogarcia-ar
Last active June 26, 2025 12:25
Show Gist options
  • Select an option

  • Save mariogarcia-ar/c4bf6a7b283ab308e43727648b3da6fa to your computer and use it in GitHub Desktop.

Select an option

Save mariogarcia-ar/c4bf6a7b283ab308e43727648b3da6fa to your computer and use it in GitHub Desktop.

Laravel Sail Cheatsheet

Installation & Setup

Install Sail in existing project

composer require laravel/sail --dev
php artisan sail:install

Create new project with Sail

curl -s https://laravel.build/my-app | bash
cd my-app && ./vendor/bin/sail up

Basic Commands

Start/Stop Services

./vendor/bin/sail up        # Start all services
./vendor/bin/sail up -d     # Start in detached mode
./vendor/bin/sail down      # Stop all services
./vendor/bin/sail restart   # Restart services

Create Alias (Recommended)

alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'

Application Management

Artisan Commands

sail artisan migrate
sail artisan make:controller UserController
sail artisan queue:work
sail artisan tinker

Composer Commands

sail composer install
sail composer require package/name
sail composer update
sail composer dump-autoload

NPM/Node Commands

sail npm install
sail npm run dev
sail npm run build
sail yarn install
sail yarn dev

Database Operations

MySQL Commands

sail mysql                  # Connect to MySQL
sail mysql -u root -p      # Connect as root

Database Migrations & Seeding

sail artisan migrate
sail artisan migrate:fresh
sail artisan migrate:fresh --seed
sail artisan db:seed

Testing

PHPUnit Tests

sail test                   # Run all tests
sail test --filter=UserTest # Run specific test
sail test --coverage       # Run with coverage

Pest Tests

sail pest
sail pest --filter=user

Queue & Jobs

Queue Workers

sail artisan queue:work
sail artisan queue:listen
sail artisan queue:restart
sail artisan queue:failed

File Permissions & Storage

Fix Storage Permissions

sail root-shell
chown -R sail:sail /var/www/html/storage
chown -R sail:sail /var/www/html/bootstrap/cache

Access Container Shell

sail shell          # Access as sail user
sail root-shell     # Access as root user

Services & Ports

Default Services & Ports

View Running Containers

sail ps
docker ps

Useful Docker Commands

Container Management

sail exec app bash         # Execute bash in app container
sail logs                  # View logs
sail logs -f              # Follow logs

Database Backup/Restore

# Backup
sail exec mysql mysqldump -u sail -ppassword laravel > backup.sql

# Restore
sail exec -T mysql mysql -u sail -ppassword laravel < backup.sql

Configuration

Sail Configuration

sail artisan sail:publish  # Publish Sail configuration

Environment Variables

# .env file
APP_PORT=80
FORWARD_DB_PORT=3306
FORWARD_REDIS_PORT=6379
FORWARD_MEILISEARCH_PORT=7700
FORWARD_MAILHOG_PORT=1025
FORWARD_MAILHOG_DASHBOARD_PORT=8025

Custom Services

Add to docker-compose.yml:

selenium:
    image: 'selenium/standalone-chrome'
    volumes:
        - '/dev/shm:/dev/shm'
    networks:
        - sail

Debugging

Xdebug

sail up            # Xdebug enabled by default in local
sail shell
php -v            # Check if Xdebug is loaded

View Container Logs

sail logs app
sail logs mysql
sail logs redis

Production Tips

Build for Production

sail build --no-cache
sail up -d

Optimize Laravel

sail artisan config:cache
sail artisan route:cache
sail artisan view:cache
sail artisan optimize

Troubleshooting

Common Issues

# Port conflicts
sail down && sail up

# Permission issues
sail root-shell
chown -R sail:sail /var/www/html

# Clear caches
sail artisan cache:clear
sail artisan config:clear
sail artisan view:clear

# Rebuild containers
sail build --no-cache

Reset Everything

sail down -v           # Remove volumes
docker system prune -a # Clean Docker system
sail up -d            # Restart fresh

Quick Reference

Command Description
sail up -d Start services in background
sail down Stop all services
sail artisan Run Artisan commands
sail composer Run Composer commands
sail npm Run NPM commands
sail test Run PHPUnit tests
sail shell Access container shell
sail mysql Connect to MySQL
sail logs View container logs
# Laravel Sail with GitHub Actions CI/CD Cheatsheet

## Basic CI/CD Workflow

### Complete Test & Deploy Workflow
```yaml
# .github/workflows/laravel.yml
name: Laravel CI/CD

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: testing
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
      
      redis:
        image: redis:alpine
        ports:
          - 6379:6379
        options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
    - uses: actions/checkout@v4
    
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.2'
        extensions: mbstring, dom, fileinfo, mysql, redis
        coverage: xdebug

    - name: Copy .env
      run: php -r "file_exists('.env') || copy('.env.example', '.env');"

    - name: Install Dependencies
      run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

    - name: Generate key
      run: php artisan key:generate

    - name: Directory Permissions
      run: chmod -R 777 storage bootstrap/cache

    - name: Create Database
      run: |
        mkdir -p database
        touch database/database.sqlite

    - name: Execute tests (Unit and Feature tests) via PHPUnit
      env:
        DB_CONNECTION: mysql
        DB_HOST: 127.0.0.1
        DB_PORT: 3306
        DB_DATABASE: testing
        DB_USERNAME: root
        DB_PASSWORD: password
      run: vendor/bin/phpunit

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Deploy to production
      uses: appleboy/[email protected]
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.KEY }}
        script: |
          cd /var/www/html
          git pull origin main
          ./vendor/bin/sail down
          ./vendor/bin/sail up -d
          ./vendor/bin/sail artisan migrate --force
          ./vendor/bin/sail artisan config:cache
          ./vendor/bin/sail artisan route:cache
          ./vendor/bin/sail artisan view:cache
```

## Sail-Specific CI/CD Workflows

### Using Sail in GitHub Actions
```yaml
# .github/workflows/sail-ci.yml
name: Laravel Sail CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Setup Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Copy .env
      run: cp .env.example .env
    
    - name: Install Sail
      run: |
        composer install --no-dev --optimize-autoloader
        php artisan sail:install --with=mysql,redis
    
    - name: Start Sail
      run: ./vendor/bin/sail up -d
    
    - name: Wait for services
      run: ./vendor/bin/sail exec -T app sleep 30
    
    - name: Generate Application Key
      run: ./vendor/bin/sail artisan key:generate
    
    - name: Run Migrations
      run: ./vendor/bin/sail artisan migrate
    
    - name: Run Tests
      run: ./vendor/bin/sail test
    
    - name: Stop Sail
      run: ./vendor/bin/sail down
```

### Multi-Stage Testing with Different PHP Versions
```yaml
# .github/workflows/matrix-test.yml
name: Matrix Testing

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        php-version: [8.1, 8.2, 8.3]
        
    steps:
    - uses: actions/checkout@v4
    
    - name: Build Sail with PHP ${{ matrix.php-version }}
      run: |
        cp .env.example .env
        sed -i "s/SAIL_PHP_VERSION=.*/SAIL_PHP_VERSION=${{ matrix.php-version }}/" .env
        ./vendor/bin/sail build --no-cache
        ./vendor/bin/sail up -d
    
    - name: Run Tests
      run: ./vendor/bin/sail test
    
    - name: Cleanup
      run: ./vendor/bin/sail down -v
```

## Docker Registry Integration

### Build and Push to Docker Hub
```yaml
# .github/workflows/docker-build.yml
name: Build & Push Docker Image

on:
  push:
    tags: [ 'v*' ]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Login to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: your-username/your-app
    
    - name: Build and push
      uses: docker/build-push-action@v5
      with:
        context: .
        file: ./docker/8.2/Dockerfile
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
```

### Custom Dockerfile for Production
```dockerfile
# docker/production/Dockerfile
FROM sail-8.2/app:latest

WORKDIR /var/www/html

COPY . .

RUN composer install --no-dev --optimize-autoloader
RUN php artisan config:cache
RUN php artisan route:cache
RUN php artisan view:cache

EXPOSE 80

CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=80"]
```

## Advanced CI/CD Patterns

### Parallel Jobs for Speed
```yaml
# .github/workflows/parallel.yml
name: Parallel CI

on: [push, pull_request]

jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      cache-key: ${{ steps.cache-keys.outputs.key }}
    steps:
    - uses: actions/checkout@v4
    - name: Generate cache key
      id: cache-keys
      run: echo "key=${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}" >> $GITHUB_OUTPUT

  tests:
    needs: setup
    runs-on: ubuntu-latest
    strategy:
      matrix:
        test-suite: [unit, feature, browser]
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Start Sail
      run: |
        cp .env.example .env
        ./vendor/bin/sail up -d
    
    - name: Run ${{ matrix.test-suite }} tests
      run: ./vendor/bin/sail test --testsuite=${{ matrix.test-suite }}

  static-analysis:
    needs: setup
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Start Sail
      run: |
        cp .env.example .env
        ./vendor/bin/sail up -d
    
    - name: Run PHPStan
      run: ./vendor/bin/sail exec -T app ./vendor/bin/phpstan analyse
    
    - name: Run PHP CS Fixer
      run: ./vendor/bin/sail exec -T app ./vendor/bin/php-cs-fixer fix --dry-run --diff
```

### Database Seeding & Migration Testing
```yaml
# .github/workflows/database.yml
name: Database Testing

on: [push, pull_request]

jobs:
  migration-test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Start Sail with fresh database
      run: |
        cp .env.example .env
        ./vendor/bin/sail up -d
        ./vendor/bin/sail artisan migrate:fresh
    
    - name: Test migrations rollback
      run: ./vendor/bin/sail artisan migrate:rollback --step=5
    
    - name: Test migrations re-run
      run: ./vendor/bin/sail artisan migrate
    
    - name: Seed database
      run: ./vendor/bin/sail artisan db:seed
    
    - name: Test with seeded data
      run: ./vendor/bin/sail test --group=integration
```

## Environment-Specific Deployments

### Staging Deployment
```yaml
# .github/workflows/staging.yml
name: Deploy to Staging

on:
  push:
    branches: [ develop ]

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment: staging
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Deploy to staging server
      uses: appleboy/[email protected]
      with:
        host: ${{ secrets.STAGING_HOST }}
        username: ${{ secrets.STAGING_USERNAME }}
        key: ${{ secrets.STAGING_KEY }}
        script: |
          cd /var/www/staging
          git pull origin develop
          cp .env.staging .env
          ./vendor/bin/sail down
          ./vendor/bin/sail up -d
          ./vendor/bin/sail artisan migrate
          ./vendor/bin/sail artisan config:cache
```

### Production Deployment with Blue-Green
```yaml
# .github/workflows/production.yml
name: Production Deployment

on:
  push:
    tags: [ 'v*' ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Blue-Green Deployment
      uses: appleboy/[email protected]
      with:
        host: ${{ secrets.PROD_HOST }}
        username: ${{ secrets.PROD_USERNAME }}
        key: ${{ secrets.PROD_KEY }}
        script: |
          # Switch deployment slot
          if [ -f /var/www/current ]; then
            CURRENT=$(readlink /var/www/current)
            if [ "$CURRENT" = "/var/www/blue" ]; then
              TARGET="/var/www/green"
            else
              TARGET="/var/www/blue"
            fi
          else
            TARGET="/var/www/blue"
          fi
          
          cd $TARGET
          git pull origin main
          ./vendor/bin/sail down
          ./vendor/bin/sail up -d
          ./vendor/bin/sail artisan migrate --force
          ./vendor/bin/sail artisan optimize
          
          # Health check
          sleep 30
          if curl -f http://localhost:8080/health; then
            ln -sfn $TARGET /var/www/current
            nginx -s reload
          else
            echo "Health check failed"
            exit 1
          fi
```

## Security & Quality Gates

### Security Scanning
```yaml
# .github/workflows/security.yml
name: Security Scan

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Start Sail
      run: |
        cp .env.example .env
        ./vendor/bin/sail up -d
    
    - name: Security Audit
      run: ./vendor/bin/sail composer audit
    
    - name: Run Enlightn Security Checker
      run: ./vendor/bin/sail artisan enlightn --show-exceptions
```

### Code Quality Gates
```yaml
# .github/workflows/quality.yml
name: Code Quality

on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Start Sail
      run: |
        cp .env.example .env
        ./vendor/bin/sail up -d
    
    - name: Run tests with coverage
      run: ./vendor/bin/sail test --coverage --min=80
    
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage.xml
```

## Quick Reference

### Essential Secrets to Configure
```
DOCKERHUB_USERNAME=your-username
DOCKERHUB_TOKEN=your-token
HOST=your-server-ip
USERNAME=your-server-user
KEY=your-ssh-private-key
STAGING_HOST=staging-server-ip
PROD_HOST=production-server-ip
```

### Common Sail Commands in CI
```bash
# Setup
./vendor/bin/sail up -d
./vendor/bin/sail artisan key:generate

# Testing
./vendor/bin/sail test
./vendor/bin/sail pest
./vendor/bin/sail artisan dusk

# Database
./vendor/bin/sail artisan migrate:fresh --seed
./vendor/bin/sail artisan migrate --force

# Optimization
./vendor/bin/sail artisan optimize
./vendor/bin/sail artisan config:cache

# Cleanup
./vendor/bin/sail down -v
```

### Debugging CI Issues
```bash
# View logs
./vendor/bin/sail logs app
./vendor/bin/sail logs mysql

# Check container status
./vendor/bin/sail ps

# Execute commands in running container
./vendor/bin/sail exec app php artisan --version
```

Similar code found with 3 license types

Here’s a step-by-step tutorial for deploying a Laravel 12 project using Sail, running CI tests via GitHub Actions, and deploying to a DigitalOcean VPS.


πŸš€ Full Deployment Pipeline Tutorial (Sail + GitHub Actions + VPS)


βœ… 1. Local Setup with Laravel Sail

If you haven't already:

composer create-project laravel/laravel myapp
cd myapp
composer require laravel/sail --dev
php artisan sail:install --with=mysql,redis
./vendor/bin/sail up -d

πŸ” 2. Setup GitHub Repository

  1. Push your code to GitHub.
  2. Add .env.example if not already present.

πŸ€– 3. GitHub Actions for CI

Create a CI workflow at .github/workflows/ci.yml:

name: Laravel CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_DATABASE: sail
          MYSQL_USER: sail
          MYSQL_PASSWORD: password
          MYSQL_ROOT_PASSWORD: password
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
      - uses: actions/checkout@v3

      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'

      - name: Install Composer dependencies
        run: composer install --no-progress --prefer-dist

      - name: Setup ENV
        run: cp .env.example .env

      - name: Generate key
        run: php artisan key:generate

      - name: Run migrations
        run: php artisan migrate --force

      - name: Run tests
        run: php artisan test

🌐 4. Setup DigitalOcean VPS with Docker

  1. Create a Droplet (Ubuntu 22.04).
  2. SSH into the server:
ssh root@your-server-ip
  1. Install Docker and Docker Compose:
apt update
apt install docker.io docker-compose -y
usermod -aG docker $USER
  1. Clone your repo:
git clone https://github.com/yourname/yourrepo.git
cd yourrepo

🐳 5. Deploy Laravel Sail to VPS

  1. Copy your .env.production to .env.

  2. Modify .env:

    • Set APP_ENV=production
    • Set correct DB host, user, password
  3. Run Sail:

./vendor/bin/sail up -d

Laravel will be running on port 80 or 8000 (depending on your setup).


πŸ”’ 6. Optional: Enable HTTPS with Nginx and Let's Encrypt

Sail doesn't handle Nginx for production. If needed:

  • Proxy requests from host Nginx to laravel.test container
  • Use Certbot for SSL

πŸŽ‰ You Now Have:

  • Sail-powered Laravel app running in development
  • Automated testing via GitHub Actions
  • Remote deployment on a VPS with Docker Compose

Would you like me to generate scripts for VPS setup or Nginx proxy with HTTPS for this Sail deployment?

To automatically update your Laravel Sail app on your VPS whenever you push to GitHub, you need to implement CI/CD deployment automation. Here’s how you can do that:


πŸ”„ Auto-Deploy Laravel on Push Using GitHub Actions

🧱 Overview

On every push to your GitHub repo (e.g., to main), GitHub Actions will:

  1. SSH into your VPS.
  2. Pull the latest changes.
  3. Run deployment commands: Composer, migrations, etc.
  4. Restart Docker/Sail services.

πŸ›‘οΈ 1. Set Up SSH Key

On your local machine:

ssh-keygen -t rsa -b 4096 -C "github-actions"

Add the public key (~/.ssh/id_rsa.pub) to your VPS:

ssh-copy-id root@your-server-ip

Add the private key (~/.ssh/id_rsa) to GitHub Secrets:

Name Value
VPS_SSH_KEY contents of id_rsa
VPS_HOST e.g., your-server-ip
VPS_USER root or custom user
APP_DIR e.g., /var/www/myapp

βš™οΈ 2. GitHub Actions Workflow for Deployment

Create .github/workflows/deploy.yml:

name: Deploy to VPS

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup SSH
        uses: webfactory/[email protected]
        with:
          ssh-private-key: ${{ secrets.VPS_SSH_KEY }}

      - name: Deploy via SSH
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} << 'EOF'
            cd ${{ secrets.APP_DIR }}
            git pull origin main
            ./vendor/bin/sail composer install --no-dev --optimize-autoloader
            ./vendor/bin/sail artisan migrate --force
            ./vendor/bin/sail up -d --build
          EOF

βœ… What Happens on Push?

  • GitHub triggers the workflow.
  • It authenticates to your VPS via SSH.
  • Pulls the latest code.
  • Rebuilds Docker containers if needed.
  • Runs migrations and restarts services.

Would you like me to generate the actual files or secret setup scripts for this auto-deployment flow?

Certainly! In Laravel Sail, you can extend and customize the behavior of the stack (especially laravel.test) through custom scripts and configurations. Here’s how it works:


πŸ”§ 1. Custom Scripts

Sail allows adding custom scripts in your Laravel project to run specific commands or adjust service behavior.

πŸ“ Location:

  • Add shell scripts to .docker/entrypoint.d/ or .docker/scripts/ inside your project.

✨ Example: Custom startup script

Create a file: .docker/entrypoint.d/99-custom.sh

#!/bin/bash
echo "πŸ› οΈ Running custom setup..."
php artisan config:clear
php artisan migrate --force

Make it executable:

chmod +x .docker/entrypoint.d/99-custom.sh

Sail will execute this when the laravel.test container starts.


βš™οΈ 2. Custom Dockerfile

You can override the default Sail image to add PHP extensions, Node tools, or custom binaries.

🧱 Example: Dockerfile

Create a Dockerfile:

FROM laravelsail/php83-composer

# Install system dependencies
RUN apt-get update && apt-get install -y \
    libpq-dev \
    jpegoptim optipng pngquant gifsicle \
    unzip git curl

# Optional: Install Node and npm/yarn manually

Then update your docker-compose.yml:

laravel.test:
  build:
    context: .
    dockerfile: Dockerfile

🧩 3. Custom Nginx Config

To use a custom Nginx configuration, you’ll need to manually decouple from Sail’s built-in server. In a full custom setup (not default Sail), define your Nginx in docker-compose.yml and mount a config file:

services:
  nginx:
    image: nginx:alpine
    volumes:
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf

πŸ“œ 4. Environment Overrides

You can customize environment variables per service using .env and .env.testing.

For example, to run Sail with a specific port:

APP_PORT=8080

Then access via http://localhost:8080.


Would you like help creating a sample custom Dockerfile or startup script tailored to your Laravel 12 app?

Setting up CI/CD with GitHub Actions for a Laravel project using Sail is entirely possible and enables automated testing and deployment workflows.

Here’s a complete breakdown:


πŸš€ Why Use GitHub Actions with Sail?

  • Run Laravel tests in a Docker environment matching your local dev setup.
  • Automatically lint, test, and deploy code on push or pull request.

πŸ› οΈ Sample GitHub Actions Workflow for Laravel Sail

Create a GitHub Actions workflow file at .github/workflows/laravel.yml:

name: Laravel CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  laravel-tests:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: sail
          MYSQL_USER: sail
          MYSQL_PASSWORD: password
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

    steps:
      - uses: actions/checkout@v3

      - name: Set up Laravel Sail environment
        run: cp .env.example .env && ./vendor/bin/sail up -d

      - name: Wait for MySQL to be ready
        run: |
          for i in {1..10}; do
            docker-compose exec mysql mysql -usail -ppassword -e "SELECT 1" && break
            echo "Waiting for MySQL..."
            sleep 5
          done

      - name: Install Composer dependencies
        run: ./vendor/bin/sail composer install --prefer-dist --no-progress --no-suggest

      - name: Generate application key
        run: ./vendor/bin/sail artisan key:generate

      - name: Run migrations
        run: ./vendor/bin/sail artisan migrate --force

      - name: Run tests
        run: ./vendor/bin/sail test

πŸ“Œ Key Highlights

  • Service: Uses Docker MySQL as a service.
  • Sail: Commands are run using ./vendor/bin/sail ....
  • Parallelism: You can add more steps (e.g., lint, deploy) as needed.

πŸ”’ Security Tip

Avoid storing sensitive .env data in the repo β€” use GitHub Secrets for anything private like API keys or DB credentials.


Would you like to extend this with automatic deployment (e.g., to Forge, Ploi, or VPS)?

Here's a concise and practical tutorial for using profiles in Docker Compose, ideal for managing different service configurations like "minimal" vs "full stack" environments.


🧩 Tutorial: Using Profiles in Docker Compose

πŸ” What Are Profiles?

Profiles in Docker Compose allow you to group services together and selectively start them depending on the environment or workflow (e.g., development, testing, production).

Think of it like toggling between "minimal" and "full" environments:

  • minimal: only essential services (e.g., Laravel + MySQL)
  • full: all services (e.g., Redis, RabbitMQ, Mailpit, etc.)

🧱 1. Add Profiles to Your docker-compose.yml

Here's a simplified example:

services:
  laravel.test:
    image: sail-8.4/app
    profiles:
      - minimal
      - full

  mysql:
    image: mysql:8
    profiles:
      - minimal
      - full

  redis:
    image: redis:alpine
    profiles:
      - full

  rabbitmq:
    image: rabbitmq:management
    profiles:
      - full

πŸš€ 2. Use Profiles at Runtime

You can specify which profile(s) to activate when starting Docker Compose.

▢️ Minimal Stack

docker compose --profile minimal up

▢️ Full Stack

docker compose --profile full up

You can combine profiles if needed:

docker compose --profile minimal --profile full up

⛔️ Stop Everything

docker compose down

πŸ“Œ 3. Use .env to Control Profiles (Optional)

You can define a variable to help conditionally set profiles.

.env

ACTIVE_PROFILE=full

Then script it in your shell:

docker compose --profile $ACTIVE_PROFILE up

πŸ§ͺ 4. Verify What’s Running

docker compose ps

You'll see only services from the active profile.


πŸ“š Use Cases

Use Case Profile
Fast development startup minimal
End-to-end integration testing full
Local performance benchmarking full
CI pipeline (e.g. GitHub/Bitbucket Actions) minimal or custom

βœ… Benefits

  • 🧹 Cleaner startup: Avoid loading unneeded services.
  • βš™οΈ Better performance: Only start what you need.
  • πŸ§ͺ Custom test environments: Define ci, debug, monitoring, etc.
  • 🧩 Modular design: Easily extend stack with optional services.

🧠 Pro Tip

You can still override profiles manually for quick testing:

docker compose run --no-deps redis redis-cli ping

This runs a service outside its profile.


🏁 Summary

Profiles are powerful for:

  • Environment segmentation
  • Simplified CI/CD
  • Faster development
  • Modular docker-compose setups

Would you like a Makefile or shell script to automate profile selection, or integrate it with GitHub Actions or Bitbucket Pipelines?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment