How to run Laravel using Docker
Tags: laravel, docker, operations, testing
Published: 2018-07-13 18:28:06

---
title: How to run Laravel using Docker
published: true
description: There is one more alternative to running laravel.
tags: laravel, docker, operations, testing
cover_image: https://thepracticaldev.s3.amazonaws.com/i/xes4906pd72jvnvgymsf.png
---

Laravel has official documentation for running laravel locally [here](https://laravel.com/docs/5.6/installation).  The documentation doesn't touch on how to use docker.  [Laradock](https://github.com/laradock/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](https://hub.docker.com/r/kyleparisi/larasible/).  From there a `docker-compose.yml` file can be added to your laravel project with the following configuration.

```yaml
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
```

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.

```bash
#!/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 "$@"
```

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.

```bash
#!/usr/bin/env bash

docker run --rm \
    --volume $PWD:/usr/src/app \
    --workdir /usr/src/app \
    node:8 npm "$@"
```

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

```bash
chmod +x ./scripts/composer.sh
chmod +x ./scripts/npm.sh
```

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

```bash
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=
```

Now for the meat and potatoes.

```bash
#!/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
```

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.  

```bash
./testrig.sh
```

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.

```bash
docker-compose stop && docker-compose rm
```

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

[Gist of files.](https://gist.github.com/kyleparisi/b1fa7e0da8a5ac64c6c340c72f67ba49)