Feb 27, 2021 by Thibault Debatty | 14356 views
https://cylab.be/blog/131/run-your-laravel-app-with-docker-compose
Docker-compose is an elegant way to run a Laravel app. It allows to define and run the different services: the main web app, a MySQL database and a redis server. There are however a few tricks to solve: how to run the database migrations, how to run the queue worker and the scheduler?
In this blog post we show one possible approach, where we override the entrypoint directive.
First, create docker-compose.yml like the one below:
version: "3"
services:
myapp:
image: myapp
build:
context: .
depends_on:
- redis
- mysql
ports:
- 8080:80
volumes:
- myapp:/var/www/html/storage
## we wait for the MySQL container to be up and running
## then we run the migration
## and finally we start apache
entrypoint: sh -c "sleep 30 && php /var/www/html/artisan migrate && apache2-foreground"
queue:
image: myapp
depends_on:
- myapp
volumes:
- myapp:/var/www/html/storage
## for the queue worker, we use the same image, but run
## artisan queue:work
entrypoint: php /var/www/html/artisan queue:work --verbose --tries=3 --timeout=60
scheduler:
image: myapp
depends_on:
- myapp
## for the scheduler we use an infinite while loop
entrypoint: sh -c "while true; do php /var/www/html/artisan schedule:run --verbose & sleep 60; done"
redis:
image: redis:4-alpine
volumes:
- redis:/data
mysql:
image: mysql:5.7
volumes:
- mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: myapp
volumes:
myapp:
driver: "local"
redis:
driver: "local"
mysql:
driver: "local"
Now create the appropriate Dockerfile to build your image. In the example below we use a multi-stage build. You can also find some inspiration in the other blog post Dockerize your Laravel app - part 2
#### Step 1 : composer
FROM cylab/php74 AS composer
COPY . /var/www/html
WORKDIR /var/www/html
RUN composer install --no-dev --optimize-autoloader
#### Step 2 : actual docker image
FROM php:7.4-apache
## PHP extensions
RUN docker-php-ext-install pdo_mysql
RUN pecl install -o -f redis
&& rm -rf /tmp/pear
&& docker-php-ext-enable redis
## Apache
# change the document root to /var/www/html/public
RUN sed -i -e "s/html/html/public/g"
/etc/apache2/sites-enabled/000-default.conf
RUN a2enmod rewrite
## Laravel application
COPY . /var/www/html
# I like to use a dedicated .env file to prive sound defaults
COPY env.docker /var/www/html/.env
COPY --from=composer /var/www/html/vendor /var/www/html/vendor
RUN mkdir -p storage/framework/cache storage/framework/sessions storage/framework/views
&& chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
&& php artisan config:clear
As you may have noticed above, I like to have a dedicated .env file to run the application. Here is an example env.docker:
APP_NAME=myqpp
APP_ENV=prod
APP_KEY=base64:ezEe4jH/6EUM2fMWLnco3kuMz1OMStq/XfV456ZwMhc=
APP_DEBUG=false
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=root
BROADCAST_DRIVER=log
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
You are now ready to run your app:
docker-compose up --build
This blog post is licensed under CC BY-SA 4.0