Docker php laravel tutorial. dockerize a php app in 3 minutes

Начинаем установку

1. Устанавливаем git, чтоб он был доступен из командной строки. Процесс описывать не буду, это легко гуглится.

2. Устанавливаем сам Docker desktop for mac/windows https://docs.docker.com/docker-for-mac/install/https://docs.docker.com/docker-for-windows/install/

Затруднений при установке возникнуть не должно, делать все как описано в инструкции по этим ссылкам.
Главное чтоб у вас установился Docker desktop, чтобы его иконка отображалась в строке состояния со статусом: is running

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

3. Проверяете установился ли Докер. Когда вы установили сам клиент docker — открываете командную строку и вводите:

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

Если все хорошо на этом шаге — то, отлично, переходим дальше!

4. Теперь мы выберем сборку контейнеров для докера и создадим папку, в которой все это будет храниться.

Вообще можно собрать конечно самому сборку и я вначале так и пытался сделать, однако столкнулся с множеством проблем, чтением мануалов. Что привело меня к поиску уже готовой сборки для веб сервера. И я такую нашел: https://github.com/sprintcube/docker-compose-lamp

В нее входят следующие компоненты:

  • PHP (вы сами можете выбрать нужную вам 1 из 6 версий. начиная с 5.4 до 7.4)
  • Apache
  • MySQL
  • phpMyAdmin
  • Redis

Теперь нужно создать папку куда мы ее скачаем. У меня это — /Users/your_name/Documents/docker/lamp

lamp — это название сборки (в первую очередь для меня, чтобы не забыть)

5. Далее читаем Installation https://github.com/sprintcube/docker-compose-lamp
переходим в папку и выкачиваем файлы с репозитория:

6. Команда docker-compose up -d

Это команда обращается к пакетному менеджеру docker, скачивает и устанавливает (если еще не установлены) все компоненты которые описаны в docker-compose.yml — собирает их вместе и запускает контейнеры.

В файле docker-compose.yml — вы увидите какие именно это пакеты и как они прописаны. Обязательно откройте этот файл и ознакомьтесь с содержимым!

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

Поздравляю! Теперь можете заходить на localhost и отобразиться страничка, которая расположена по адресу /Users/your_name/Documents/docker/lamp/www/index.php

Разумеется, вы ее меняете, закачиваете в папку свой проект и наслаждаешь дальнейшей разработкой!

NGINX + PHP + PHP-FPM

Рекомендуется каждый микросервис помещать в свой отдельный контейнер, но мы (для отдельного примера) веб-сервер с интерпретатором PHP поместим в один и тот же имидж, на основе которого будут создаваться контейнеры.

Создание образа

Создадим каталог, в котором будут находиться файлы для сборки образа веб-сервера:

mkdir -p /opt/docker/web-server

Переходим в созданный каталог:

cd /opt/docker/web-server/

Создаем докер-файл:

vi Dockerfile

  1. FROM centos:8
  2. MAINTAINER Dmitriy Mosk <master@dmosk.ru>
  3. ENV TZ=Europe/Moscow
  4. RUN dnf update -y
  5. RUN dnf install -y nginx php php-fpm php-mysqli
  6. RUN dnf clean all
  7. RUN echo «daemon off;» >> /etc/nginx/nginx.conf
  8. RUN mkdir /run/php-fpm
  9. COPY ./html/ /usr/share/nginx/html/
  10. CMD php-fpm -D ; nginx
  11. EXPOSE 80

* где:
1) указываем, какой берем базовый образ. В нашем случае, CentOS 8.
3) задаем для информации того, кто создал образ. Указываем свое имя и адрес электронной почты.
5) создаем переменную окружения TZ с указанием временной зоны (в нашем примере, московское время).
7) запускаем обновление системы.
8) устанавливаем пакеты: веб-сервер nginx, интерпретатор php, сервис php-fpm для обработки скриптов, модуль php-mysqli для работы php с СУБД MySQL/MariaDB.
9) удаляем скачанные пакеты и временные файлы, образовавшиеся во время установки.
10) добавляем в конфигурационный файл nginx строку daemon off, которая запретит веб-серверу автоматически запуститься в качестве демона.
11) создаем каталог /run/php-fpm — без него не сможет запуститься php-fpm.
13) копируем содержимое каталога html, который находится в том же каталоге, что и dockerfile, в каталог /usr/share/nginx/html/ внутри контейнера. В данной папке должен быть наше веб-приложение.
15) запускаем php-fpm и nginx. Команда CMD в dockerfile может быть только одна.
17) открываем порт 80 для работы веб-сервера.

