How to create Laravel Docker image

How to create Laravel Docker image

In this guide, you'll learn how to create a Dockerfile from a Laravel application and use it to build a Docker image that you can use in your Continuous Delivery process.

Hint

Actions used in this guide:

Introduction

Dockerize and deploy Laravel in one click with the easiest CI/CD tool ever designed
Try Buddy for Free

What is Laravel?

Laravel is a popular open source PHP web development framework with an elegant syntax and user-friendly documentation. It follows the Model-View-Controller (MVC) architectural pattern, which helps in creating maintainable and scalable applications, while its robust set of tools and features allow developers to streamline common tasks, such as routing, database management, and authentication.

What is Docker?

Docker is an open-source virtualization method that allows you to automate the deployment, scaling, and management of applications using containerization. Docker makes it easier to create, deploy, and run applications by providing a standardized way to package and distribute software for any operating system. This eliminates the "works on my machine" issue when working across different environments.

  • faster and less resource-consuming than traditional VM's
  • easy to set up and configure
  • a breeze to reuse: pick an existing image as the cornerstone of your setup and install any libraries or packages not bundled with the image
  • shareability: you can push images to Docker registries and pull them on other machines, just like you push and pull code from Git
Tip
This video by Ryan Schachte is a great introduction to the idea of Docker and containerization:

Laravel in Docker

In theory, Dockerization is the process of packaging an application and its dependencies into a Docker container. In case of Laravel applications, this can be translated into the following steps:

  • writing a Dockerfile with configuration instructions for the application
  • building a Docker image from the Dockerfile and pushing it to the registry
  • pulling the image and launching the app on the web server
Success
In this guide, we're going to containerize a simple calculator written with the Laravel framework. Simply fork the repository and Dockerize Laravel with the instructions below!

To check out how the calculator works before baking Laravel into an image, run this command in the repository:

bash
php artisan serve$
Tip
If you'd like to see how to create such app from scratch, we described how to write and run the calculator in this guide.

Step 1: Install Docker

Begin with installing Docker Desktop on your machine:

Step 2: Write a Dockerfile

The Dockerfile is a text that defines the contents and launching method of our Docker image. Open a text editor and create a new file Dockerfile. Populate the file with the following lines and push it to the repository. We are going to break them down one by one later on.

docker
FROM php:8.0 RUN apt-get update -y && apt-get install -y openssl zip unzip git RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN docker-php-ext-install pdo mbstring WORKDIR /app COPY . /app RUN composer install CMD php artisan serve --host=0.0.0.0 --port=8181 EXPOSE 8181

Dockerfile details

Line 1

Just like we mentioned in the introduction, Docker images can be inherited from other users. Using official Docker images guarantees the template is well written and prepared. In this case, we shall use PHP in version 8.0:

dockerfile
FROM php:8.0
Hint
Docker images are shared through image registries. The most popular is Docker Hub. You can browse the list of all official Docker images here.

Lines 2-4:

These lines cover the installation of tools required to install Laravel: Git, Zip, Unzip, and OpenSSL. Next, we run the installation command and run PHP modules: PDO and mbstring.

dockerfile
RUN apt-get update -y && apt-get install -y openssl zip unzip git RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN docker-php-ext-install pdo mbstring

Lines 5-7:

Here we set the working dir in the container to /app, copy the Laravel application files to it, and install dependencies using Composer:

dockerfile
WORKDIR /app COPY . /app RUN composer install

Line 8:

Use CMD to set the command that will be run when launching the Docker PHP image. In our case, we're going to serve the application with php artisan set to port 8181:

docker
CMD php artisan serve --host=0.0.0.0 --port=8181

Line 9:

Expose port 8181 outside the launched container. This is the same port our Laravel application is going to use:

dockerfile
EXPOSE 8181

Step 3: Build Docker image for your Laravel project

With the Dockerfile in place, we're ready to create the Docker image. Fire up the terminal, go to the directory with the Dockerfile, and run the Docker build command:

bash
docker build -t my-first-image .$

The -t parameter is the tag of the Docker image. The dot at the end of the command means that we're going to build the image in the context of the parent directory. In other words, the files that will be copied to the /app directory in the application container are files from the contextual directory of the build (in this case: repository directory).

Step 4: Run Docker image

Time to run Laravel in Docker! Launch the container with docker run. Don't forget to add the parameter with the port:

bash
docker run -p 8181:8181 my-first-image$
Hint
Your Laravel application is now available from your browser at http://localhost:8181.

Sharing images through Docker registry

Once created, a Docker image can be pushed to a Docker registry from which it can be pulled and run by other users. You can create a private registry and serve images from your server, or use a cloud-hosted solution. Currently, the most popular Docker registries are:

In this part of the guide we'll show you how to add an image to Docker Hub so you can use it on another computer. Here's what you need to do:

  1. Create a profile on hub.docker.com/ or log in with an existing one.
  2. Build the Laravel image and tag it with your DH username:
bash
docker build -t [USERNAME]/my-first-image .$
  1. Log in to DH with your username and password:
bash
docker login$
  1. Push the image to the registry:
bash
docker push [USERNAME]/my-first-image$

