Локальный веб-сервер: VirtualBox, Debian, Nginx, php-fpm, etc

Создавая недавно новый сайт на Yii2 я довольно прилично помучился из-за различий рабочего окружения, которые обеспечивают локальный Open-Server на Windows и реальный сервер с Debian. Это вынудило меня настроить правильный локальный сервер, используя VirtualBox. В статье я расскажу, как это сделать.

Задача

Есть компьютер с Windows 10, где установлен VirtualBox. Создадим виртуальную машину в VirtualBox, установим на неё Debian. Затем настроим на этой машине веб-сервер и установим некоторый софт, необходимый для веб-разработки.

Дополнительно настроим общую папку, чтобы удобно работать в ней с кодом сайтов в любимом редакторе под Windows. Открываться сайты тоже будут под Windows.

Виртуалка и Debian

Скачиваем новейший образ для установки Debian. Даю ссылку на страницу с образами, предназначенными для сетевой установки. Они маленькие, не имеют ничего лишнего, хорошо подходят для веб-сервера. Я использую 64-битный образ. На момент написания статьи актуален Debian версии 8.5.

Создаём виртуальную машину:

Создаём виртуальную машину

Объём памяти и диска по своему усмотрению.

Диск особо расходоваться не будет, т.к. мы будем работать с сайтами в общей папке, которая будет подключается к Debian как дополнительный носитель. Тип основного диска по умолчанию, динамический.

Настройки виртуальной машины

Машина подготовлена. Пока не включаем. Заходим в свойства машины, подключаем скаченный установочный образ на CD/DVD:

Подключаем установочный образ на CD/DVD

Пройдёмся по другим настройкам.

Число ядер процессора выбирайте сами, в зависимости от возможностей и потребностей. Обязательно установите отметку «Включить PAE/NX».

Настройки виртуальной машины

Можно выключить разные ненужные вещи, типа удаленного доступа по RDP, звуковой карты, порта USB стандарта 2.0 и т.д.

Отключение звуковой карты

В сетевых адаптерах выбираем тип подключения «NAT», ниже тут же кликаем «Дополнительно» и заходим в «Проброс портов».

Сетевые настройки

Здесь для SSH указываем порты 3022 и 22, для веба 80 и 80. Остальное заполнять не надо. Этого достаточно.

Проброс портов

Почему именно «NAT»? Виртуальную машину сможете использовать только вы, она не будет видна в вашей локальной сети и никак на неё не повлияет. Для меня это важно.

Если вы хотите, чтобы ваша виртуальная машина полноценно добавлялась в вашу локальную сеть, то выбирайте тип подключения «Сетевой мост». Другие компьютеры в вашей локальной сети тоже смогут обращаться к вашей виртуальной машине.

В завершении добавляем общую папку:

Добавляем общую папку

Выходим из настроек.

Запускаем машину, устанавливаем Debian.

VirtualBox

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

Установка Debian

Ближе к концу установки надо будет выбрать компоненты, которые требуется установить. Рабочий стол и прочий мусор нам на веб-сервере не нужен, снимаем везде отметки. Оставляем только SSH-сервер и стандартные системные утилиты.

Компоненты Debian

Предлагаемый в списке «web server»  я тоже предпочитаю не ставить, т.к. там будет Apache, на который у меня аллергия. Лучше установить потом самому именно то, что нужно.

В общем, установка завершается, машина перезапускается.

Входим под root-ом:

Вход на веб-сервер

Всё ок? Небольшая рекомендация. Делайте «снимки» машины на разных этапах настройки и использования. Это полезно! Если в процессе каких-то настроек или других действий что-то пойдёт не так, то вы сможете откатиться к предыдущему состоянию.

Вот сейчас машина успешно стартовала. Выключите её, сделайте снимок. Это займет от силы минуту.

Создаём снимок

Чтобы выключить машину можно написать «poweroff», чтобы перезапустить — «reboot».

Настройки

Пока продолжаем работать с созданной машиной через окно VirtualBox. К подключению по SSH вернёмся чуть позже.

В процессе установки Debian, кроме root, обязательно создаётся дополнительный пользователь. Если он совсем вам не нужен, то его можно удалить:

userdel -r имя_пользователя

Дополнительный пользователь иногда полезен, например, когда вы будете работать с Composer. Этот менеджер пакетов считает, что работа под root небезопасна и выдаёт предупреждение, хотя и продолжает исправно работать.

По умолчанию Debian не позволяет подключиться по SSH, используя пользователя root. Выглядит это так:

login as: root
root@127.0.0.1's password:
Access denied

Дополнительным пользователем подключаться можно сразу.

Чтобы по SSH можно было зайти используя root-пользователя редактируем строчку в файле /etc/ssh/sshd_config.

Ищем:

PermitRootLogin without-password

Меняем на:

PermitRootLogin yes

Чтобы изменения вступили в силу перезагружаем машину.

Для подключений по SSH в Windows удобно использовать PuTTY. Адрес машины 127.0.0.1, порт 3022:

PuTTY для подключения по SSH

Теперь уже можно большую часть времени работать с виртуальной машиной через SSH, оно удобнее, чем через окно VirtualBox. Окно PuTTY можно свободно растягивать и его содержимое будет под это подстраиваться. В вашем распоряжении буфер обмена и даже мышь.

Чтобы работала общая папка требуется установить дополнения гостевой ОС. Для начала подключаем образ:

Подключение образа дополнений гостевой ОС

Теперь монтируем его:

mount /dev/cdrom /media/cdrom

Предварительно устанавливаем требуемые пакеты:

apt-get install build-essential module-assistant

Ещё выполняем:

m-a prepare

Теперь сама установка дополнений:

sh /media/cdrom/VBoxLinuxAdditions.run

Результат успешной установки:

root@webdev:~# sh /media/cdrom/VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.1.2 Guest Additions for Linux...........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
vboxadd.sh: Building Guest Additions kernel modules.
update-initramfs: Generating /boot/initrd.img-3.16.0-4-amd64
vboxadd.sh: Starting the VirtualBox Guest Additions.

Could not find the X.Org or XFree86 Window System, skipping.
root@webdev:~#

Перезапускаем машину и радуемся, что теперь у нас заработала общая папка. В виртуальной машине в моём случае это:

/media/sf_Webdev

На основной машине она соответствует:

c:\VirtualDub\Folders\Webdev

Работа с общей папкой в виртуальной машине осуществляется из под пользовательской группы vboxsf. Это означает, что если пользователь (под которым вы работаете) не входит в эту пользовательскую группу, то он не сможет записывать в общую папку. Для него в папке по умолчанию режим «readonly».

Чтобы добавить пользователя в эту группу выполняем:

usermod -aG vboxsf имя_пользователя
usermod -aG vboxsf root
usermod -aG vboxsf www-data

Пользователь www-data по умолчанию используется Nginx.

Веб-сервер

Переходим к настройке веб-сервера:

apt-get install nginx
apt-get install php5-fpm php5-cgi

В общей папке создадим папку первого сайта:

/media/sf_Webdev/site.loc

Соответственно он появится и на основной машине. В эту папку поместим тестовый файл index.php с кодом:

<?php phpinfo(); ?>

Не имеет значения, как именно вы создаёте папки и файлы в общей папке, можете всё это делать уже из вашей основной системы.

Создадим символическую ссылку для каталога сайта:

ln -s /media/sf_Webdev/site.loc /var/www

Создадим для сайта файл настроек Nginx:

/etc/nginx/sites-available/site.loc

Его содержимое:

server {
  listen 80;
  server_name site.loc;
  root /var/www/site.loc;
  index index.php;

  location / {
    try_files $uri $uri/ =404;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
  }

  access_log /var/log/nginx/site.loc_access.log;
  error_log /var/log/nginx/site.loc_error.log;
}

Подключим файл настроек:

ln -s /etc/nginx/sites-available/site.loc /etc/nginx/sites-enabled/site.loc

Перезапустим Nginx:

/etc/init.d/nginx restart

Теперь в основной системе отредактируем hosts-файл, обычно он расположен здесь:

c:\Windows\System32\drivers\etc\hosts

