Сегодня я расскажу вам, как сделать своё первое приложение Laravel в контейнере Docker.
Необходимые условия
- Ubuntu 18.04
- Установленный Composer
- Установленный Docker — https://docs.docker.com/install/linux/docker-ce/ubuntu/
- Установленный Docker Compose — https://docs.docker.com/compose/install/
Шаг 1. Установка Laravel
Создаём приложение Laravel при помощи команды composer create-project
composer create-project — prefer-dist laravel/laravel laradock
Переходим в каталог проекта
cd laradock
Прописываем разрешение на запись для папки storage, и папки cache внутри папки bootstrap.
sudo chmod 777 -R storage/ sudo chmod 777 -R bootstrap/cache/
Затем используем образ Docker composer, чтобы смонтировать каталоги, нужные для Laravel, и чтобы избежать глобальной установки Composer.
docker run --rm -v $(pwd):/app composer install
Шаг 2. Создание файла Docker Compose
touch docker-compose.yml
version: '3' services: #PHP Service app: build: context: . dockerfile: Dockerfile image: php:7.3-fpm container_name: app restart: unless-stopped tty: true environment: SERVICE_NAME: app SERVICE_TAGS: dev working_dir: /var/www volumes: - ./:/var/www - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini networks: - app-network #Nginx Service webserver: image: nginx:alpine container_name: webserver restart: unless-stopped tty: true ports: - "8080:80" - "8443:443" volumes: - ./:/var/www - ./nginx/conf.d/:/etc/nginx/conf.d/ networks: - app-network #MySQL Service db: image: mysql:5.7.24 container_name: db restart: unless-stopped tty: true ports: - "33061:3306" environment: MYSQL_DATABASE: laravel MYSQL_ROOT_PASSWORD: root SERVICE_TAGS: dev SERVICE_NAME: mysql volumes: - dbdata:/var/lib/mysql/ - ./mysql/my.cnf:/etc/mysql/my.cnf networks: - app-network #Docker Networks networks: app-network: driver: bridge #Volumes volumes: dbdata: driver: local
Для веб-сервера я использовал порты 8080 и 844, так как у меня уже есть на компьютере установленный Apache. И я использовал порт 33061 для MySQL — уже есть установленный сервер MySQL.
Шаг 3. Сохранение данных
Я использовал тома и монтирование для хранения базы данных, файлов приложения и конфигурации.
В переменной db файла docker-compose.yml задан том под именем dbdata для хранения базы данных MySQL.
... #MySQL Service db: ... volumes: - dbdata:/var/lib/mysql networks: - app-network ...
Том dbdata хранит содержимое папки var/lib/mysql внутри контейнера. Это позволяет остановливать и перезапускать службу db без потери данных.
В конце файла compose добавлено определение тома dbdata:
... #Volumes volumes: dbdata: driver: local
Добавим монтирование файлов конфигурации MySQL в службу db.
... #MySQL Service db: ... volumes: - dbdata:/var/lib/mysql - ./mysql/my.cnf:/etc/mysql/my.cnf ...
Добавим монтирование к сервису webserver. Их будет два: один для кода вашего приложения, а другой для конфигурации Nginx.
#Nginx Service webserver: ... volumes: - ./:/var/www - ./nginx/conf.d/:/etc/nginx/conf.d/ networks: - app-network
И, наконец, добавим монтирование к службе app для файлов конфигурации и кода приложения:
#PHP Service app: ... volumes: - ./:/var/www - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini networks: - app-network
Служба app монтирует папку laradock, содержащую код приложения в папку /var/www в контейнере.
В итоге docker-compose.yml должен выглядеть так:
version: '3' services: #PHP Service app: build: context: . dockerfile: Dockerfile image: digitalocean.com/php container_name: app restart: unless-stopped tty: true environment: SERVICE_NAME: app SERVICE_TAGS: dev working_dir: /var/www volumes: - ./:/var/www - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini networks: - app-network #Nginx Service webserver: image: nginx:alpine container_name: webserver restart: unless-stopped tty: true ports: - "80:80" - "443:443" volumes: - ./:/var/www - ./nginx/conf.d/:/etc/nginx/conf.d/ networks: - app-network #MySQL Service db: image: mysql:5.7.22 container_name: db restart: unless-stopped tty: true ports: - "3306:3306" environment: MYSQL_DATABASE: laravel MYSQL_ROOT_PASSWORD: your_mysql_root_password SERVICE_TAGS: dev SERVICE_NAME: mysql volumes: - dbdata:/var/lib/mysql/ - ./mysql/my.cnf:/etc/mysql/my.cnf networks: - app-network #Docker Networks networks: app-network: driver: bridge #Volumes volumes: dbdata: driver: local
Шаг 4. Создание Dockerfile
touch Dockerfile
Устанавливает базовый образ и задает необходимые команды и инструкции.
FROM php:7.3-fpm # Copy composer.lock and composer.json COPY composer.lock composer.json /var/www/ # Set working directory WORKDIR /var/www # Install dependencies RUN apt-get update && apt-get install -y \ build-essential \ libzip-dev \ libpng-dev \ libjpeg62-turbo-dev \ libwebp-dev libjpeg62-turbo-dev libpng-dev libxpm-dev \ libfreetype6 \ libfreetype6-dev \ locales \ zip \ jpegoptim optipng pngquant gifsicle \ vim \ unzip \ git \ curl # Clear cache RUN apt-get clean && rm -rf /var/lib/apt/lists/* # Install extensions RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl # Install composer RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer # Add user for laravel application RUN groupadd -g 1000 www RUN useradd -u 1000 -ms /bin/bash -g www www # Copy existing application directory contents COPY . /var/www # Copy existing application directory permissions COPY --chown=www:www . /var/www # Change current user to www USER www # Expose port 9000 and start php-fpm server EXPOSE 9000 CMD ["php-fpm"]
Шаг 5. Настройка PHP
Для настройки PHP создается файл local.ini.
mkdir php touch php/local.ini
Я добавил следующие настройки в этот файл.
upload_max_filesize=10M post_max_size=10M
Это файл, который я подмонтировал к /usr/local/etc/php/conf.d/local.ini внутри контейнера в шаге 2.
Шаг 6. Настройка NGINX
Для настройки Nginx я создал файл app.conf в папке nginx/conf.d
mkdir -p nginx/conf.d touch nginx/conf.d/app.conf
И добавил в него:
server { listen 80; index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/public; location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location / { try_files $uri $uri/ /index.php?$query_string; gzip_static on; } }
Шаг 7. Настройка MySQL
Для настройки MySQL был создан файл my.cnf внутри папки mysql.
mkdir mysql touch mysql/my.cnf
Добавляем следующий код в my.cnf для того, чтобы включить логи и указать их местоположение.
[mysqld] general_log = 1 general_log_file = /var/lib/mysql/general.log
Шаг 8 — Запуск контейнеров
Я определил все сервисы в файле docker-compose и создал файлы конфигурации для этих сервисов. Теперь я запускаю контейнеры командой:
docker-compose up -d
Она загружает все необходимые образы Docker. После этого я просматриваю все запущенные контейнеры и их состояние, используя команду:
docker ps
Шаг 9. Создание пользователя MySQL
Чтобы создать нового пользователя, запустите оболочку bash для контейнера db:
docker-compose exec db bash root@18833a170621:/# mysql -u root -p
Затем создаю пользователя и даю ему все привилегии.
mysql> GRANT ALL ON laravel.* TO 'laraveluser'@'%' IDENTIFIED BY 'my_password';
Сбрасываю привилегии для применения изменений.
mysql> FLUSH PRIVILEGES; mysql> EXIT; root@18833a170621:/# exit
Шаг 10. Обновление настроек окружения
Отредактируем настройки Laravel.
docker-compose exec app vim .env
Обновим учетные данные базы данных и URL приложения.
APP_URL=http://0.0.0.0:8080DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=laraveluser DB_PASSWORD=my_password
Шаг 11. Перенос базы данных
docker-compose exec app php artisan migrate
Теперь у нас есть доступ к нашему приложению Laravel по адресу http://0.0.0.0:8080/
Я развернул это приложение на GitHub: https://github.com/SreejithEzhakkad/laravel-docker
Автор: Sreejith Ezhakkad
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.