В рабочем каталоге создаем папку html:

mkdir html

… а в ней — файл index.php: 

vi html/index.php

<?php
phpinfo();
?>

* мы создали скрипт, который будет выводить информацию о php в браузере для примера. По идее, в данную папку мы должны положить сайт (веб-приложение).

Создаем первый билд для нашего образа:

docker build -t dmosk/webapp:v1 .

Новый образ должен появиться в системе:

docker images

При желании, его можно отправить на Docker Hub следующими командами:

docker login —username dmosk

docker tag dmosk/webapp:v1 dmosk/web:nginx_php7

docker push dmosk/web:nginx_php7

* первой командой мы прошли аутентификацию на портале докер-хаба (в качестве id/login мы используем dmosk — это учетная запись, которую мы зарегистрировали в Docker Hub). Вторая команда создает тег для нашего образа, где dmosk — учетная запись на dockerhub; web — имя репозитория; nginx_php7 — сам тег. Последняя команда заливает образ в репозиторий.
* подробнее про докера.

Запуск контейнера и проверка работы

Запускаем веб-сервер из созданного образа:

docker run —name web_server -d -p 80:80 dmosk/webapp:v1

Открываем браузер и переходим по адресу http://<IP-адрес сервера с docker> — откроется страница phpinfo:

Наш веб-сервер из Docker работает.

Angular и Docker multi-stage builds

На основе docker multi-stage build можно реализовать полный жизненный цикл angular-приложения:

  1. Разработка (npm start).
  2. Сборка (ng build —prod).
  3. Деплой (nginx).

Исходный код примера можно получить на GitHub. Docker-файл будет содержать 3 шага (FROM) сборки и выглядеть будет так:

### STAGE 1: Develop ###
FROM node:11.14.0-alpine as develop

USER node

RUN mkdir /home/node/.npm-global && mkdir /home/node/logs

ENV PATH=/home/node/.npm-global/bin:$PATH
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV HOME=/home/node

WORKDIR $HOME/app

RUN npm i -g npm

RUN npm install -g @angular/cli && npm cache clean --force

EXPOSE 4200

CMD 

### STAGE 2: Build ###
FROM develop as builder

USER root

COPY app .

RUN npm install && ng build --prod --output-path=dist

### STAGE 3: Setup ###
FROM nginx:1.15.12-alpine
# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
# From 'builder' stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /home/node/app/dist /usr/share/nginx/html

Первый шаг (develop) содержит в себе установку пакета Angular CLI и будет использоваться для разработки. Второй шаг (builder) предназначен для сборки приложения: RUN npm install && ng build —prod —output-path=dist. Третий шаг предназначен для копирования артефакта (сбилдженого приложения) в контейнер с HTTP-сервер.

Для этапа разработки будет использоваться docker-compose. Начиная с версии 3.4, docker-compose поддерживает build.target, что позволяет остановить сборку контейнера на конкретном шаге (в нашем случае этот шаг — develop).

version: "3.4"

services:
  angular:
      build:
        context: .
        target: develop # use stage develop
      ports:
        - 4200:4200
      volumes:
        - ./app:/home/node/app:rw
      command:
          - /bin/sh
          - -c
          - |
              cd /home/node/app && npm install && npm start

Выполнив команду docker-compose up, мы получим полноценно работающее окружение для разработки Angular-приложения (компиляция TypeScript, релоад браузера и т. д.).

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

$ docker build --no-cache -t docker-multi-stage-builds/go:latest .

