Перейти к содержанию

Cервер разработки для веб. приложения. Настраиваем NGINX, PHP 8 и Alpine с помощью Docker.

Введение

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

1. Подготовка рабочей среды

Установка языка программирования и его зависимостей. Это основа, на которой будет строиться весь проект. В нашем случае это PHP 8.

Следующим шагом будет установка сервера разработки и его зависимостей. В нашем случае это NGINX и PHP-FPM. Эти компоненты обеспечивают запуск и выполнение нашего кода в браузере пользователя.

2. Командная разработка и совместимость систем.

При работе над проектом в команде важно обеспечить, чтобы каждый разработчик мог легко и быстро настроить рабочую среду на своем компьютере. Здесь мы сталкиваемся с вопросом совместимости систем. Как обеспечить, чтобы ваш коллега, работающий, например, на Windows, мог так же легко запустить проект, как и вы на вашем MacOS или Linux?

3. Решение: Docker

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

Основы Docker

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

Компоненты сервера

Для запуска нам понадобиться.

1. Docker Engine

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

  • Руководство по установке Docker для Windows
  • Руководство по установке Docker для Ubuntu
  • Руководство по установке Docker для Mac

2. Docker-compose

Docker-compose — это дополнительный инструмент для Docker, который позволяет управлять многоконтейнерными приложениями. С его помощью вы сможете определить и запустить все службы вашего приложения с помощью одной команды.

  • Руководство по установке Docker-compose

3. Операционная система. Основа любого образа.

Для работы внутри контейнера Docker нам понадобится операционная система. Я рекомендую использовать Alpine Linux из-за ее легковесности и высокой производительности.

  • Список доступных образов ОС для Docker

4. NGINX

NGINX — это мощный веб-сервер, который также может выполнять функции обратного прокси-сервера, балансировщика нагрузки и HTTP-кеша.

  • Руководство по установке NGINX на Alpine Linux

5. PHP-FPM

Для того чтобы NGINX мог корректно обрабатывать PHP-скрипты, нам понадобится PHP-FPM. Это менеджер процессов, который позволяет NGINX обрабатывать PHP.

6. PHP

И, конечно же, нам понадобится сам PHP и его модули. В процессе настройки мы установим его в наш контейнер.

Поехали дальше!

Структура нашего проекта

Вот как может выглядеть файловая структура нашего проекта.

├── 📂 project/
│   └── 📂 backend/
│       ├── 📂 nginx-config/
│       │   └──📄 default.conf
│       ├── 📂 src/
│       │   └──📄 index.php
│       └── 📄 Dockerfile
├── 📄 docker-compose.yml
└── 📄 README.md

Dockerfile

Давайте создадим простой Dockerfile, на основе которого будет создан образ с операционной системой, веб-сервером (прокси) nginx и PHP.

    # FROM  это первая инструкция в Dockerfile. Она указывает, на базе какого образа,  Dockerfile будет создавать свой образ.
    # Указываем что будем использовать образ с ОС Alpine из репозитория docker.
    FROM alpine:3.16.2

    # Команда RUN выполняет команду внутри образа во время процесса сборки.
    # Далее, обновляем операционную систему Alpine
    RUN apk update && apk upgrade

    # Далее нам нужно установить утилиты и php, мы можем добиться этого, используя команду RUN.
    # Установим утилиты apline и php
    RUN apk add --no-cache \
        bash \
        php8 \ 
        php8-fpm \ 
        php8-opcache \
        php8-gd \
        php8-zlib \
        php8-curl \
        php8-bcmath \
        php8-ctype \
        php8-iconv \
        php8-intl \
        php8-json \
        php8-mbstring \
        php8-mysqlnd \
        php8-openssl \
        php8-pdo \
        php8-pdo_mysql \
        php8-pdo_pgsql \
        php8-pdo_sqlite \
        php8-phar \
        php8-posix \
        php8-session \
        php8-soap \
        php8-xml \
        php8-zip \
        libmcrypt-dev \
        libltdl 

    # Далее установим nginx по гайду с официального сайте nginx. Я просто скопировал и вставил то, что есть в руководстве по установке nginx на alpine.
    # https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/
    RUN apk add openssl curl ca-certificates

    # Чтобы настроить репозиторий apk для стабильных версий пакетов nginx, выполните команду:
    RUN printf "%s%s%s\n" \
    "http://nginx.org/packages/alpine/v" \
    `egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release` \
    "/main" \
    | tee -a /etc/apk/repositories

    # Импортируйте официальный ключ подписи nginx, чтобы apk мог проверить подлинность пакетов.
    RUN curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub

    # Проверяем, что загруженный файл содержит правильный ключ
    RUN openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout

    # Переместите ключ в хранилище доверенных ключей apk
    RUN mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/

    # Теперь, устанавливаем nginx
    RUN apk add nginx

    # Установите PHP Composer, если вы используете composer, вы можете раскомментировать этот файл.
    # RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

    # Копируем файлы проекта внутрь контейнера
    COPY ./src /usr/share/nginx/html/project

    # Скопируйте конфигурацию по умолчанию и вставьте ее в путь к конфигурации nginx внутри docker.
    COPY ./nginx-configs/default.conf /etc/nginx/conf.d/default.conf

    # Открываем порты так, чтобы они были снаружи контейнера.
    EXPOSE 80
    EXPOSE 443

    # чтобы указать, что контейнер будет корректно завершать работу при получении сигнала SIGTERM.
    STOPSIGNAL SIGTERM

    # Выполните команду запуска.
    # Запустите php-fpm8 и nginx через терминал bash.
    CMD ["/bin/bash", "-c", "php-fpm8 && chmod 755 /usr/share/nginx/html/* && nginx -g 'daemon off;'"]

Этот Dockerfile создает образ на основе Alpine, устанавливает NGINX, копирует файлы из локальной директории src в стандартную директорию NGINX для веб-содержимого и запускает NGINX при старте контейнера.

Теперь, когда мы создали Dockerfile, нам нужно протестировать наше приложение. Во-первых, нам нужно собрать образ. Имя нашего образа — backend.

Введите команду ниже в терминале проекта.

  docker build -t backend .

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

  docker run -dp 8080:80 backend

Чтобы узнать, запущен ли контейнер, вы можете проверить его, набрав: docker ps в терминале проекта или протестируйте приложение через веб-браузер: http://localhost:8080

Важно понять. Что такое Docker Volume?

Представьте себе, что у вас есть коробка (контейнер Docker), и вы хотите сохранить в ней какие-то вещи (данные). Если вы не используете специальный ящик (Docker Volume), то все ваши вещи будут просто лежать в коробке, и если коробка сломается, вы потеряете все, что в ней было.

Docker Volume, по сути, это такой специальный ящик в вашем шкафу (файловой системе компьютера), который вы можете подключить к своей коробке.

Это удобно, потому что:

  • Ваши вещи (данные) не будут занимать много места в коробке, делая ее тяжелой и неудобной.
  • Если вы захотите что-то изменить в своих вещах, вам не нужно будет каждый раз переупаковывать коробку.
  • И самое главное, даже если коробка сломается, ваши вещи в ящике останутся в безопасности.

Информация

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

Давайте попробуем это на практике. Если мы хотим сохранить все из папки src, мы можем использовать следующую команду:

docker run -dp 8080:80 -v src:/usr/share/nginx/html/project backend

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

Docker Compose: работа с контейнерами

Представьте, что у вас есть множество коробок (контейнеров Docker), каждая из которых требует своего набора инструкций для запуска. Было бы утомительно открывать каждую коробку по отдельности, верно? Именно здесь на помощь приходит docker-compose.

Docker Compose позволяет нам создать "инструкцию" или "сценарий", где мы описываем, какие коробки нам нужны, как они связаны между собой и какие настройки они должны использовать. Таким образом, вместо того чтобы работать с каждой коробкой по отдельности, мы можем запустить их все одной командой!

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

Давайте попробуем преобразовать нашу ручную команду в инструкцию для docker-compose. Создайте файл с именем docker-compose.yml в вашем проекте и используйте следующий код:

version: "1.0"

services:
  backend:
    # Имя образа
    image: backend

    # Имя контейнера
    container_name: backend

    # Создаём образ из Dockerfile
    build: 

      # Путь к dockerfile
      context: ./

      # Dockerfile для создания образа
      dockerfile: Dockerfile

    # Пробрасываем порты
    ports:
      - "8080:80"
      - "8443:43"

    # Подключаем хранилище
    volumes: 
      - ./src:/usr/share/nginx/html/project

Теперь, чтобы запустить ваш проект, всё, что вам нужно сделать, это ввести команду docker-compose up, и все ваши контейнеры будут запущены согласно инструкциям, указанным в файле docker-compose.yml.

Теперь протестируйте приложение через веб-браузер: http://localhost:8080.

Чтобы удалить контейнер:

  docker-compose down

Чтобы создать образ:

  docker-compose build