---
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` на публічних серверах. Конфігурація за замовчуванням є небезпечною та відкриває доступ до службових dev-інструментів ззовні.

---

<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>