Запуск контейнера с HTTP-сервером и Angular-приложением выполняется так:

$ docker run -p 8080:80 docker-multi-stage-builds/angular:latest

Предварительное создание образов

Ещё один способ решить проблему чистого кэша докера — часть слоёв вынести в другой Dockerfile, собрать его отдельно, запушить в Container Registry и использовать как родительский.

Создаём свой образ nodejs для сборки Angular-приложения. Создаём в проекте Dockerfile.node

Собираем и пушим публичный образ в Docker Hub:

Теперь в нашем основном Dockerfile используем готовый образ:

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

Мы рассмотрели несколько методов ускорения сборки докер-образов. Если хочется, чтобы деплой проходил быстро, попробуйте применить в своём проекте:

  • уменьшение контекста;
  • использование небольших родительских образов;
  • мультистейдж-сборку;
  • изменение порядка инструкций в Dockerfile, чтобы эффективно использовать кэш;
  • настройку кэша в CI/CD-системах;
  • предварительное создание образов.

Надеюсь, на примере станет понятнее, как работает Docker, и вы сможете оптимально настроить ваш деплой. Для того, чтобы поиграться с примерами из статьи, создан репозиторий https://github.com/devopsprodigy/test-docker-build.

Запуск стека приложений

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

  1. Сначала убедитесь, что никакие другие копии приложения и базы данных не запущены ( и ).

  2. Запустите стек приложений с помощью команды . Добавьте флаг , чтобы выполнить все в фоновом режиме. Либо можно щелкнуть правой кнопкой мыши файл Compose и выбрать параметр Compose Up (запустить Compose) на боковой панели VS Code.

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

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

  3. Просмотрите журналы с помощью команды . Отобразятся журналы каждой из служб, которые чередуются в одном потоке. Это чрезвычайно полезно, когда необходимо отслеживать проблемы, связанные с временем. Флаг дает команду «следовать за журналом», поэтому выходные данные будут выдаваться в режиме реального времени по мере их создания.

    Если вы еще этого не сделали, вы увидите следующий результат.

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

    Dica

    Ожидание базы данных перед запуском приложения. При запуске приложения оно фактически ожидает, пока MySQL будет готов к работе, прежде чем попытаться подключиться к нему. В Docker отсутствует встроенная поддержка, позволяющая ожидать, пока другой контейнер будет полностью готов, запущен и подготовится к запуску другого контейнера. Для проектов на основе узлов можно использовать зависимость wait-port. Аналогичные проекты существуют для других языков и платформ.

  4. На этом этапе вы сможете открыть приложение и увидеть, что оно запускается. И постойте! Вы сделали это с помощью одной команды!

Подключение к базе из веб-сервера

По отдельности, наши серверы готовы к работе. Теперь настроим их таким образом, чтобы из веб-сервера можно было подключиться к СУБД.

Зайдем в контейнер с базой данных:

docker exec -it maria_db /bin/bash

Подключимся к mariadb:

:/# mysql -p

Создадим базу данных, если таковой еще нет:

> CREATE DATABASE docker_db DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

* в данном примере мы создаем базу docker_db.

Создаем пользователя для доступа к нашей базе данных:

> GRANT ALL PRIVILEGES ON docker_db.* TO ‘docker_db_user’@’%’ IDENTIFIED BY ‘docker_db_password’;

* и так, мы дали полные права на базу docker_db пользователю docker_db_user, который может подключаться от любого хоста (%). Пароль для данного пользователя — docker_db_password.

Отключаемся от СУБД:

> quit

Выходим из контейнера:

:/# exit

Теперь перезапустим наши контейнеры с новым параметром, который будет объединять наши контейнеры по внутренней сети.

Останавливаем работающие контейнеры и удаляем их:

docker stop maria_db web_server

docker rm maria_db web_server

Создаем docker-сеть:

docker network create net1

* мы создали сеть net1.

Создаем новые контейнеры из наших образов и добавляем опцию —net, которая указывает, какую сеть будет использовать контейнер:

docker run —name maria_db —net net1 -d -v mariadb:/var/lib/mysql mariadb

