DEV Community

Cover image for How to run Laravel using Docker
Kyle Parisi
Kyle Parisi

Posted on

How to run Laravel using Docker

Laravel has official documentation for running laravel locally here. The documentation doesn't touch on how to use docker. Laradock is a good solution, however it tries to provide everything under the sun. I don't need that. I need simplicity so I can code.

At my previous employer I came up with a pretty slick test rig so that I could do end to end tests with typescript. This post will describe my approach to this.

So first thing I needed to provide was a docker image for this to work. That can be found here. From there a docker-compose.yml file can be added to your laravel project with the following configuration.

version: '2'
services:
  app:
    image: kyleparisi/larasible
    ports:
      - 80:80
    environment:
      - APP_ENV=testing
    volumes:
      - ./:/var/www/default

  mysql:
    image: mysql:5.7
    ports:
      - 3306:3306
    environment:
      - MYSQL_DATABASE=homestead
      - MYSQL_USER=homestead
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=secret
Enter fullscreen mode Exit fullscreen mode

One thing I have rarely seen answered is how to do a composer install without running into permission issues between the host and the container. I later found that you can attach the host user id as the owner and this will allow both the host and the container to work with the vendor files.

#!/usr/bin/env bash

docker run --rm \
    --user $(id -u):$(id -g) \
    --volume $PWD:/var/www/default \
    --volume $HOME/.composer:/.composer \
    --workdir /var/www/default \
    --entrypoint "composer" \
    kyleparisi/larasible "$@"
Enter fullscreen mode Exit fullscreen mode

I usually add this bash script to ./scripts/composer.sh and you can run all the typical commands you want. ./scripts/composer.sh install for example. This is nice because you no longer need any dependencies on the host beyond docker. The same thing can be done for the front end dependencies.

#!/usr/bin/env bash

docker run --rm \
    --volume $PWD:/usr/src/app \
    --workdir /usr/src/app \
    node:8 npm "$@"
Enter fullscreen mode Exit fullscreen mode

So add both scripts to a ./scripts/ directory in your laravel project and make them executable.

chmod +x ./scripts/composer.sh
chmod +x ./scripts/npm.sh
Enter fullscreen mode Exit fullscreen mode

Add a .env.testing file to your laravel project which will be used in our test rig.

APP_ENV=testing
APP_KEY=base64:blahblah
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
Enter fullscreen mode Exit fullscreen mode

Now for the meat and potatoes.

#!/usr/bin/env bash

set -e

 [ -f ".env.testing" ] || $(echo Please make an .env.testing file and run: php artisan key:generate --env=testing; exit 1)
export $(cat .env.testing | grep -v ^# | xargs);
echo Starting services
docker-compose up -d
echo Host: 127.0.0.1
until docker-compose exec mysql mysql -h 127.0.0.1 -u $DB_USERNAME -p$DB_PASSWORD -D $DB_DATABASE --silent -e "show databases;"
do
  echo "Waiting for database connection..."
  sleep 5
done
echo Installing dependencies
./scripts/npm.sh install
./scripts/composer.sh install
echo Seeding database
rm -f bootstrap/cache/*.php
docker-compose exec app php artisan migrate --env=testing && echo Database migrated
docker-compose exec app php artisan db:seed --env=testing && echo Database seeded
Enter fullscreen mode Exit fullscreen mode

Add the above script to the root of your laravel project as testrig.sh and also make it executable. This script does everything you need to run your laravel project. It starts up the servers, ensures the database is booted, installs dependencies, runs database migrations, and runs database seeds. These services are exposed to your computer on the standard ports.

./testrig.sh
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost when the script is done to see the laravel welcome screen. Mysql can be found on port 3306. If you had snazzy end to end tests you could add your test command to the end of the testrig.sh file. For example npm test.

From here you can do your "test driven development" or regular development using this test rig. When your done for the day, clean up is super simple.

docker-compose stop && docker-compose rm
Enter fullscreen mode Exit fullscreen mode

Hopefully you'll find this method faster than the official options and simpler than laradock.

Gist of files.

Top comments (3)

Collapse
 
mradom profile image
Omar Mrad • Edited

Hello Kyle, your publication was very useful for me, the docker-compose it's very simple. But I have a little issue, when I try to run php artisan migrate from app, I get error. I tried to add links inside app configuration, but I get the same error. I attach the a screenshot, I'll appreciate your help. Regards

Screenshot

Collapse
 
kyleparisi profile image
Kyle Parisi

Your .env file is wrong. it's trying to connect to 127.0.0.1 in the container which it shouldn't be. If you are using the compose file the details are in the env file above.

Collapse
 
mradom profile image
Omar Mrad

Thanks is working fine now... Regards!