Laravel and Docker are two very popular tools of choice when considering building for the web. Although both of them do very different things, they can both be combined to create amazing products.
For our use case, we will be running Laravel in a Docker container. This is going to be a simple demonstration on how to use both products to create real-life applications. Nothing heavy.
Before you start, you need to have some certain prerequisites in place:
- Local machine running the latest version of Docker, v1.13.1 at the time of writing this article.
- Local machine running the latest version of Docker compose.
- Server running the latest version of Docker, v1.13.1 at the time of writing this article.
- Laravel Installer installed on your machine (optional but recommended).
To get started, let us create an instance of Laravel running inside a Docker container. We will be starting with a base image and customizing it to suit our applications needs.
# Create the project directory and some subdirectories we will need later $ mkdir -p acme/storage/mysql $ mkdir -p acme/storage/logs $ mkdir -p acme/storage/app # Go into the application directory and create a new laravel application $ cd acme $ laravel new src
Now that we have our Laravel application inside the appropriate directory, let us create a Dockerfile to instruct the Laravel application on how to build. Create a new Docker file at
FROM creativitykills/nginx-php-server:latest MAINTAINER Neo Ighodaro <email@example.com>
The Dockerfile is where we instruct Docker on what to build and how to build it. In this file, we are saying: 'Hey Docker, build a container from the creativitykills/nginx-php-server image, the maintainer is Neo Ighodaro...'. For more information on dockerfiles and the options available to you, read the documentation, but this will do for now.Essential Reading: Learn React from Scratch! (2019 Edition)
Finally, lets create a
./docker-compose.yml file. Make sure it is at the root of your project. We will add our first service which is the web service to the docker compose file.
version: '2' services: web: build: ./src container_name: web ports: - 8888:80 volumes: - ./src:/var/www - ./storage/app:/var/www/storage/app - ./storage/logs:/var/www/storage/logs
Once we have defined the web service file, we can move on to the next thing which is creating a MySQL service. Open the
docker-compose.yml and make sure you have the following.
version: '2' services: mysql: image: mysql:5.7 env_file: - ./mysql.env volumes: - ./storage/mysql:/var/lib/mysql web: build: ./web container_name: web ports: - 8888:80 volumes: - ./web:/var/www - ./storage/app:/var/www/storage/app - ./storage/logs:/var/www/storage/logss
Docker allows you to bring up a container in many ways, you can manually bring up a running instance using
docker run, but sometimes, you will want to bring up multiple containers with one single command and that's where docker-compose comes in.
The version is telling Docker compose what version of the docker-compose syntax tthe current yaml uses. services lists the services we would like to control with docker compose. In the mysql service, we want to build the mysql:5.7 image, load an environment file that contains the MySQL image configuration, and finally mount a volume to the MySQL image for persistent storage of the database data.
Protip: Mounting a volume to the container keeps it alive even after the container is killed. When you mount a folder on the host to the container, the folder is basically mapped to the docker container and can be accessed from either inside or outside the container.
In the web service, one different thing we did is we exposed and mapped a port 8888 (on the host) to 80 (inside the container). We also specified a container_name so we can easily reference the container when we want to.
Now create a new file called
./mysql.env in the root directory, and in there customize these environment values. These will be set as your database credentials when the MySQL container is built.
MYSQL_DATABASE=homestead MYSQL_USER=homestead MYSQL_PASSWORD=secret MYSQL_ROOT_PASSWORD=SuperSecretRootPassword
Protip If you are using a git repository, you might want to
mysql.envfile for security reasons.
Once you are done, you need to edit your Laravel applications
.env file. Update the database configuration to match whatever you set as your MySQL details above. Note that the
DB_HOST value in your Laravel
.env file is equal to the name of the mysql service in the
docker-compose.yml; in this case its
Now, we can bring up our containers
web using a single command.
cd to the root directory of your application and run the command
docker-compose up -d. This should bring up all your services. You can visit the docker URL for your
web container http://localhost:8888 and you should see the awesome Laravel welcome page.
You can ssh into your web container and run the command
php artisan migrate to run migrations on your database. To ssh into your container, run the command:
$ docker exec -it web bash
Docker makes it easy to run consistent disposable environments, and with a little push, it is easy to get up and running with Docker and Laravel. In future articles, I will cover how to create a simple Todo app using our new Laravel + Docker application and also how to scale your Laravel application using Docker compose.