docker run —name web_server —net net1 -d -p 80:80 dmosk/webapp:v1

* указав опцию —net, наши контейнеры начинают видеть друг друга по своим именам, которые мы задаем опцией —name.

Готово. Для проверки соединения с базой данных в php мы можем использовать такой скрипт:

<?php
ini_set(«display_startup_errors», 1);
ini_set(«display_errors», 1);
ini_set(«html_errors», 1);
ini_set(«log_errors», 1);
error_reporting(E_ERROR | E_PARSE | E_WARNING);
$con = mysqli_connect(‘maria_db’, ‘docker_db_user’, ‘docker_db_password’, ‘docker_db’);
?>

* в данном примере мы подключаемся к базе docker_db на сервере maria_db с использованием учетной записи docker_db_user и паролем docker_db_password.

После его запуска, мы увидим либо пустой вывод (если подключение выполнено успешно), либо ошибку.

Реализация

Начиная с версии 17.05, в докере появились многоступенчатые билды. Многоступенчатые сборки полезны для всех, кто пытается оптимизировать Docker-файлы и образы, сохраняя их легкими для чтения и обслуживания. До появления этой фичи применяли подход под названием «Builder Pattern». Подход «Builder Pattern» заключается в создании двух Docker-файлов и sh-скрипта:

  • Dockerfile.build — собирает приложение (вытягивает зависимости, компилирует и т. д.).
  • Dockerfile — запускает приложение.
  • build.sh — копирует артифакт, полученный из Dockerfile.build, в контейнер, собирающийся из Dockerfile.

Пример «Builder Pattern». Исходный код примера можно получить на GitHub.

Dockerfile.build

FROM golang:1.12.4-stretch
# Change worck directory
WORKDIR /go/src/github.com/zhooravell/docker-multi-stage-builds/builder-pattern
# Copy go code & dep files to worck directory
COPY main.go   Gopkg.toml Gopkg.toml ./
# Install dep, packages and build application
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh \
   && dep version \
   && dep ensure \
   && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

Dockerfile

FROM alpine:latest
# Add ssl support
RUN apk --no-cache add ca-certificates

WORKDIR /root/

COPY app .

CMD ["./app"]
#!/usr/bin/env bash
echo Building docker-multi-stage-builds/builder-pattern:build
# Билдим образ с приложение (зависимости, компиляция)
docker build -t docker-multi-stage-builds/builder-pattern:build . -f Dockerfile.build
# Создаем контейнер с коротким именем extract
docker container create --name extract docker-multi-stage-builds/builder-pattern:build
# Копируем артефакт из контейнера на хост-машину
docker container cp extract:/go/src/github.com/zhooravell/docker-multi-stage-builds/builder-pattern/app ./app
# Удаляем контейнер
docker container rm -f extract

echo Building docker-multi-stage-builds/builder-pattern:latest
# Собираем образ с скомпилированным приложением
docker build --no-cache -t docker-multi-stage-builds/builder-pattern:latest .
# Удаляем артефакт
rm ./app

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

$ docker run -p 8080:8080 docker-multi-stage-builds/builder-pattern

В результате получается очень маленький образ, с минимальным набором пакетов/зависимостей — только то, что нужно для запуска приложения. Production-образ не содержит инструментов сборки, компиляции, систем управления версиями.

$ docker images
REPOSITORY                                 TAG     IMAGE ID      CREATED         SIZE
docker-multi-stage-builds/builder-pattern  latest  4be00adf69b0  16 seconds ago  13.8MB
docker-multi-stage-builds/builder-pattern  build   3f0177d07175  20 seconds ago  819MB

Что же тогда multi-stage build? И зачем он нужен?

Многоступенчатый билд позволяет достичь того же результата, но без bash-скриптов, без нескольких Docker-файлов. Это достигается за счет использования нескольких инструкций FROM. В результате предыдущий пример будет выглядеть так:

FROM golang:1.12.4-stretch as builder
# Change worck directory
WORKDIR /go/src/github.com/zhooravell/docker-multi-stage-builds/go-multi-stage-build
# Copy go code & dep files to worck directory
COPY main.go Gopkg.toml Gopkg.toml ./
# Install dep, packages and build application
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh \
    && dep version \
    && dep ensure \
    && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
# Add ssl support
RUN apk --no-cache add ca-certificates

WORKDIR /root/
# Copy just the built artifact from the previous stage into this new stage
# The Go SDK and any intermediate artifacts are left behind, and not saved in the final image.
COPY --from=builder /go/src/github.com/zhooravell/docker-multi-stage-builds/go-multi-stage-build/app ./

EXPOSE 8080

CMD ["./app"]

Вся «хитрость» заключается в конструкции COPY —from=builder. Она копирует артефакт с шага с алиасом builder (FROM golang:1.12.4-stretch as builder). Соберем наш контейнер:

$ docker build --no-cache -t docker-multi-stage-builds/go:latest .

Давайте рассмотрим еще пример использования multi-stage builds.

Приступаем

Создадим основную папку, например docker-lamp, которая будет корневой, а внутри создадим следующую структуру:

— sites — тут будут лежать наши проекты

— data
— mysql — тут будут храниться файлы наших баз данных
— logs — сюда будут записываться все логи

— config
— php — все настройки контейнера и php.ini
— nginx — — все настройки контейнера и конфигурационные файлы

Создаем в корневой папке файл docker-compose.yml и добавим в него следующее содержание (я постарался его прокомментировать чтобы не возникало вопросов):

Образы nginx и mysql прекрасно работают из коробки, а вот официальный образ php совсем пустой и в него не включены никакие расширения, еще мы хотели чтобы в нашей среде разработки был Composer.

Поэтому переходим в папку  и создадим файлы  и .

Php.ini пока оставим пустым, если нам понадобиться в будущем настраивать PHP то воспользуемся им, а пока добавим в Dockerfile  следующий код:

Теперь в папке sites для теста создадим тестовый проект Hello, для этого создадим папку hello и поместим туда единственный файл index.php который будет выводить информацию о php:

Остается только сконфигурировать NGINX, для этого добавим в  файл hello.conf:

Не забываем в файле HOSTS добавить:

На этом все )

Запускаем терминал, переходим в нашу папку и запускаем команду:

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

Если при сборке не было никаких ошибок:

Переходим по адресу http://hello.loc/ и видим, что все работает.

Можно зайти в Docker-контейнер php и запустить bash, и проверить работает ли git и composer, для этого введем команду:

Завершаем работу командой:

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

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

UPD:

На Windows 10 у меня возникла ошибка при запуске контейнера MySQL, в логах было что то такое:

…..
Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
…..

Гугление показало — это означает, что используемая файловая система не поддерживает aio. Для этого в docker-compose добавим команду:

В статье, в описание файла docker-compose, я это добавил.

Problems That Docker Multistage Builds Might Encounter

Depending on how they are designed, multistage builds can introduce some serious issues around the speed of the build process. Since these Dockerfiles have multiple stages to produce the production-grade image, your cache will not consist of the images built in the previous steps leading to your final output. Simulating the build locally might give you the impression that it’s worth the wait. However, when you’re working with build services such as AWS CodeBuild, Travis CI, or CircleCI, you want to keep your build time as short as possible for cost reasons, as well as streamlining application delivery.

In order to make use of the cache, you will have to tag, push, and pull the images produced from the preliminary build stages. As an example, take the multistage Dockerfile from the previous section and split it into two files, Dockerfile.stage-one and Dockerfile.final. The first Dockerfile will create the image that will be pulled and used in stage 0 of the multistage Dockerfile.

That being said, following such an approach for every stage can create an increasingly verbose process every stage that you have. Another way of solving this issue is to make use of BuildKit. BuildKit came about to address issues and improve on the build features in the Moby Engine. It allows for better cache efficiency and control when building. To enable BuildKit builds, follow the steps outlined in .

Angular и Docker multi-stage builds

