Установка и базовая настройка nginx и php-fpm для разработки проектов локально в Ubuntu 16.04

Здравствуй, уважаемый пользователь Хабрахабра. Мое повествование будет о том, как подготовить почву для локальной веб-разработки проектов в операционной системе Ubuntu 16.04.1 LTS.

В данной статье хочется развеять и разъяснить возможные трудности связанные с установкой и настройкой ПО, которое требуется для современной веб-разработки, с которыми возможно сталкиваются начинающие разработчики и не только.

Технологии которые будут использованы в статье: nginx, php-fpm.

Перед началом повествования, хочу отметить, что я проделывал все эти действия на «голой» системе.
Я буду работать с пакетным менеджером aptitude. Так же рекомендую обновить индекс пакетов и сами пакеты перед установкой ПО. В статье мы проделаем эти действия вместе.

Поехали!

Установка пакетного менеджера aptitude, обновление индекса и пакетов


Устанавливаем:

sudo apt install aptitude

Обновляем индекс.

sudo aptitude update

Обновляем пакеты (команда обновит все пакеты, для которых есть новые версии, если потребуется удаление пакетов, то оно будет выполнено).

sudo aptitude full-upgrade

Установка и настройка nginx (версия >= 1.10.0)


Устанавливаем.

sudo aptitude install nginx 

Запускаем.

sudo service nginx start

Проверяем версию, чтобы убедиться что не установили старую, то есть ниже 1.10.0.

nginx -v



Установку и запуск произвели, теперь пойдем в каталог туда куда установлен наш nginx и посмотрим на его структуру. Каталог nginx находится по такому пути:

cd /etc/nginx/

Посмотреть содержимое директории можно командой ls, с флагами -la будет удобнее просматривать содержимое каталога (в действительности эту команду с конкретными флагами можно описать детальнее и вернее, но у нас сегодня другая тема).

ls -la 

Наc интересуют в данный момент два каталога, которые вы видите на скриншоте. Это каталоги sites-available и sites-enabled.



Давайте перейдем в каталог sites-available и начнем конфигурировать наш виртуальный хост (сайт).

cd /etc/nginx/sites-available

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

Важное отступление
В случае установки nginx «с нуля», именно «с нуля», так как при удалении nginx командой
sudo apt-get remove nginx
или
sudo apt remove nginx 
конфигурационные файлы остаются и если вы вдруг будете не понимать, почему nginx не работает и захотите его переустановить (обычно к такому прибегают начинающие пользователи Linux), то и после переустановки он не будет корректно работать, из-за того что в старых конфигурационных файлах (они не удаляются после удаления командой remove) прописаны неверные настройки, их придется удалить, либо настроить верно, только тогда nginx заработает.

Рекомендую удалять командой sudo apt-get purge nginx или sudo apt purge nginx. Если вы используете пакетный менеджер aptitude, то команда sudo aptitude purge nginx удаляет пакет полностью со всеми зависимостями и конфигурационными файлами.

В этом каталоге будет по умолчанию один файл, с названием default. В нем будет конфигурационный файл с примером, с комментариями, его вы можете изучить на досуге, а можете и вовсе удалить (всегда можно обратиться к официальной документации).

ls -la



Создадим свой конфигурационный файл, который будет соответствовать названию домена нашего локального сайта (или реального, если уже знаете его название). Это удобно, в будущем, когда будет много конфигурационных файлов, то это избавит вас от путаницы в них. У меня этот файл будет называться project.local.

sudo touch project.local

Посмотрим что получилось.



Теперь откроем его в редакторе, я открою его в nano.

sudo nano project.local

Видим что он у нас пустой. Теперь перейдем к формированию нашего файла. Нужно привести конфигурацию к такому виду, как написано ниже. Я опишу только жизненно важные директивы этого файла, описывать остальное не буду, так как это не является на данный момент важным, все-таки у нас тема базовой настройки. Этих настроек с «горкой» хватит для разработки проектов локально, не только мелких, но и довольно крупных. В следующих статьях опишу отдельно каждые использованные директивы (именно так называются строки, например server_name) этого файла.

