https://github.com/maxyc/laravel-tickets/blob/master/docker-compose.yml
Данная конфигурация кочует со мной из проекта в проект
Первым делом давайте разберемся: какие сервисы нам потреубуются?
- php-fpm 7.4+ with xdebug
- mysql | postgresql | sqlite
- nginx | apache
- redis | … etc…
Давайте попробуем на примере php-fpm 7.4 + mysql + nginx
Создадим папку нашего проекта /var/www/example.loc/ и создадим в ней файл docker-compose.yml, также нам понадобится папка ./docker где будем хранить конфигурации наших сервисов.
Внутренняя сеть
В нашей сборке ничего, кроме nginx не будет смотреть наружу. Ни какие порты, кроме 80. Нам не требуется извне иметь доступ к 9000 порту php или 3306 бд. Все контейнеры будут залинкованы между собой внутренней сетью, которую можно описать следующим образом:
networks:
internal:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.220.0/28
База данных
db:
image: mysql
restart: always
command: --default-authentication-plugin=mysql_native_password
networks:
- internal
environment:
- MYSQL_DATABASE=${DB_DATABASE}
- MYSQL_USER=${DB_USERNAME}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
volumes:
- ./docker/mysql/datadir:/var/lib/mysql
Нам необходимо в корне папки создать файл .env, в котором будут наши настройки БД
DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=db DB_USERNAME=user DB_PASSWORD=123456
Эти данные в дальнейшем будут в .env файле нашего проекта на Laravel.
Стоит обратить внимание на DB_HOST=db. Здесь нельзя указывать localhost или еще какой ip. За счет удобной внутренней сети докера мы можем использовать имя сервиса в качестве пути к серверу базы данных. в нашем случае это db
Т.к. после перезапуска контейнера все данные удаляются, то нам необходимо вынести файлы таблиц базы данных. Поэтому помещаем их в папку docker/mysql
volumes:
- ./docker/mysql/datadir:/var/lib/mysql
Если вдруг вам потребуется mariadb, то вместо image: mysql, впишите image: mariadb. Конфигурация остается та же.
А что, если мы захотим использовать postgresql? Все так же просто:
db:
image: postgres
restart: always
networks:
- internal
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- ./docker/postgres/datadir:/var/lib/postgresql/data
С базами данных закончили.
php-fpm
Будем использовать кастомную сборку php-fpm, т.к. нам необходимо добавить поддержку работы с базой данных, поддержку xdebug и пр.
Для начала опишем сервис. Условимся, что наш docker-compose.yml и папка docker будет лежать в корне laravel проекта на одном уровне с папкой app
php-fpm:
build:
context: docker/php-fpm
volumes:
- ./:/var/www
environment:
XDEBUG_CONFIG: "remote_host=192.168.220.1 remote_enable=1"
PHP_IDE_CONFIG: "serverName=Docker"
depends_on:
- db
networks:
- internal
Т.к. наша сборка кастомная, то вместо image секции, нам необходимо указать путь к настройкам:
build:
context: docker/php-fpm
Создаем папку ./docker/php-fpm и в ней два файла php.ini и Dockerfile, в котором далее будем описывать процесс сборки php-fpm
В php.ini мы можем указать желаемые нами параметры, например:
max_execution_time = 1000 max_input_time = 1000 error_reporting=E_ALL display_errors=on short_open_tags=off
Перейдем к Dockerfile. В этом файле (с большой буквы) хранятся построчно все инструкции по установке php внутри контейнера.
FROM php:7.4-fpm
RUN apt-get update \
&& apt-get install -y wget git unzip libpq-dev libicu-dev libpng-dev libzip-dev libjpeg-dev libfreetype6-dev\
&& pecl install xdebug-2.9.1 \
&& docker-php-ext-enable xdebug \
&& docker-php-ext-install pdo_pgsql \
&& docker-php-ext-install pgsql \
&& docker-php-ext-install zip \
&& docker-php-ext-install gd \
&& docker-php-ext-enable pgsql
ADD ./php.ini /usr/local/etc/php/php.ini
RUN wget https://getcomposer.org/installer -O - -q \
| php -- --install-dir=/bin --filename=composer --quiet
USER 1000
WORKDIR /var/www
В первой строке (команда FROM) мы указали какую версию image файла нам использовать. В данном случае php:7.4-fpm
Следующая команда RUN устанавливает требуемые зависимости
Далее, мы указываем контейнеру, что php.ini необходимо брать из нашей текущей папки.
Далее, Устанавливаем composer. Он нужен нам только на уровне php-fpm контейнера.
Ну и наконец указываем контейнеру, где лежат все наши файлы со стороны контейнера. В нашем случае, мы указали, что корень нашего сервера это /var/www
Вы можете с легкостью указать любую другую версию php, например
php:7.3-fpm, но учтите, для этой версии может потребуетсяxdebugболее низкой версии, например 2.7.1
Nginx
nginx:
build:
context: docker/nginx
volumes:
- ./:/var/www/
- ./storage/app/public/:/var/www/public/storage/
ports:
- 80:80
depends_on:
- php-fpm
networks:
- internal
Обратите внимание, что папку storage мы пробрасываем на уровне конфигурации. Симлинки не работают между контейнерами. В нашем случае nginx и php-fpm
Nginx у нас так же имеет кастомную сборку, потому указываем путь к файлу Dockerfile как в прошлом примере.
Создаем папку ./docker/nginx и там файл Dockerfile и папку conf.d
В conf.d у нас будут храниться виртуальные хосты, обычно 1-2 достаточно. Обрабатываются только файлы с расширением .conf. Например, default.conf:
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
server_name example.loc localhost;
root /var/www/public;
index index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_read_timeout 1000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
#fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~* /\. {
deny all;
}
}
Настроим Dockerfile следующим образом:
FROM nginx ADD ./conf.d /etc/nginx/conf.d/ WORKDIR /var/www
На этом настройка окружения для нашего проекта закончена. Нам остается только запустить контейнеры командой
docker-compose up -d --build
Если все ок, то наше приложение теперь доступно по адресу http://localhost
Одна из возможных причин, почему не запустилось, может крыться в том, что 80 порт может быть уже занят. В любом случае, понять причину ошибки можно запустив команду docker-compose logs и проанализировав ее.
Установка Laravel
Предположим, что мы разворачиваем фреймфорк впервые на машине, где не установлен php. Для того, чтобы установить фреймворк, нам необходимо скачать его командой
git clone https://github.com/laravel/laravel.git laravelapp
И скопировать все файлы в папке laravelapp в корень нашего сервера.
Для того, чтобы можно было использовать artisan, нам необходимо обращаться к нему внутри контейнера, а именно docker-compose exec php-fpm php artisan make:controller, либо запускать команды внутри контейнера запустив команду docker-compose exec php-fpm bash, а затем уже использовать php artisan make:controller
Часто у новичков и не только, у кого локально установлен php? возникает ошибка подключения к базе данных, при использовании команд artisan. Для решения которой, как бы не было это глупо и банально, предлагаю проверить как вы запускаете команду. Возможно вы запускаете ее локально, а не в контейнере. =)
Здравствуйте, что-то у меня не так
в конце выполнения docker-compose up -d –build возникают ошибки
Creating db … done
Creating php-fpm … error
ERROR: for php-fpm Cannot start service php-fpm: OCI runtime create failed: container_linux.go:345: starting container process caused “chdir to cwd (\”/var/www\”) set in config.json failed: permission denied”: unknown
ERROR: Encountered errors while bringing up the project.
Потом смотрю в portainer контейнер db вроде running, а php-fpm просто created и при попытке запуска выдаёт ту же ошибку OCI runtime create failed.
В логах db
2020-11-28 15:16:15+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.,
2020-11-28 15:16:16+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’,
2020-11-28 15:16:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.,
2020-11-28 15:16:17+00:00 [Note] [Entrypoint]: Initializing database files,
mysqld: Can’t create directory ‘/var/lib/mysql/’ (OS errno 17 – File exists),
2020-11-28T15:16:17.119612Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.22) initializing of server in progress as process 43,
2020-11-28T15:16:17.120948Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.,
2020-11-28T15:16:17.120984Z 0 [ERROR] [MY-010119] [Server] Aborting,
2020-11-28T15:16:17.121088Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.22) MySQL Community Server – GPL.
Привет. Сложно так будет сказать что у вас. У вас что то с правами доступа.
https://youtu.be/9TlXDyoCK10
Я вот попробовал впервые видео записать. Вдруг поможет вместе со мной повторять действия
Привет.
Видео с ошибкой не помогло. Но хорошее – поставил доп компоненты
Creating cache … done
Creating db … done
Creating node … error
Creating backend … error
ERROR: for backend Cannot start service backend: OCI runtime create failed: container_linux.go:345: starting container process caused “chdir to cwd (\”/var/www\”) set in config.json failed: permission denied”: unknown
ERROR: for node Cannot start service node: OCI runtime create failed: container_linux.go:345: starting container process caused “chdir to cwd (\”/home/node/app\”) set in config.json failed: permission denied”: unknown
Похоже действительно были проблемы с правами доступа. Папка проекта выглядела вот так в листинге
drwx——+ 1 schel4ok users 556 Nov 29 20:34 example.loc
Я попробовал изменил права для юзера 1000 вот так
chown -vR 1000:1000 example.loc
chmod 700 example.loc
Теперь стало так.
drwx—— 1 1000 1000 556 Nov 29 20:34 example.loc
И после этого php стартанул. Что это за юзер 1000?
Это типа www-data? У меня просто линукс не чистый, а сборка Synology DSM. Там много изменений.
Например не работают команды make и нет юзера www-data нет, но есть юзер http. Может вместо 1000 использовать id юзера http?
В логе nginx всё ОК
/docker-entrypoint.sh: Configuration complete; ready for start up
В логе php есть вот такие строчки, которые мне не очень ясны. Вроде работает, но первые 2 строки напрягают
NOTICE: [pool www] ‘user’ directive is ignored when FPM is not running as root,
NOTICE: [pool www] ‘group’ directive is ignored when FPM is not running as root
NOTICE: fpm is running, pid 1,
NOTICE: ready to handle connections
В логе db всё ОК
LOG: database system is ready to accept connections
cache вообще никакого лога не выводит
А node какой-то странный. Он стартует, а потом автоматически останавливается со статусом Stopped for a few seconds with exit code 1.
да , нода не висит в качестве демона. в видео показал как им пользоваться. как обычной программой запускать