Image loading...Logging in to DH

That's it. From now on you can pull and run your Laravel application on any computer with Docker installed. The default docker run command will automatically pull and run the image from the selected location:

bash
docker run [USERNAME]/my-first-image$

Image loading...Docker image on DH

Warning
The download from a public provider might take a while depending on the load, so if you run your business from a location with a slow internet connection, consider setting up a private registry for better performance.

Adding database with Docker Compose

You can attach database services to your containers using Docker Compose. Docker Compose is a tool which uses a YAML file to define the services, networks, and volumes required for your application.

Below you'll find an example of a docker-compose.yml file with a definition of a MySQL database. The definition contains the MySQL version, environment variables for the database name, user, and password, and volume mapping to persist the database:

yaml
version: '3' services: app: build: context: . dockerfile: Dockerfile ports: - 8000:80 depends_on: - db db: image: mysql:5.7 environment: MYSQL_DATABASE: laravel MYSQL_USER: laravel MYSQL_PASSWORD: secret MYSQL_ROOT_PASSWORD: secret volumes: - ./data:/var/lib/mysql
Hint
Learn more about Docker Compose in the official Docker documentation.

Docker in practice: Use cases

So far we've covered the technical process of building and sharing Docker images. Below we share some concrete appliance of Docker in everyday work.

Docker in development

Every developer knows that before you start working on an application you first need to prepare your work environment. This involves a series of pains, including but not limited to:

  • installing the framework in version X
  • installing the database in version Y
  • installing the library in version Z

The more advanced the project, the more dependencies and setup it involves, which considerably prolongs the process of delivering the application. We won't even mention the dependency hell when you're trying to develop two applications with different requirements on one computer.

With Docker, you don't need to write documentation detailing the operating system setup because the entire working environment is defined in the Laravel Dockerfile and safely stored in Git. This means you can go back to any revision of the file in the repository to see how your project evolved.

What's even more convenient, you don't need anything but Docker to run the software on your computer because everything else – frameworks, libraries, dependencies – is stored in the image. What you do is run git clone, docker build, and docker run and the app is already running on your computer.

Tip
It's also possible to create a Dockerfile that will serve the application directly from the directory where you code, so that you won't have to rebuild the image on every change!

Docker in QA

Image loading...Every developer knows that phrase

The phrase above is bound to appear whenever a tester and a developer discuss a new feature. In reality, 99% of such problems result from compatibility issues between different environments in which the application is run. One developer codes the application on Linux, another one on Mac, and QA runs the tests on Windows. With Docker, the environment is the same for every member of the team: the app is forwarded to QA in the form of a Docker image pre-configured in the Dockerfile.

Docker for dev/stage/production

Usually, the development process is divided into three consecutive environments:

  • Development environment – where the actual coding takes place
  • Staging environment – where the application is reviewed and tested
  • Production environment – where the final version of the application is hosted

Each of these environments is assigned to a separate branch in the repository. When the work in the development branch is over, it is merged to the staging branch, where the QA runs their tests. Then, the staging branch is merged into the master (production) branch and the application is ready to be reviewed by the client.

With Docker, each environment is described in a separate Dockerfile for every branch. If you change something in the DEV branch, the STAGE branch remains in its original state until the changes have been merged.

Continuous Delivery with Buddy

Dockerize and deploy Laravel in one click with the easiest CI/CD tool ever designed
Try Buddy for Free

Buddy is a tool that lets you streamline the process of building images and launching Docker containers on a manual trigger or a push to the repository.

Success
In this part of the guide, we'll add a pipeline that will build and test a Docker image, push it to the selected registry, and run it on a web server.

Image loading...Continuous Delivery pipeline for Docker

Pipeline configuration

Buddy drops configuration-as-code in favor of visual pipelines that can be arranged using preconfigured actions.

All you need to start is a repository with your project:

  1. Create a new pipeline and set the trigger mode to On push. This way the pipeline will update the image on every change in the selected branch:

Image loading...Pipeline configuration

  1. Add the Build image action and select the Dockerfile with the description of your app:

Image loading...Docker action roster

  1. The next action will test the newly built image before it can be pushed to the registry. Add the Run Image action and indicate the previous action as the source of the image:

Image loading...Run Image action details

  1. Once Builds and tests the image, we can push it to the selected Docker registry. In this example, we'll use Amazon ECR:

Image loading...Push Image action details

  1. The last action will run docker pull and docker run on the selected remote:
default
docker pull [USERNAME]/my-first-image docker run -d -p 80:80 [USERNAME]/my-first-image

Image loading...SSH action details

Once ready, make a push to the selected branch, and watch Buddy will perform all the tasks on auto-pilot. Sweet!

Tip
You can store Docker registry credentials as environment variables for safekeeping and easy update.
Hint
You can create a separate pipeline for each environment, and automate other common developer tasks, such as deployments, tests, and website monitoring.
Jarek Dylewski

Jarek Dylewski

Customer Support

A journalist and an SEO specialist trying to find himself in the unforgiving world of coders. Gamer, a non-fiction literature fan and obsessive carnivore. Jarek uses his talents to convert the programming lingo into a cohesive and approachable narration.