В него надо добавить строчку:

127.0.0.1 site.loc

Всё! Настало время в веб-браузере основной системы попробовать открыть сайт site.loc. Если всё в порядке, то вы увидите информацию по PHP виртуальной машины.

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

Чтобы выяснить, выключите пока виртуальную машину, в основной системе откройте консоль:

cmd

Выполняем в ней:

netstat -an -p tcp -o | findstr 80

Получим примерно такое:

C:\Users\kodmg>netstat -an -p tcp -o | findstr 80
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       5684
  TCP    0.0.0.0:7680           0.0.0.0:0              LISTENING       1000
  TCP    0.0.0.0:49664          0.0.0.0:0              LISTENING       580
  TCP    0.0.0.0:49665          0.0.0.0:0              LISTENING       980
  TCP    192.168.1.210:56543    77.234.45.61:80        ESTABLISHED     1736
  TCP    192.168.1.210:56793    5.45.58.148:80         CLOSE_WAIT      1736
  TCP    192.168.1.210:56800    52.20.134.145:443      CLOSE_WAIT      7036
  TCP    192.168.1.210:57180    95.213.255.17:443      ESTABLISHED     8616
  TCP    192.168.1.210:57288    188.43.75.80:80        TIME_WAIT       0
  TCP    192.168.1.210:57309    104.27.186.197:80      ESTABLISHED     8616
  TCP    192.168.1.210:57340    23.43.134.135:80       TIME_WAIT       0

Здесь первая строка с адресом 0.0.0.0:80 – это признак, что 80 порт в настоящее время используется. В конце этой строки цифры, в примере это 5684. Данный номер — это ID процесса приложения.

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

Диспетчер задач Windows

На вкладке «Подробности» делаем сортировку по колонке «ИД процесса» и ищем нужный номер. В моём случае это оказался Skype.

По умолчанию Skype использует именно 80 порт для соединений, но это можно изменить в его настройках. Убираем галочку «Для дополнительных входящих соединений следует использовать порты 80 и 443». Выходим из настроек, перезапускаем Skype.

Skype и 80 порт

Той же командой в консоли ещё раз делаем проверку:

C:\Users\kodmg>netstat -an -p tcp -o | findstr 80
  TCP    0.0.0.0:7680           0.0.0.0:0              LISTENING       1000
  TCP    0.0.0.0:49664          0.0.0.0:0              LISTENING       580
  TCP    0.0.0.0:49665          0.0.0.0:0              LISTENING       980
  TCP    192.168.1.210:56543    77.234.45.61:80        ESTABLISHED     1736
  TCP    192.168.1.210:56793    5.45.58.148:80         CLOSE_WAIT      1736
  TCP    192.168.1.210:56800    52.20.134.145:443      CLOSE_WAIT      7036
  TCP    192.168.1.210:57180    95.213.255.17:443      ESTABLISHED     8616
  TCP    192.168.1.210:57309    104.27.186.197:80      ESTABLISHED     8616
  TCP    192.168.1.210:57340    23.43.134.135:80       TIME_WAIT       0

Теперь 80 порт никем не используется. Запускаем обратно виртуальную машину и снова пробуем открывать сайт. Теперь, если вы всё делали по инструкции, то он точно должен открыться!

Nginx

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

Очень многие сталкиваются с этими граблями. Типичный случай: вы изменили файл CSS или JS, а на сайте не видно этих изменений, файл используются старый.

Мне помогло решить проблему включение в конфиг Nginx параметра:

if_modified_since off;

Некоторым помогает ещё этот дополнительный параметр:

sendfile off;

Поскольку проблема может быть актуальна для всех сайтов, работающих на веб-сервере виртуальной машины, то правильнее включить эти параметры в общем файле /etc/nginx/nginx.conf.

Дополнительная информация по теме.

База

Вместо обычного MySQL я предпочитаю более продвинутую реализацию в лице Percona Server. Многие его рекомендуют, благодаря скорости и дополнительным фичам. Я использую Percona Server не менее 2 лет и тоже могу его уже рекомендовать. Для сайта, для любого сайтового движка — это будет просто MySQL, они не увидят разницы.

Установка Percona Server:

wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb
dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb

Обновляем источники:

apt-get update

Продолжаем установку:

apt-get install percona-server-server-5.6

Я устанавливаю именно версию 5.6, хотя есть на текущий момент уже релиз 5.7. Эти версии основаны, соответственно на MySQL 5.6 и 5.7. Последняя имеет некоторые существенные отличия, которые меня пока не устраивают. Из-за них в частности у меня не работал phpMyAdmin.

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

apt-get install percona-server-server-5.7

В процессе установки потребуется указать пароль для root-пользователя базы. Не путайте с root-пользователем системы.

Установим дополнительно phpMyAdmin:

apt-get install phpmyadmin

В процессе потребуется указать пароль root-пользователя базы. Также будет создан ещё один пользователь базы, специально для phpMyAdmin и для него нужно будет придумать дополнительный пароль, либо оставить поле пустым и пароль будет сгенерирован автоматически.

Чтобы иметь доступ к phpMyAdmin через созданный уже тестовый сайт просто добавим в его каталог символическую ссылку:

ln -s /usr/share/phpmyadmin /var/www/site.loc

Теперь из основной системы phpMyAdmin можно открывать:

site.loc/phpmyadmin

Workbench

Используя приложение MySQL Workbench на основной машине проще всего подключаться к базе MySQL на виртуальной машине используя SSH. Создавая подключение устанавливаем параметр «Connection Method» в состояние «Standard TCP/IP over SSH» и далее вписываем уже знакомые параметры:

Подключение к MySQL через Workbench

Рабочий софт

Установка Composer:

cd /usr/src
apt-get install curl php5-cli
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

Для проверки работоспособности можно просто:

composer

Если всё хорошо, получите справку по программе.

Остальное по желанию.

Установка Node.js:

curl -sL https://deb.nodesource.com/setup_6.x | bash -
apt-get install nodejs

Установка Gulp.js:

apt-get install npm
npm i -g gulp

Если будут предупреждения:

npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated minimatch@0.2.14: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated graceful-fs@1.2.3: graceful-fs v3.0.0 and before will fail on node releases >= v7.0. Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree.

Тогда надо установить предложенное:

npm install -g minimatch@3.0.2
npm install -g graceful-fs@^4.0.0

Установка Less.js:

npm install -g less

Vagrant

Это такая вспомогательная программа для VirtualBox и других систем виртуализации. Она позволяет быстро создавать виртуальные машины, наподобие той, которую мы уже создали. Работать с Vagrant необходимо из командной строки.

Пишу это здесь просто для информации, что такое есть.

Я пробовал Vagrant. Да, действительно программа делает своё дело. Но мне показалось это лишним и не совсем тем, что надо:

  • Такое полезно тому, кто создаёт виртуальные машины пачками. Не мой случай. Возможно, пока.
  • Виртуальные машины при помощи Vagrant создаются на основе готовых образов (боксов), список которых есть на официальном сайте. Они в случае необходимости автоматически загружаются. Честно говоря, я не сильно доверяю этим боксам. Считаю, что безопаснее создать своё. Тем более это не так уж и сложно.

В принципе, боксы для Vagrant — это созданные и специально настроенные виртуальные машины VirtualBox. Мы вот создали свою виртуальную машину. Её, в теории, можно немного допилить, чтобы использовать в качестве бокса. Бокс может быть локальным.

Я когда начал изучать информацию по Vagrant, то меня напугали все эти инструкции в интернете. В каждой автор начинает разбирать конфигурационный файл виртуальной машины, и это поначалу выглядит дико и совсем непросто. Спешу успокоить новичков! Этот файл создается автоматически самим Vagrant-ом. Вы (при желании) можете внести в него дополнительные параметры, а можете и не вносить! Машина просто получит настройки по умолчанию. Часто этого достаточно.

Далее простой пример, как можно создать с помощью Vagrant тот же веб-сервер на базе Debian 8. Перед тем, как начать скачиваем Vagrant с официального сайта и устанавливаем его в любую папку так, чтобы в пути к этой папке не было русских символов.

Открываем консоль в Windows:

cmd

Скачиваем нужный бокс и убеждаемся, что он попал в список доступных локально боксов:

vagrant box add cimmwolf/jessie64-lemp
vagrant box list

Для первой команды название бокса я нашёл в списке по запросу «debian 8 lemp». Вот информация по нему, где автор советует перед использованием бокса выполнить установку плагина:

vagrant plugin install vagrant-vbguest

Такая команда выполняется единожды, если ранее данный плагин ещё не инсталлировался. Плагин позволяет автоматически устанавливать в виртуальную машину дополнения гостевой ОС.

Создаём каталог и переходим в него, например:

mkdir c:\VMs\Deb8lemp
cd c:\VMs\Deb8lemp

Инициализация виртуальной машины:

vagrant init cimmwolf/jessie64-lemp

При этом у нас появляется в этом каталоге файл Vagrantfile. Он содержит конфигурацию будущей машины. Как уже сказал, настройки можно оставить по умолчанию.

Устанавливаем виртуальную машину:

vagrant up

Всё! Через некоторое время машина будет готова.

При установке машины автоматически устанавливаются все актуальные обновления Debian. При каждом старте монтируется общая папка.

Таким образом, всего несколько команд в консоли и у нас готовая для работы виртуальная машина. Для входа по SSH используем адрес 127.0.0.1, порт 2222, пользователя vagrant, пароль vagrant.

Последующий запуск машины из консоли происходит быстро:

C:\VMs\Deb8lemp>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'cimmwolf/jessie64-lemp' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
[default] GuestAdditions 5.1.2 running --- OK.
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
    default: /vagrant => C:/VMs/Deb8lemp
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

В VirtualBox машину тоже видно:

Машина созданная с помощью Vagrant

Docker

Это ещё один альтернативный вариант. По своей сути Docker предлагает уже не виртуализацию, а создание изолированных контейнеров поверх вашей системы. Таких контейнеров на одной системе можно запускать множество. Приложения в каждом из них работают полностью независимо.

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

Docker предназначен для Linux и использует для создания контейнеров специфику ядра этой операционной системы. В Windows использовать Docker можно двумя способами. Во-первых, есть Boot2docker, который автоматически создаёт, опять же, в VirtualBox виртуальную машину и уже там запускает контейнеры. Во-вторых, можно самостоятельно создать виртуальную машину с Linux и там разворачивать контейнеры.

Автоматически созданная машина Boot2docker-ом:

Машина Boot2docker

Помимо уже сказанного есть ещё одна очень весомая фишка. Мы создаём для разработки сайта один или несколько контейнеров Docker, зависит от сложности и масштабов сайта. Потом, когда сайт будет готов, то мы именно эти же контейнеры просто переносим на хостинг! Получается, что сайт «продолжает» работать в своём родном окружении уже на другой площадке.

На мой взгляд Docker интересен, но только если вы работаете именно в Linux. Использование контейнеров через виртуализацию трудно назвать изящным вариантом. Поэтому я, как пользователь Windows, отказался от Docker. Во всяком случае, нет пока необходимости.

5 Комментариев

  1. Дмитрий, статья просто шикарная. Но не мог бы ты подсказать как организовать удалённый доступ с хоста к базе данных на виртуальной машине? То есть, я вот пользуюсь MySQL Workbranch, как всё настроить, чтобы я мог работать с базами на виртуальной машине из основной системы?

    • Проще всего работать с базой через SSH. Для этого уже все готово. Просто создаем подключение и работаем. В статью добавил скриншот по теме.

  2. Спасибо все очень круто описано. Хочется продолжения, добавления ключей для доступа без пароля к ssh, подключить git к этому всему и т.д. Принятие изменения из bare репозитория, слышал нужно хук писать какой-то что бы он срабатывал когда делаем git pull

    • А зачем все это на локальном сервере для разработки? Я пользуюсь Netbeans на основной машине, код здесь же в общей папке, и git у меня здесь же. Из Netneans очень удобно работать с git.

  3. Самая годная инструкция, которую нашел. Автор пречислен к лику святых теперь, благодарю!

Добавить комментарий