---
title: "Laravel Sail: структура .env, проброс портов, CI и отличие от продакшена | DevSense"
description: "Разделение конфигурации Laravel Sail и хоста: .env.example, порты FORWARD_*, APP_URL в Docker, опциональный env_file, запуск тестов в GitHub Actions и чек-листы для релиза."
faq:
  - question: "Почему при запуске sail up возникает ошибка 'port already allocated' (порт уже занят)?"
    answer: "Это происходит, когда другая служба на хост-машине (например, локальный MySQL или другой запущенный проект Sail) уже использует этот порт. Вы можете решить проблему, изменив параметры FORWARD_DB_PORT или APP_PORT в вашем файле .env."
  - question: "Стоит ли коммитить файл .env в Git?"
    answer: "Нет, коммитить .env ни в коем случае нельзя. Он содержит секреты и индивидуальные настройки разработчика. Вместо этого поддерживайте безопасные значения по умолчанию в файле .env.example."
  - question: "Как загрузить контейнерные настройки разработчика без изменения общего файла конфигурации?"
    answer: "Вы можете использовать список 'env_file' под вашей службой в docker-compose.yml для загрузки дополнительного локального файла (например, .env.docker.local), содержащего локальные переопределения."
  - question: "Можно ли использовать Laravel Sail на продакшене?"
    answer: "Нет. Sail разработан для удобства локальной разработки и не имеет необходимых для продакшена средств защиты, TLS-терминации, систем резервного копирования и оптимизации масштабирования. Развертывайте приложение с помощью специализированных инструментов (например, Kubernetes, Ansible или Laravel Forge)."
---

# Sail: окружения и деплой

Вы отправляете в GitHub локальный файл `.env` с паролями от базы данных, и системы безопасности мгновенно бьют тревогу. Или коллега скачивает ваш проект, запускает `sail up` и видит ошибку запуска, потому что локальный порт MySQL `3306` уже занят другим проектом. Управление конфигурацией окружения — это не просто заполнение пар ключ-значение; это четкое разграничение локального удобства, тестирования в CI/CD и защищенных боевых систем.

Контейнеризация меняет логику работы переменных окружения. Так как PHP работает внутри контейнера `laravel.test`, а базы данных привязаны к портам хост-машины, пути, URL-адреса и маппинг портов должны адаптироваться под то, откуда к ним обращаются — с вашего компьютера или из внутренней сети Docker Compose.

В этом руководстве мы разберем, как структурировать файлы `.env`, избегать конфликтов портов на хосте, настраивать CI-пайплайны на базе Docker и проверять настройки перед выходом в продакшен.

**Навигация:** [Все инструменты](../) · [Sail обзор](sail#what-sail-is) · [Базы данных](sail-databases#networking) · [Очереди](sail-queues#connections) · [Диагностика](sail-troubleshooting#wsl-filesync)

## Содержание

* [`.env`, `.env.example` и секреты](#env-files)
* [Порты `FORWARD_*` и конфликты](#forward-ports)
* [`APP_URL` и доверенные прокси](#app-url)
* [Опциональный `env_file` в Compose](#compose-env-file)
* [CI: Шаблон для GitHub Actions](#ci-example)
* [Sail против серверов разработки/staging/prod](#not-production)
* [Чек-лист перед запуском](#checklist)
* [Частые ошибки](#common-mistakes)
* [Вопросы для самопроверки](#self-check)

---

<a id="env-files"></a>
## `.env`, `.env.example` и секреты

- **`.env`**: Хранит секреты и настройки текущей локальной машины. **Никогда не добавляйте этот файл в систему контроля версий.**
- **`.env.example`**: Коммитится в Git. Значения по умолчанию должны быть безопасными и готовыми к тому, чтобы новый разработчик скопировал их в `.env` и сразу запустил проект через `sail up`.

```dotenv
# .env.example
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306

# Настройки портов Sail
FORWARD_DB_PORT=3306
FORWARD_REDIS_PORT=6379
```

---

<a id="forward-ports"></a>
## Порты `FORWARD_*` и конфликты

По умолчанию Sail привязывает базы данных и веб-сервер к локальным портам вашего компьютера. Если у вас запущено несколько проектов, такие порты, как `3306` (MySQL) или `80` (HTTP), вызовут конфликт.

Чтобы исправить это, переопределите порты в вашем `.env`:

```dotenv
# .env
APP_PORT=8080
FORWARD_DB_PORT=3307
FORWARD_REDIS_PORT=6380
```

> [!NOTE]
> **Внутренние порты против внешних**
> Изменение `FORWARD_DB_PORT` меняет порт, который прослушивается на вашей физической машине. Внутри сети Docker база данных по-прежнему общается по стандартному порту `3306`. В коде Laravel менять `DB_PORT` не требуется.

---

<a id="app-url"></a>
## `APP_URL` и доверенные прокси

Laravel использует `APP_URL` для генерации подписанных ссылок и редиректов.

```dotenv
# .env
APP_URL=http://localhost:8080
```

Убедитесь, что этот адрес совпадает с портом, проброшенным на ваш хост. При развертывании за балансировщиком нагрузки или обратным прокси-сервером (например, Nginx или Traefik) на продакшене настройте `TrustProxies` в Laravel для корректного считывания оригинального IP и протокола (HTTPS) клиента.

---

<a id="compose-env-file"></a>
## Опциональный `env_file` в Compose

Если у вас есть переменные окружения, которые должны применяться исключительно внутри контейнеров Docker, вы можете подгрузить их в `docker-compose.yml`:

```yaml
# docker-compose.yml
services:
    laravel.test:
        env_file:
            - .env
            - .env.docker.local
```

Это позволяет не забивать общий файл `.env` специфичными для контейнеров параметрами.

---

<a id="ci-example"></a>
## CI: Шаблон для GitHub Actions

Вы можете повторно использовать контейнеры Sail в вашем CI/CD конвейере для автоматического тестирования в изолированном окружении.

```yaml
# .github/workflows/tests.yml
name: Run Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Copy CI Env
        run: cp .env.ci .env
      - name: Start Sail
        run: docker compose up -d
      - name: Run Pest/PHPUnit
        run: docker compose exec -T laravel.test php artisan test
```

---

<a id="not-production"></a>
## Sail против серверов разработки/staging/prod

- **Sail** оптимизирован для скорости разработки на локальной машине (включает утилиты вроде Mailpit, Meilisearch и отладочные режимы).
- **Staging/Production** среды требуют жестких настроек безопасности, агрегации логов, резервного копирования данных, SSL/TLS-сертификатов и выделенных серверов БД (например, AWS RDS).

> [!NOTE]
> Никогда не запускайте `sail up` на публичных серверах. Конфигурация по умолчанию небезопасна и открывает доступ к отладочным утилитам извне.

---

<a id="checklist"></a>
## Чек-лист перед запуском

- [ ] Включены `APP_ENV=production` и `APP_DEBUG=false` на продакшене.
- [ ] Сгенерирован надежный ключ шифрования `APP_KEY` через `php artisan key:generate`.
- [ ] Настроено подключение к облачной базе данных вместо локального контейнера.
- [ ] `QUEUE_CONNECTION` переведен в `redis` или `sqs` под управлением Supervisor.
- [ ] Настроен SSL/HTTPS.
- [ ] Подключены внешние логгеры (например, Sentry или Bugsnag).

---

## ⚠️ Частые ошибки

**1. Коммит файла `.env` в систему контроля версий**
Публикация ключей API, паролей к БД и секретов в истории Git.
*Решение:* Перед коммитом всегда проверяйте, что файл `.env` добавлен в `.gitignore`.

**2. Изменение `DB_PORT` вместо `FORWARD_DB_PORT` для устранения локальных конфликтов**
Изменение `DB_PORT=3307` в файле `.env` без изменения конфигурации Sail нарушит подключение, поскольку контейнер базы данных продолжает слушать порт `3306`.
*Решение:* Оставляйте `DB_PORT=3306` (для внутренней связи контейнеров) и настраивайте `FORWARD_DB_PORT=3307` (для внешнего порта на компьютере).

**3. Использование `docker-compose.yml` от Sail на продакшене без изменений**
Запуск баз данных в контейнерах без репликации, бэкапов и политик разграничения прав доступа.
*Решение:* Конфигурация Sail — это локальный инструмент разработчика, а не манифест для деплоя.

---

## 🧠 Вопросы для самопроверки

1. **Почему изменение `DB_PORT=3307` в файле `.env` ломает миграции в Sail, тогда как изменение `FORWARD_DB_PORT=3307` работает корректно?**
2. **В чем заключается основная опасность развертывания Compose-файла Sail напрямую на боевом сервере?**
3. **Как использование секции `env_file` в `docker-compose.yml` помогает структурировать настройки проекта?**
4. **Какой файл необходимо обновить, чтобы команда узнала о добавлении нового обязательного ключа API?**

<details>
<summary><b>Показать ответы</b></summary>

1. Изменение `DB_PORT` заставляет Laravel искать базу данных на порту `3307` внутри сети контейнеров, где контейнер базы данных по-прежнему слушает порт `3306`. Изменение `FORWARD_DB_PORT` меняет только внешний порт, проброшенный на компьютер разработчика, не затрагивая внутренние связи Docker.
2. В продакшен попадут служебные dev-инструменты (Mailpit, Meilisearch), базы данных будут запущены без бэкапов и репликации, а контейнеры будут иметь избыточные права доступа.
3. Это позволяет разделять переменные по разным файлам (например, `.env` и `.env.docker.local`), подгружая специфичные для Docker переопределения без засорения основной конфигурации.
4. Необходимо обновить файл `.env.example`, указав в нем имя нового параметра и его пустое значение-плейсхолдер.
</details>
