Локальный веб-сервер Symfony

Дата обновления перевода 2024-07-29

Локальный веб-сервер Symfony

Вы можете запускать приложения Symfony с любым веб-сервером (Apache, nginx, внутренний веб-сервер PHP, и др.). Однако, Symfony предоставляет собственный веб-сервер, чтобы сделать вас более продуктивным во время разработки ваших приложений.

Хотя этот сервер не предназначен для использования в производстве, он поддерживает HTTP/2, TLS/SSL, автоматическое генерирование сертификатов безопасности, локальные домены, и многие другие функции, которые рано или поздно понадобятся вам во время разработки веб-проектов. Более того, сервер не привязан к Symfony, и вы также можете использовать его с любым PHP-приложением, и даже с HTML или приложениями одной страницы.

Установка

Сервер Symfony является частью бинарности symfony, созданной, когда вы устанавливаете Symfony, и имеет поддержку для Linux, macOS и Windows.

Note

Вы можете просмотреть и сделать свой вклад в источник Symfony CLI в хранилище symfony-cli/symfony-cli GitHub.

Начало работы

Сервер Symfony запускается один раз в проекте, поэтому у вас может получиться несколько экземпляров (каждый из них будет слушать разные порты). Вот типичный рабочий процесс обслуживания проекта Symfony:

1
2
3
4
5
6
7
8
$ cd my-project/
$ symfony server:start

  [OK] Web server listening on http://127.0.0.1:....
  ...

# Теперь, перейдите по заданному URL, или выполните эту команду:
$ symfony open:local

Запуск сервера таким образом может отобразить сообщение лога в консоли, поэтому вы не сможете выполнять другие команды одновременно. Если вы хотите, вы можете запустить сервер Symfony фоново:

1
2
3
4
5
6
7
8
9
$ cd my-project/

# запустите сервер фоново
$ symfony server:start -d

# продолжайте работать и выполнять другие команды...

# покажите последние сообщения лога
$ symfony server:log

Tip

На macOS при запуске сервера Symfony может появиться диалоговое окно с предупреждением "Do you want the application to accept incoming network connections?"_. Это происходит при запуске неподписанных приложений, не включенных в список брандмауэра. Решением проблемы является выполнение этой команды, которая подписывает бинарность Symfony:

1
$ sudo codesign --force --deep --sign - $(whereis -q symfony)

Подключение PHP-FPM

Note

PHP-FPM должен быть установлен локально для использования сервера Symfony.

Когда сервер запускается, он проверяет web/index_dev.php, web/index.php, public/app_dev.php, public/app.php в таком порядке. Если найден один из них, сервер автоматически запустится с подключенным PHP-FPM. В других случаях, сервер запустится без PHP-FPM, и отобразит страницу Страница не найдена, при попытке получить доступ к файлу .php в браузере.

Tip

Когда присутствует и index.html, и фронт-контроллер, вроде index.php, сервер запустится с подключенным PHP-FPM, но index.html будет главенствовать над фронт-контроллером. Это означает, что когда в public или web есть файл index.html, он будет отображен вместо index.php, что покажет, к примеру, приложение Symfony.

Подключение TLS

Локальный просмотр безопасной версии ваших приложений важен для того, чтобы обануржить проблемы со смешанным содержанием как можно раньше, и чтобы запускать библиотеки, работающие только на HTTPS. По традиции это было больно и сложно настраивать, но сервер Symfony автоматизирует все. Для начала, выполните команду:

1
$ symfony server:ca:install

Эта команда создает локальный авторитет сертификата, регистрирует его в вашем хранилище доверия системы, в Firefox (необходимо только для этого браузера), и создает сертификат по умолчанию для localhost и 127.0.0.1. Другими словами, она все делает за вас.

Tip