Смотрите комментарии прям в конфигурационном файле.

server {
        listen 80; # порт, прослушивающий nginx
        server_name    project.local; # доменное имя, относящиеся к текущему виртуальному хосту
        root  /home/stavanger/code/project.local; # каталог в котором лежит проект, путь к точке входа


        index index.php;
        # add_header Access-Control-Allow-Origin *;


        # serve static files directly
        location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
                access_log off;
                expires max;
                log_not_found off;
        }


        location / {
                # add_header Access-Control-Allow-Origin *;
                try_files $uri $uri/ /index.php?$query_string;
        }

        location ~* \.php$ {
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; # подключаем сокет php-fpm
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
                deny all;
        }
}

Сохраняем файл. Теперь нам надо проверить, нет ли в нем ошибок. Сделать мы это можем командой.

sudo nginx -t

Если видим такую информацию как на скриншоте, значит у нас все верно, может продолжать настройку. Если вы получаете какие-либо ошибки, стоит перепроверить конфигурационный файл.



Теперь нам надо активировать конфигурационный файл, в каталоге /etc/nginx/sites-enabled/ необходимо создать симлинк (символическая ссылка). Если у вас nginx был установлен «с нуля», то в этом каталоге есть симлинк на файл default, про который рассказывалось выше, его можно удалить, если он вам не требуется. Переходим в нужный каталог.

cd /etc/nginx/sites-enabled/

Теперь мы в нужном каталоге. Давайте создадим наш симлинк. Для создания используется команда ln с флагом -s, далее мы укажем путь до нашего конфига project.local.

sudo ln -s /etc/nginx/sites-available/project.local

Посмотрим на наш созданный симлинк.



Чтобы убедиться что мы делаем еще все верно опять запустим команду.

sudo nginx -t

Если все ок, едем дальше.

Файл hosts


Этот файл находится по пути /etc/hosts. Наличие в нем записей, позволяет запускать nginx с использованием в качестве домена localhost. В этом файле можно присваивать альтернативные псевдонимы, например для нашего проекта project.local, мы присвоим домен project.local.

Открываем файл в редакторе nano.

sudo nano /etc/hosts

У вас в этом файле будет и другая информация, просто игнорируйте ее. Вам всего лишь нужно добавить строку как на моем скриншоте.



Не забываем сохранить файл. На этом настройка файла hosts закончена.

Установка php-fpm (>=7.0)


sudo aptitude install php-fpm

Проверяем установленную версию, на всякий случай, хотя в Ubuntu 16.04.1 в репозиториях лежит именно 7.0 версия.

php-fpm7.0 -v



Убеждаемся что все ок. Стартуем php-fpm.

sudo service php7.0-fpm start

Если будете править конфиги, то не забывайте рестартовать демон. Это делает так. Но нам это не потребуется.

sudo service php7.0-fpm restart

На этом установка и настройка php-fpm закончена. Правда, это все. Это не магия, путь до сокета php-fpm у нас уже был прописан в конфигурационном файле. Конечно, вам могут понадобиться какие-либо расширения php для разработки личных проектов, но их вы можете поставить по мере того как они будут требоваться.

Теперь пойдем для в каталог с нашим проектом, у меня он лежит по такому пути.

cd /home/stavanger/code/project.local

Поднимемся на каталог выше и сделаем права 777 (то есть мы будем делать полные права каталогу с нашим проектом project.local). В будущем это избавим нас от лишних проблем.

cd ..
sudo chmod -R 777 project.local

На этом настройка ПО завершена, давайте создадим тестовый файл в нашем рабочем каталоге project.local и убедимся что все работает. Я создам файл index.php с таким содержанием.

<?php
    echo "Hello Habrahabr!";

Идем в браузер и видим что у нас все прекрасно работает! Интерпретатор php в том числе.



С уважением к читателям, Stavanger.
  • –14
  • 60,1k
  • 62
Поделиться публикацией

Комментарии 62

    +4
    Неофитская пятница началась.

    Автор, неправильно делаешь. Такие вещи нельзя конфигурировать руками. Нужно использовать какой-нибудь ansible, puppet или типа того.
      +2
      Я приветствую конструктивную критику. Статья о том как настраивать определенный софт, а не о системах централизованного управления конфигурациями.

      Иногда лишние надстройки только усложняют понимание. Для крупных компаний несомненно удобно и необходимо использовать ПО о котором вы говорите.
      –3
      Есть же Docker.
        0
        Есть много чего интересного. Но если не понимать азов, то Docker не спасет. Не понимаю к чему такой комментарий.
          –1
          Так верстают только м Не понимаете, потому и нет у вас докера. Когда вам с вашей локалки надо будет перенести всё на тест, а потом на прод — вы что будете делать?
            +1
            Bash, который разворачивает конфигурацию на продакшине/тестовом сервере — все. Я не видел ни разу Docker-контейнера с тем ПО, которое было бы актуально для моих проектов, все приходится до настраивать и вся «прелесть» Docker уходит на нет.

            Один раз написать bash и больше не париться.
            Потом с помощью Git разворачивается проект.
            Ставить лишнюю прослойку в виде Docker — лишнее.
              +4
              Какая-то странная логика. Докер придуман вовсе не для того чтоб какие-то левые парни написали вам докерфайлы на все случаи жизни, под ваш любимый софт с нужными вам версиями. Он нужен для переносимости окружения, как раз то о чём вы пишите ниже:
              Да и вообще принято использовать идентичное ПО локально и на боевом сервере

              Баш скрипт может не сработать, сработать не так, или вообще сделать что-то левое, в зависимости от окружения. Докерфайл (конфигурация для докер-контейнера) это по сути тот же самый баш-скрипт (различия — минимальны, правда) только вот он работает всегда одинаково, на всех машинах, под любой ОС. Собирается контейнер который будет работать одинаково и на проде и на тесте и на «ноуте разработчика». Точно так же храните свой докерфайл в том же самом git с исходниками проекта, и ваш проект будет всегда и у всех собираться ровно точно так же как вы и задумали.
              Поверьте я тут вам рассказываю всё это не потому что я какой-то злобный буратино и пытаюсь вас заставить делать бесполезную работу. То что вы описываете — так я и сам когда-то работал, и вот сейчас у меня лежит по докерфайлу в каждом проекте, (а на самом деле минимум 2-3, отдельные контейнеры на php-fpm, nginx, nodejs… но это мои замарочки, так делать не обязательно) там же лежат конфиги от системы орестрации и всё это работает у меня на компе, на компе моих сотрудников, на тесте и проде, на нескольких проектах. Попробуйте преодолеть это ваше «лишнюю прослойку в виде Docker», тем более что у вас итак линукс, потом скажете нам спасибо.
                +2

                Спасибо за информацию, я попробую развернуть окружение с помощью Docker буквально на днях, правда. Вы меня заинтриговали. Свое мнение отпишу сюда.

                  0
                  По любым вопросам — пишите в личные сообщения, постараюсь помочь.
                    0

                    Спасибо Вам.

                  0

                  Пока только единственный вопрос, если докер контейнер везде идентичный, соответственно и клнфиги в нем. То как разруливать такую ситуацию, когда на бое у меня в конфигах подключен ssl, а в локально директивы отвечающие за ssl придется закомментировать, то есть уже контейнер не идентичный получается. Или эти моменты как-то по-другому решаются?

                    0
                    Ну во первых вам никто не мешает на локалке подключать папку с нужынми локальными сертификатами в контейнер, поверх продуктовых сертификатов. Во вторых — на локалке можно просто игнорировать ошубку сертификата и нажимать «продалжить».
                      0
                      Это уже часть конфигурации, а не сборки. Положите свои сертификаты в какой-нибудь etcd или consul. Класть их в сам контейнер неправильно, поскольку вы наверняка будете передавать этот контейнер другим разработчикам, например, из своей команды. А ключи вещь такая, что чем меньше человек имеет к ним доступ, тем лучше.

                      Но это все в теории. А на практике, в продакшене у вас, скорее всего, будет отдельный контейнер для шифрования трафика. В локальном окружении вам этот контейнер не нужен, ходите напрямую.
                        0
                        Спасибо за наводку.
            –5
            Статья хорошая. С комментариями выше про Docker и Ansible не соглашусь, я бы лично просто завернул это в виртуалку, притом желательно VirtualBox, потому что он есть у всех.

            Очень жаль, что вы про MariaDB забыли, был бы полноценный LEMP стек. Ну и Memcached можно было бы для кучи.
              0
              Спасибо.

              Кстати, если кто-то предпочитает Windows, то можно использовать Vagrant, это довольно удобно и целесообразно для такого случая. То есть мы работаем в IDE под Windows, но проект у нас на виртуальной машине например под Ubuntu Server, а IDE в него смотрит (общий каталог).

              Конечно есть под Windows Open Server, но у него проблемы есть с правкой конфигов nginx и некоторые ограничения. Так же под Windows нет официальной поддержки Redis, в Open Server Redis — сборка энтузиастов. А Redis нужен всегда, по крайней мере мне.
                0
                Под windows можно использовать docker и виртуализацию hyper-v.
              0

              include fcgi_params должен быть в начале.

                +3
                add_header Access-Control-Allow-Origin *;
                Всегда найдется идиот, который скопирует ваш конфиг в production не глядя.

                Про include уже написали выше.
                  –7
                  Хедеры разрешающие обращение аяксом с других доменов.

                  add_header Access-Control-Allow-Origin *;
                  
                    +3
                    Спасибо, я знаю, зачем нужен CORS. А вот многие из тех, кто будет использовать ваш конфиг — нет.

                    Так что лучше закомментируйте эту строку. Кому надо, тот сознательно раскомментирует.
                      0
                      Поправил этот момент.
                        +3
                        Порядок include так и не исправили. Загляните в файл, который вы инклудите. Не он должен переопределять ваши переменные, а вы его. Иначе действительно возникает впечатление, что вы надергали куски каких-то левых конфигов из Интенета, не понимая их сути.
                  +2
                  Статья начитается с
                  Установка и базовая настройка nginx и php-fpm для разработки проектов локально в Ubuntu 16.04

                  и следом
                  aptitude install nginx

                  aptitude install php-fpm

                  Далее конфиги из гугла… елы палы.

                  Я расчитывал увидеть вот такое про php 7.1 и сборку nginx с какими-нить кастомными плагинами (хотя бы ngx_http_substitutions_filter_module, от которого пользы вагон).

                  Но самое страшное:
                  На этом установка и настройка php-fpm закончена. Правда, это все.

                  Не хочу ругаться, так как вас спасает лишь
                  как подготовить почву для локальной веб-разработки проектов
                  , ибо на сервер такое не проканает. Дефолтные конфиги php-fpm без настройки юзеров, это классная дырка, даже не отверстие. И локально все равно надо пользователей настраивать, так как когда будет перенос на сервер, под урезанной учеткой могут начаться сюрпризы, которых не было на локальной анархии.
                    –2
                    Статья исключительно для разработки локально, не больше. Локально этого с головой хватит, локально мы не думаем о безопасности, зачем лишние движения и лишние строки в конфигах?

                    Для продакшина это не годится, но и статья не о настройках на продакшине.

                    И конфиги не из гугла.

                    Хедеры разрешающие обращение аяксом с других доменов.

                    add_header Access-Control-Allow-Origin *;
                    
                      0
                      Это вы про аналогию с китайским Абибасом или 2-3 линейным найком? Ну… добавить одну линию и уже, вроде как, свое.

                      Я вам написал про косяк, что анархия на дев тачке может попросту на завестись на продакшене, так как юзер на продакшине сидит в железной клетке или еще фиг знает где (как его злобный буратино огородил). Да и, ей богу, установку PHP7 из репы… когда я 2 недели назад ставил 7.1 (который работает отлично!) на новую виртуалку для инет магаза… это нехорошо. Можно было и 5й поставить, все равно репо ж.
                        0
                        зачем лишние движения и лишние строки в конфигах?

                        Обращаю внимание на две бессмысленные директивы fastcgi_split_path_info и fastcgi_index в location ~* \.php$. Это либо ошибка, либо копипаста.

                        +1
                        ISPConfig (конкретно про это не могу сказать, не пробовал), а вот ISPManager я принципиально не использую, так как кучу гемора можно получить, был уже опыт с ним.
                          0
                          Речь не про ISPConfig и прочие свистоперделки. Речь о том, что поставить софт через пакет менеджер это пара команд + первый конфиг из гугла, если дефолтные (у вас тут микс из дефолтных и чутьчуть изменений).

                          Это не тема для статьи, это твит максимум. Статья — это как в том примере по ссылке, когда чем качает исходник PHP (самый последний, а не 7й), конфигурирует его как хочет, затем добавляет в системы и сервисы и докидывает пачку модов к нему. Вот это статья.
                        +4
                        В поиске Хабра можно найти тучу статей конфигурации LAMP/LEMP стэка под кучу разных осей, зачем еще одна? Ну и во времена docker/vagrant это уже странно смотрится. Если хотите донести азы установки пакетов в убунте, то это прекрасно можно сделать и в виде vagrant + bash скрипт для провиженинга.
                          +2
                          Чтобы настраивать doker/vagrant нужно их понять. Дайте настроить их новичку и посмотрите как он встанет в ступор. Например подготовка бокса для распространения в команде, чтобы его настроить, нужно понимать азы, инчане все это бестолку.

                          LAMP/LEMP опять же не годится, без понимания основ, если вы конечно не мини-проекты разрабатываете.

                          Да и вообще принято использовать идентичное ПО локально и на боевом сервере. Если учитывать ваше недовольство, то можно и на продакшине LAMP развернуть.
                            0
                            Ну полнейшего новичка что угодно поставит в ступор. Может тогда начать с базовых юникс команд вообще?

                            LAMP = Linux/Apache/MySQL/PHP, LEMP=Linux/Nginx/MySQL/PHP если что. А то не совсем пойму о чем вы.
                          +2

                          когда мне лень поднимать вагрант, я делаю php -S localhost:8080 -t web/

                            +4
                            Если Вы не против, я укорочу немного.

                            docker run -d -p 80:80 -v /tmp/html:/var/www/html --name php7 richarvey/nginx-php-fpm:php7 && sudo chmod 777 /tmp/html
                            

                            ~1.5 минуты и можно начинать разработку.
                              0
                              Да, это безусловно круто.

                              Но повторюсь, что я хотел рассказать именно про нативную настройку.
                                0
                                Я не уверено что там будет весь стек технологий, который мне потребуется и с теми настройками, которые мне нужны. Контейнеров масса, но все не дотягивает до специфичности проекта.
                                  +1
                                  Контейнеров масса, но все не дотягивает до специфичности проекта.
                                  По вашим комментариям можно заключить, что что такое Docker, вы не знаете.

                                  Хотя я сам не являюсь сторонником использования контейнеров в production, но вам однозначно следует почитать что-нибудь на эту тему, чтобы понять, что это вообще такое и перестать приводить аргументы «не в тему».
                                –1
                                Написали бы лучше гуевину, чтобы возня с sites-available и /etc/hosts находилась под капотом
                                  –4
                                  Где закрывающий тэг
                                  ?>
                                  
                                  в Хэлловорде????
                                    +6
                                    Современный стандарт рекомендует его не ставить.
                                    0
                                    Зачем там закрывающий тег?
                                    По умолчанию его можно опускать, даже нужно, лишняя писанина.
                                    Если у вас интерпретатор настроен специфично, то это уже другой вопрос.
                                    Это лет 5 назад его рекомендовалось оставлять.
                                      0
                                      Почитайте про стандарты PSR
                                        –1
                                        PSR это не стандарты, это «PHP Standards Recommendations», рекомендации.
                                          0

                                          RFC от IETF тоже de jure не стандарты, но многие de facto таковыми являются.

                                            –2
                                            Отличный аргумент и очень в тему обсуждения. Если кто-то пользуется RFC как стандартами, это не значит что они «de facto таковыми являются», это значит что кто-то не хочет думать своей головой.
                                              –2

                                              HTTP/1.1, которым вы, скорее всего, пользовались для отправки этого сообщения, описан в пачке RFC (2616 и другие). TCP, поверх которого это работает, — тоже (rfc 793 и другие). Далее продолжать или таки осилите вбить что-нибудь в гугл?

                                                +1
                                                На заборе тоже написано, а там дрова лежат (с)
                                                От того что что-то где-то написано, стандартом оно не становится.
                                                  –1

                                                  Видимо, вам не очень понятно что такое de facto. Просвещайтесь, я вас покину.

                                                    0

                                                    Влезу в ваш диалог. Стандарты были в СССР в виде ГОСТ-ов и были обязательны к исполнению. RFC и иже с ними де юре не законы и к исполнению не обязательны. Де факто их используют как некие инструкции при этом вендоры их реализуют как считают нужным. Многие из этих документов вообще по многу лет не выходят из черновиков.

                                                      0

                                                      А сейчас ГОСТ и ГОСТ Р тоже стандарты, но не обязательны к исполнению. Например, используя openssl в качестве библиотеки для сервера с https, я полагаюсь на корректную имлементацию пачки стандартов de facto (начиная от C calling conventions для linux до rfc, описывающих TLSv1.x, всяких стандартов из группы pkcs 1, 7, 11 и т. п.), но не использую при этом ГОСТ Р 34.10-2001, являющийся стандартом криптографической подписи в РФ. Не нужен он мне, и всё.


                                                      Говорить про, скажем RFC 793, что это не стандарт de facto несколько странно, учитывая, что, в процессе написания этого комментария, TCP-пакеты, описанные этим стандартом, прошли оборудование десятка различных вендоров и близкое количество различных сетевых стеков, которые только благодаря наличию коллективных рекомендаций под эгидой IETF корректно работают совместно.


                                                      Рекомендую почитать историю зари интернета и успешного захвата мира sendmail'ом. Там довольно много про становление стандартов de facto, которые сейчас известны как rfc822 плюс его соседи и наследники (smtp: 821/2821/5321, email/imf: 822/2822/5322 и куча других).


                                                      Некоторая свобода в реализации RFC естественно закладывается каждым конкретным стандартом (всякие SHOULD и MAY в тексте соответствующего стандарта), но это абсолютно нормально. ГОСТы многие вещи тоже дают на откуп "пользователю" стандарта.

                                                        0

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

                                      +3
                                      Если вы используете пакетный менеджер aptitude, то команда sudo aptitude remove nginx удаляет пакет полностью со всеми зависимостями и конфигурационными файлами.


                                      remove — Remove packages.
                                      purge — Remove packages and their configuration files.
                                        0
                                        Спасибо, вы действительно правы.
                                        Проверил, тут моя ошибка, у меня не верная информация, поправлю.
                                        +1
                                        Мда… прочитал ветку, только укрепился в желании, что когда разрабы пытаются дотянутся рученьками до серверов их им надо нежно обламывать и посылать обратно код писать, а не пытаться админить :)
                                          0

                                          Разработчики разные бывают. Не говоря уж про ныне модное направление devops.

                                          +1
                                          Чтобы попросить nginx использовать свежую конфигурацию без перезагрузки сервиса, рекомендую после
                                          sudo nginx -t
                                          

                                          , если всё ок, запускать
                                          sudo service nginx reload
                                          

                                          вместо
                                          sudo service nginx restart
                                          

                                          , о чём в статье не упоминается.
                                            0
                                            Да, безусловно.
                                            Добавлю в статью.
                                            Спасибо.
                                            +1
                                            chmod -R 777 гениально! Особенно не забудьте сделать это на проде.
                                              0
                                              Очевидно же что на проде так делать не надо.
                                                –2
                                                без 777 в проде у вас php не сможет писать в свои же каталоги, потому как каталог создан от одного пользователя, а fpm пускается от nginx/www-data/apache, а стандартная маска запрещает other писать в каталог. надо либо в конфиге пула fpm менять user/group либо chown делать на каталоге.
                                                  0

                                                  явно єто решается через кнфигурацию и владельца, а не через 777

                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                            Самое читаемое