Sail: environments & deployment

How to organize environment variables for Sail, teammates, and CI—and how that differs from staging/production. See also Sail overview, Databases, and Queues.

Navigation: All tools · Sail overview · Databases · Queues · Troubleshooting

Table of contents

  • .env, .env.example, secrets
  • **FORWARD_* ports and collisions](#forward-ports)
  • **APP_URL and trusted proxies](#app-url)
  • **Optional env_file in Compose](#compose-env-file)
  • **CI: GitHub Actions pattern](#ci-example)
  • **Sail vs dev/staging/prod servers](#not-production)
  • **Checklist before go-live](#checklist)

.env, .env.example, secrets

  • .env: local secrets; never commit. Copy from .env.example on first clone.
  • .env.example: safe defaults, document every key the app needs (DB_*, REDIS_*, QUEUE_*, MAIL_*, Scout, etc.). Sail-specific: WWWUSER, WWWGROUP, FORWARD_DB_PORT, …
  • Teams: agree whether host-run commands (e.g. npm on Mac) need any Laravel env; often only containerized commands matter.
  • Production: inject secrets via hosting provider, Vault, or CI masked variables—not a copied .env file on disk in the image.

FORWARD_* ports and collisions

Sail forwards DB, Redis, Meilisearch, etc. to localhost. When several projects run at once, set in .env:

FORWARD_DB_PORT=3307
FORWARD_REDIS_PORT=6380

Restart Compose after changes. Inside containers, ports stay default (3306, 6379); only host mapping changes.


APP_URL and trusted proxies

For browser-facing features (signed URLs, some OAuth callbacks), set:

APP_URL=http://localhost

Use the host port you actually open (e.g. http://localhost:80 if mapped). Behind Traefik/nginx on a real server, configure TrustProxies and real APP_URL with https.


Optional env_file in Compose

You can load an extra file in docker-compose.yml:

laravel.test:
    env_file:
        - .env
        - .env.docker.local

Use this for developer-specific overrides without editing shared .env. Document required keys in README to avoid “works on my machine” gaps.


CI: GitHub Actions pattern

Minimal idea: checkout, copy .env.ci.env, docker compose run tests.

- name: Run tests in Sail
  run: |
    cp .env.ci .env
    docker compose up -d
    docker compose exec -T laravel.test php artisan test

Adjust service names to your published compose file. Cache Composer/npm in CI separately from Docker layer cache to save time.


Sail vs dev/staging/prod servers

  • Sail optimizes developer ergonomics (Mailpit, forwarded ports, single-node DB).
  • Shared dev/staging often uses one long-lived environment; still not production HA.
  • Production needs TLS, backups, monitoring, log aggregation, queue supervision, database replicas, and secret rotation—none of which Sail solves by itself.

You may reuse the same Docker images built from Sail Dockerfiles, but orchestration (Compose file, env, scaling) will differ.


Checklist before go-live

  • [ ] APP_ENV=production, APP_DEBUG=false, strong APP_KEY
  • [ ] Real DB_* / REDIS_* endpoints (managed services)
  • [ ] QUEUE_CONNECTION matches a supervised worker setup
  • [ ] schedule:run in cron (or managed scheduler)
  • [ ] Mail/SMS/payment live keys in secret store
  • [ ] LOG_CHANNEL and retention appropriate for compliance

See also

← All tools