Если вы делаете это в WSL (подсистема Windows для Linux), только что созданный локальный центр сертификации необходимо вручную импортировать в Windows. Файл находится в wsl по адресу ~/.symfony5/certs/default.p12. Самый простой способ это запустить explorer.exe \`wslpath -w $HOME/.symfony5/certs\ из wsl. и дважды щелкнуть на файле default.p12.

До просмотра вашего локального приложения с HTTPS вместо HTTP, перезапустите его сервер, остановив и запустив его снова.

Разные PHP-настройки для каждого проекта

Выбор другой PHP-версии

Если у вас на компьютере установлено несколько версий PHP, вы можете сообщить Symfony, какую использовать, создав файл под названием .php-version в корневом каталоге приложения:

1
2
3
4
5
6
7
$ cd my-project/

# использовать конкретную версию PHP
$ echo 7.4 > .php-version

# использовать любую доступную версию PHP 8.x
$ echo 8 > .php-version

Tip

Сервер Symfony траверсирует структуру каталогов до корневого каталога, поэтому вы можете создать файл .php-version в каком-то родительском каталоге, чтобы установить одинаковую PHP-версию для группы проектов под этим каталогом.

Запустите команду ниже, если вы не помните все установленные на вашем компьютере PHP-версии:

1
2
3
4
5
$ symfony local:php:list

  # Вы увидите все поддерживаемые SAPI (CGI, FastCGI, и др.) для каждой версии.
  # FastCGI (php-fpm) используется там, где это возможно; затем CGI (который также действует,
  # как сервер FastCGIserver), и, наконец, сервер откатывается до обычного CGI.

Переопределение опций конфигурации PHP для каждого проекта

Вы можете изменить значение любой опции конфигурации прогона PHP для проекта, создав файл под названием php.ini в корневом каталоге проекта. Добавьте только опции, если хотите переопределить:

1
2
3
4
5
6
$ cd my-project/

# этот проект переопределяет только часовой пояс PHP по умолчанию
$ cat php.ini
[Date]
date.timezone = Asia/Tokyo

Запуск команд с разными версиями PHP

При запуске разных PHP-версий, полезно использовать основную команду symfony в качестве обертки команды php. Это позволяет вам всегда выбирать наиболее подходящую версию PHP в соответствии с проектом, который выполняет команды. Это также автоматически загружает переменные окружения, что важно при выполненни не-Symfony команд:

1
2
3
4
5
6
# выполняет команду с версией PHP по умолчанию
$ php -r "..."

# выполняет команду с версией PHP, выбранной проектом
# (или версией PHP по умолчанию, если проект не выбрал версию)
$ symfony php -r "..."

Имена локальных доменов

По умолчанию, проекты доступны с произвольного порта локального IP 127.0.0.1. Однако, иногда лучше ассоциировать с ними имя домена:

  • Это более удобно, когда вы беспрерывно работаете над одним проектом, так как номера портов могут изменяться, а домены - нет;
  • Поведение некоторых приложений зависит от их доменов/субдоменов;
  • Наличие стабильных конечных точек, вроде локального перенаправления URL для OAuth2.

Настройка локального прокси

Локальные домены возможны благодаря локальному прокси, предоставленному сервером Symfony. Если это первый раз, когда вы запускаете прокси, вы должны сконфигурировать его следующим образом:

  1. Откройте настройки прокси вашей ОС:

  2. Установите следующий URL как значение Автоматической конфигурации прокси: http://127.0.0.1:7080/proxy.pac

Теперь, выполните эту команду, чтобы запустить прокси:

1
$ symfony proxy:start

Если прокси не работает так, как объясняется в следующих разделах, прочитайте следующее:

  • Некоторые браузеры (например, Chrome) требуют повторного применения настроек прокси (нажатия на кнопку Re-apply settings на странице chrome://net-internals/#proxy) или полной перезагрузки после запуска прокси. Иначе вы увидите ошибку "Эта страница не доступна" (ERR_NAME_NOT_RESOLVED);
  • Некоторые ОС (например, macOS) по умолчанию не применяют настройки прокси к локальным хостам и доменам. Вам может понадобиться удалить *.local и/или другие IP-адреса из этого списка.
  • Операционная система Windows требует localhost вместо 127.0.0.1 при конфигурации автоматического прокси, иначе вы не сможете получить доступ к локальному домену из браузера, работающего в Windows.

Определение локального домена

По умолчанию, Symfony предлагает .wip (означает Незавершенная работа) для локальных доменов. Вы можете определить локальный домен для вашего проекта следующим образом:

1
2
$ cd my-project/
$ symfony proxy:domain:attach my-domain

Если вы установили локальный прокси, как объясняется в предыдущем разделе, вы теперь можете перейти на https://my-domain.wip, чтобы получить доступ к вашему локальному проекту с новым пользовательским доменом.

Tip

Перейдите по URL http://127.0.0.1:7080, чтобы получить полный список локальных каталогов проекта, их пользовательские домены и номера портов.

Вы также можете добавить домен с подстановочным знаком:

1
$ symfony proxy:domain:attach "*.my-domain"

Таким образом, он будет соответствовать всем поддоменам, таким как https://admin.my-domain.wip, https://other.my-domain.wip...

При выполненни команд консоли, добавьте переменную окружения https_proxy, чтобы пользовательские домены заработали:

1
2
3
4
5
6
7
8
# Пример с curl
$ https_proxy=$(symfony proxy:url) curl https://my-domain.wip

# Пример с Blackfire и curl
$ https_proxy=$(symfony proxy:url) blackfire curl https://my-domain.wip

# Пример с Cypress
$ https_proxy=$(symfony proxy:url) ./node_modules/bin/cypress open

Caution

Хотя имена переменных окружения всегда определяются в верхнем регистре, переменная окружения другая, чем остальные переменные окружения, и ее имя прописывается в нижнем регистре.

Tip

Если вы предпочитаете использовать другой TLD, отредактируйте файл ~/.symfony/proxy.json (где ~ означает путь к вашему каталогу пользователя) и измените значение опции tld с wip на любой другой TLD.

Долгосрочные команды

Долгосроные команды, такие как те, что компилируют форнтэнд веб-ресурсы, блокируют терминал, и вы не можете выполнять другие команды в то же время. Сервер Symfony предоставляет команду run, чтобы обернуть их следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# скомпилируйте ресурсы Webpack, используя Symfony Encore ... но сделайте это
# фоново, чтобы не блокировать терминал
$ symfony run -d yarn encore dev --watch

# продолжайте работать и выполнять другие команды...

# время от времени, проверяйте логи команд, если хотите
$ symfony server:log

# и вы также можете проверить, выполняется ли еще команда
$ symfony server:status
Web server listening on ...
Command "yarn ..." running with PID ...

# остановите веб-сервер (и все ассоциированные команды), когда вы закончите
$ symfony server:stop

Файл конфигурации

Существует несколько опций, которые вы можете установить, используя файл конфигурации
.symfony.local.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Устанаваливает domain1.wip и domain2.wip для текущего проекта
proxy:
    domains:
        - domain1
        - domain2

http:
    document_root: public/ # Путь к корню документа проекта
    passthru: index.php # Индекс прохождения проекта
    port: 8000 # Форсировать порт, который будет использоваться для запуска сервера
    preferred_port: 8001 # Preferred HTTP port [default: 8000]
    p12: path/to/p12_cert # Имя файла, содержащего сертификат TLS для использования, в формате p12
    allow_http: true # Предотвратить автоматическое перенаправление с HTTP на HTTPS
    no_tls: true # Использовать HTTP вместо HTTPS
    daemon: true # Запустить сервер фоново
    use_gzip: true # Включить сжатие GZIP

Caution

Установка доменов в этом конфигурационном файле переопределит все домены, установленные вами с помощью команды proxy:domain:attach для текущего проекта при запуске сервера.

Конфигурация работников

Если вы хотите, чтобы какие-то процессы начинались автоматически вместе с веб-сервером (symfony server:start), добавьте файл конфигурации в ваш проект:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# .symfony.local.yaml
workers:
    # встроенная команда, которая создает и следит за ресурсами фронт-энда
    # yarn_encore_watch:
    #     cmd: ['yarn', 'encore', 'dev', '--watch']
    yarn_encore_watch: ~

    # встроенная команда, которая запускает потребителя мессенджера
    # messenger_consume_async:
    #     cmd: ['symfony', 'console', 'messenger:consume', 'async']
    #     watch: ['config', 'src', 'templates', 'vendor']
    messenger_consume_async: ~

    # вы также можете добавить ваши пользовательские команды
    build_spa:
        cmd: ['yarn', '--cwd', './spa/', 'dev']

    # автоматический запуск Docker compose при запуске сервера (доступно с Symfony CLI 5.7.0)
    docker_compose: ~

Tip

Вы можете не запускать работников в некоторых окружениях, например в CI. Вы можете использовать no-workers, чтобы запустить сервер без запуска работников.

Интеграция Docker

Локальный сервер Symfony предоставляет полную интеграцию Docker для проектов, которые ее используют. Чтобы узнать больше о Docker и Symfony, см. Использование Docker с Symfony.

Когда веб-сервер определяет, что для проекта запущен Docker Compose, он автоматически демонстрирует некоторые переменные окружения.

Через API docker-compose, он ищет раскрытые порты, используемые для распространенных сервисов. Когда он обнаруживает тот, о котором знает, он использует имя сервиса, чтобы продемонстрировать переменные окружения.

Рассмотрите следующую конфигурацию:

1
2
3
4
# docker-compose.yaml
services:
    database:
        ports: [3306]

Веб-сервер определяет, что сервис, раскрывающий порт 3306 работает для проекта. Он понимает, что это - сервис MySQL, и создает переменные окружения в соответствии с именем сервиса (database) в качестве префикса: DATABASE_URL, DATABASE_HOST, ...

Если сервис не находится в списке поддерживаемых ниже, устанавливаются общие переменные окружения: PORT, IP, и HOST.

Если имена docker-compose.yaml не совпадают с соглашениями Symfony, добавьте ярлык, чтобы переопределить префикс переменных окружения:

1
2
3
4
5
6
# docker-compose.yaml
services:
    db:
        ports: [3306]
        labels:
            com.symfony.server.service-prefix: 'DATABASE'

В этом примере, сервис называется db, поэтому переменные окружения будут иметь префикс DB_, но так как com.symfony.server.service-prefix установлен, как DATABASE, веб-сервер создает переменные окружения, начинающиеся с DATABASE_ вместо того, что ожидается конфигурацией Symfony по умолчанию.

Вот список всех поддерживаемых сервисов с их портами, и префиксов Symfony по умолчанию:

?????? ???? ??????? Symfony ?? ?????????
MySQL 3306 DATABASE_
PostgreSQL 5432 DATABASE_
Redis 6379 REDIS_
Memcached 11211 MEMCACHED_
RabbitMQ 5672 RABBITMQ_ (?????????? ???????????? ? ???????? ????? ?????????? ????????? Docker RABBITMQ_DEFAULT_USER ? RABBITMQ_DEFAULT_PASS)
Elasticsearch 9200 ELASTICSEARCH_
MongoDB 27017 MONGODB_ (?????????? ?? ????? ?????????? ????????? Docker MONGO_DATABASE)
Kafka 9092 KAFKA_
MailCatcher 1025/1080 or 25/80 MAILER_
Blackfire 8707 BLACKFIRE_
Mercure 80 ?????? ?????c????????? MERCURE_PUBLIC_URL ? MERCURE_URL (???????? ?????? ? ???????????? Docker dunglas/mercure)

Вы можете открыть интерфейсы веб-управления для сервисов, которые их демонстрируют:

1
2
$ symfony open:local:webmail
$ symfony open:local:rabbitmq

Или нажать на ссылки в разделе "Server" в панели инструментов веб-отладки.

Tip

Чтобы отладить и перечислить все экспортированные переменные окружения, выполните symfony var:export --debug.

Tip

Для некоторых сервисов, веб-сервер также демонстрирует переменные окружения, понимаемые инструментами CLI, связанными с сервисом. Например, запуск symfony run psql автоматически подсоединит вас к серверу PostgreSQL, работающему в контейнере, без необходимости указывать имя пользователя, пароль или имя БД.

Когда запущены сервисы Docker, перейдите на страницу вашего приложения Symfony, и проверьте раздел "Symfony Server" в панели инструментов веб-отладки; вы увидите, что "Docker Compose" - "Up".

Note

Если вы не хотите, чтобы для сервиса демонстрировались переменные окружения, установите ярлык com.symfony.server.service-ignore как true:

1
2
3
4
5
6
# docker-compose.yaml
services:
    db:
        ports: [3306]
        labels:
            com.symfony.server.service-ignore: true

Если ваш файл Docker Compose не находится в корне проекта, используйте переменные окружения COMPOSE_FILE и COMPOSE_PROJECT_NAME, чтобы определить его местоположение, так же, как для docker-compose:

1
2
3
4
5
# запустите ваши контейнеры:
COMPOSE_FILE=docker/docker-compose.yaml COMPOSE_PROJECT_NAME=project_name docker-compose up -d

# запустите любую команду Symfony CLI:
COMPOSE_FILE=docker/docker-compose.yaml COMPOSE_PROJECT_NAME=project_name symfony var:export

Note

Если у вас более одного файла Docker Compose, вы можете предоставить их все, разделяя их :, как объясняется в _`справочнике переменных окружения Docker compose CLI`.

Caution

При использовании бинарности Symfony с php bin/console (консоль symfony ...), бинарность будет всегда использовать переменные окружения, определенные через Docker, и будет игнорировать локальные переменные окружения. Например, если вы установите другое имя БД в вашем файле .env.test (DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/test), и если вы выполните symfony console doctrine:database:drop --force --env=test, команда сбросит БД, определенную в вашей конфигурации Docker, а не "тестовую".

Caution

Похожий на другие веб-серверы, этот инструмент автоматически раскрывает все переменные окружения переменные, доступные в контексте CLI. Убедитесь, что этот локальный сервер недоступен в вашей локальной сети без разрешения, чтобы избежать проблем с безопасностью.

Интеграция Platform.sh

Локальный сервер Symfony обеспечивает полную, но необязательную интеграцию с Platform.sh, сервисом, оптимизированным для запуска приложений Symfony в облаке. Он предоставляет такие возможности, как создание окружений, резервных копий/снапшотов, и даже доступ к копии рабочих данных с вашей локальной машины, чтобы помочь отладить любые проблемы.

Прочтите техническую документацию Platform.sh для Symfony.