На основе docker multi-stage build можно реализовать полный жизненный цикл angular-приложения:

  1. Разработка (npm start).
  2. Сборка (ng build —prod).
  3. Деплой (nginx).

Исходный код примера можно получить на GitHub. Docker-файл будет содержать 3 шага (FROM) сборки и выглядеть будет так:

### STAGE 1: Develop ###
FROM node:11.14.0-alpine as develop

USER node

RUN mkdir /home/node/.npm-global && mkdir /home/node/logs

ENV PATH=/home/node/.npm-global/bin:$PATH
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV HOME=/home/node

WORKDIR $HOME/app

RUN npm i -g npm

RUN npm install -g @angular/cli && npm cache clean --force

EXPOSE 4200

CMD 

### STAGE 2: Build ###
FROM develop as builder

USER root

COPY app .

RUN npm install && ng build --prod --output-path=dist

### STAGE 3: Setup ###
FROM nginx:1.15.12-alpine
# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
# From 'builder' stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /home/node/app/dist /usr/share/nginx/html

Первый шаг (develop) содержит в себе установку пакета Angular CLI и будет использоваться для разработки. Второй шаг (builder) предназначен для сборки приложения: RUN npm install && ng build —prod —output-path=dist. Третий шаг предназначен для копирования артефакта (сбилдженого приложения) в контейнер с HTTP-сервер.

Для этапа разработки будет использоваться docker-compose. Начиная с версии 3.4, docker-compose поддерживает build.target, что позволяет остановить сборку контейнера на конкретном шаге (в нашем случае этот шаг — develop).

version: "3.4"

services:
  angular:
      build:
        context: .
        target: develop # use stage develop
      ports:
        - 4200:4200
      volumes:
        - ./app:/home/node/app:rw
      command:
          - /bin/sh
          - -c
          - |
              cd /home/node/app && npm install && npm start

Выполнив команду docker-compose up, мы получим полноценно работающее окружение для разработки Angular-приложения (компиляция TypeScript, релоад браузера и т. д.).

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

$ docker build --no-cache -t docker-multi-stage-builds/go:latest .

Запуск контейнера с HTTP-сервером и Angular-приложением выполняется так:

$ docker run -p 8080:80 docker-multi-stage-builds/angular:latest

Возможности и особенности

  • Несколько версий PHP — 7.3, 7.1 и 8.0 с набором наиболее востребованных расширений.
  • Возможность использовать для web-проектов разные версии PHP.
  • Готовый к работе монитор процессов Supervisor.
  • Предварительно сконфигурированный веб-сервер Nginx.
  • Базы данных:
    • MySQL 5.7.
    • MySQL 8.
    • PostgreSQL (latest).
    • MongoDB 4.2.
    • Redis (latest).
  • Настройка основных параметров окружения через файл .env.
  • Возможность модификации сервисов через docker-compose.yml.
  • Последняя версия docker-compose.yml.
  • Все docker-контейнеры базируются на официальных образах.
  • Структурированный Dockerfile для создания образов PHP.
  • Каталоги большинства docker-контейнеров, в которых хранятся пользовательские данные и параметры конфигурации смонтированы на локальную машину.

В целом, среда разработки удовлетворяет требованию — «при использовании Docker каждый контейнер должен содержать в себе только один сервис».

Run the magic!

Мы набросали минимальную конфигурацию для локальной среды разработки и можем ее смело запускать. Для этого из корня нашей сборки, где лежит файл нужно выполнить команду и немного подождать. Первый запуск будет дольше, потому что docker’у нужно скачать образы и собрать образ для php.

В конце концов мы увидим заветные строчки:

Они говорят нам что наши три контейнера запущены и готовы к работе. Проверимс… Для этого откроем браузер и перейдем по адресу , но сперва добавим одну строку в файл.

Важно для windows и mac адрес 127.0.0.1 нужно заменить на адрес виртуальной машины, в которой запускается докер, потому что нативной поддержки пока нет или она очень унылая. Итак, окрываем браузер и видим:

Итак, окрываем браузер и видим:

Использованные образы:

  • PHP
  • Nginx
  • Mysql

Build multi-platform images

BuildKit is designed to work well for building for multiple platforms and not
only for the architecture and operating system that the user invoking the build
happens to run.

When you invoke a build, you can set the flag to specify the target
platform for the build output, (for example, , , or
).

When the current builder instance is backed by the driver,
you can specify multiple platforms together. In this case, it builds a manifest
list which contains images for all specified architectures. When you use this
image in or
, Docker picks
the correct image based on the node’s platform.

You can build multi-platform images using three different strategies that are
supported by Buildx and Dockerfiles:

  1. Using the QEMU emulation support in the kernel
  2. Building on multiple native nodes using the same builder instance
  3. Using a stage in Dockerfile to cross-compile to different architectures

QEMU is the easiest way to get started if your node already supports it (for
example. if you are using Docker Desktop). It requires no changes to your
Dockerfile and BuildKit automatically detects the secondary architectures that
are available. When BuildKit needs to run a binary for a different architecture,
it automatically loads it through a binary registered in the
handler.

For QEMU binaries registered with on the host OS to work
transparently inside containers they must be registered with the
flag. This requires a kernel >= 4.8 and binfmt-support >= 2.1.7. You can check
for proper registration by checking if is among the flags in
. While Docker Desktop comes preconfigured
with support for additional platforms, for other installations
it likely needs to be installed using
image.

Using multiple native nodes provide better support for more complicated cases
that are not handled by QEMU and generally have better performance. You can
add additional nodes to the builder instance using the flag.

Assuming contexts and exist in ;

Finally, depending on your project, the language that you use may have good
support for cross-compilation. In that case, multi-stage builds in Dockerfiles
can be effectively used to build binaries for the platform specified with
using the native architecture of the build node. A list of build
arguments like and is available automatically
inside your Dockerfile and can be leveraged by the processes running as part
of your build.

Step 3 — Dockerize the Project

Setup Docker

Before creating a container for the Laravel application and shipping it off, you need to install Docker on your local
machine. For learning purpose, you will install Docker Community Edition. Select your OS from the list below and follow
the setup instructions:

Make the docker App image

The next stage to improve your docker php development workflow is adding a to your project. The structure of a can be considered a series of instructions on how to build your container/image.

Start the Dockerfile by creating an empty file named in the root of your project. Then, complete each
instruction according to the following example:

Building and Running the Container

Building the container is very straight forward once you have Docker and Docker Machine on your system. The following
command will look for your and download all the necessary layers required to get your container image
running. Afterwards, it will run the instructions in the and leave you with a container that is ready to
start.

To build your php laravel docker container, you will use the command and provide a tag or a name for the container, so you
can reference it later when you want to run it. The final part of the command tells Docker which directory to build
from.

The final step is to run the container you have just built using Docker:

You can see the Docker containers that are currently running on your system (along with their Container IDs) with:

To turn off your Docker container, run:

Дополнение. Добавляем еще неограниченное кол-во хостов с проектами

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

1. нужно добавить строчки в /etc/hosts на вашей машине mac (или windows — c:\windows\system32\drivers\etc\hosts), чтоб ваша операционная система понимала по какому адресу обращаться при запросе вашего хоста.

нажимаем ctrl + o, ctrl+x (перезаписываем и сохраняем файл)

2. добавляем в файл конфига /Users/your_name/Documents/docker/lamp/config/vhosts/default.conf
следующие строчки, он будет синхронизирован с контейнером Докер.

3. Чтобы наши изменения вступили в силу — перезапускаем контейнеры:

Conclusion

While creating Docker images the right way is not a small task, the final outcome does a great deal of good for the speed and security of your application delivery. Larger images have a high number of security vulnerabilities that shouldn’t be overlooked for the sake of speed. The reality is that quality images take time and care.

The builder pattern has evolved over time in its implementation, with multistage builds coming to the rescue from the tedious steps that previously had to be followed. Tools like BuildKit and Earthly further improve on this process. Though not foolproof, multistage builds have made it much easier to create optimized images that you can be more pleased and confident to have running in your production environment.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: