Laravel Dockerization out of the your box

Laravel Dockerization out of the your box

Docker is an open source platform that makes it possible for software developers to Build, Ship, and Run any App anywhere. In a high-level explanation, a dockerized App can be likened to a flower…

*Docker *is an open-source platform that makes it possible for software developers to Build, Ship, and Run any App anywhere.

In a high-level explanation, a dockerized App can be likened to a flower growing in a bucket whereby the bucket contains all that the flower needs to survive notwithstanding the environment.

It basically places (containerizes) the App in a container that houses all that the App needs to run.

This article assumes that the reader already understands how to use Laravel, our business is how to dockerize it.

Requirements

To get a Laravel app running on Docker, the following must be put in place:

  • Laravel installed on your local machine. See the official documentation for steps to installing Laravel.
  • Docker installed on your local machine. Check here to install the appropriate distribution for your operating system
  • Docker Compose installed on your local machine.
  • Knowledge of the command line, if you're a Linux user, you should check out this Linux tutorial to understand basic Linux commands

If you've met the requirements above, then you're ready and good to go. Let's dive deep into the main business.

Getting started

Before we proceed, it's important we explain some basic concepts that we'll be using in this tutorials. Most prominent among them are images and containers.

Images*: The filesystem and metadata needed to run containers. They can be thought of as an application packaging format that includes all of the dependencies to run the application, and default settings to execute that application. The metadata includes defaults for the command to run, environment variables, labels, and healthcheck command.> *Containers: An instance of an isolated application. A container needs the image to define its initial state and uses the read-only filesystem from the image along with a container specific read-write filesystem. A running container is a wrapper around a running process, giving that process namespaces for things like filesystem, network, and PIDs. Another analogy that explains images and containers is class and objects in object-oriented programming. An image is a class while a container is an object of the class.

Explaining further; in order to run a Laravel app on our local machine, we install LEMP, WAMP, XAMP, or MAMP as the case may be as well as phpmyadmin if it's needed. These pieces of software are bundled as images in docker environment. This means, to dockerize a Laravel app, we need to create an image that contains each of those packages, or we create different images for each of them and internetwork them inside the docker container

In this article, we'll not be creating images from scratch, we are going to pull already built images from docker hub. Below are the images we are going to pull from docker hub to enable us dockerize our app:

  • creativitykills/nginx-php-server -php and nginx maintained by Neo Ighodaro
  • mysql:5.7
  • phpmyadmin/phpmyadmin

Click on each of the images to read details about them. Having established the necessary theories about what we are going to do, let us begin the main processes of dockerizing the app following the steps below.

Step 1 - Create the Laravel Project to be dockerized

Create the Laravel project that you want to dockerized. Open your terminal and cd into the root of the project.

[email protected]:/var/www/html/laravel-dockerization$

Step 2- Create the docker-compose.yaml file

$ touch docker-compose.yaml

Next up, edit the docker-compose.yaml file as follows:

version: '3'
services:
  core_services:
    image: creativitykills/nginx-php-server
    container_name: core
    ports:
      - "44678:80"
    volumes:
      - ./:/var/www
    networks: 
      - backend

  mysql:
    container_name: db_mysql
    image: mysql:5.7
    ports:
      - "33062:3306"
    environment:
      - "MYSQL_ROOT_PASSWORD=${DB_PASSWORD}"
    volumes:
      - "./db/mysql/data:/var/lib/mysql"
      - "./db/mysql/initdb.d:/docker-entrypoint-initdb.d"
    networks: 
      - backend
  pma:
    container_name: pma
    image: phpmyadmin/phpmyadmin
    ports:
      - "44679:80"
    environment:
      - "PMA_HOST=db_mysql"
      - "MYSQL_DATABASE=${DB_DATABASE}"
      - "MYSQL_ROOT_PASSWORD=${DB_PASSWORD}"
    networks: 
      - backend

networks:
  backend:
    driver: bridge

We’ve finished what we need to do, but before we summarize, let me explain what is happening in the YAML file above.

On line 1, we specified the version of docker-compose to be used.

On line 2, we declared the beginning of the definition of our services, services here literally means images.

On line 3, we declared the first service name core_services; note that the name is up to you to decide. This service would be an image comprising the Nginx and PHP interpreter and other dependencies such as composer.

On line 4, we specified the name of the image to be pulled from the docker hub.

On line 5, we specified the container name, that is the name for any instance of the core_services image. Note that the name is up to you to decide.

On line 6–7, we specified the port through which we can access the app on the browser. It means we can access the app by visiting 0.0.0.44678 on the browser.

On line 8–9, we mapped the directory of our project to /var/wwwinside the docker container. What it means is, copy the entire project located in /var/www/html/laravel-dockerization to /var/www inside the container. With this, any change we make externally in the project directory will be reflected inside the docker container and vice versa.

On line 10–11, we specified the network to be used by the container so that any other container connected to the same network and communicate with each other. If you do not specify a network, docker creates one an attach the container to it. It’s advisable you specify the network to be used so that you can have full control of its behavior.

From line 13–23, we created the mysql service. We specified the version to be used as 5.7, this can change depending on your choice. We specified the MYSQL_ROOT_PASSWORD. This ${DB_PASSWORD} means replace this with the value of DB_PASSWORD in the .env file. So, ensure that the value of DB_PASSOWRD in the .env is the password you want to use for mysql.

On line 20–21, we mapped the volume from the external directory to the mysql container volume. This volume ensures that data stored in the database is persisted in the local machine even if the container is deleted. You can name the directory what you choose to but ensure you create it before the mapping.

On line 22, we mapped the external directory ./db/mysql/initdb.d to docker-entrypoint-initdb.d. This volume is used importing data into the database. For instance, if you want to import an SQL dump into the database, you need to copy the sql dump file into the db/mysql/initdb.d and then access the file from docker-entrypoint-initdb.d inside the db_mysql container. We’ll demonstrate how to do this later in this article. You can read more about docker-entrypoint here.

From line 24–34, we created the phpmyadmin service with the container name pma. We exposed port 44679 which means we can visit 0.0.0.44679 to access the phpmyadmin. On line 30, you’ll notice we specified the PMA_HOSTas the MySQL container db_mysql, this is very important. If the PMA_HOST is not in sync with the mysql container, you’ll not be able to access your phpmyadmin as the PMA_HOST will default to localhost. We also specified the MYSQL_ROOT_PASSWORD and MYSQL_DATABASE to use the DB_PASSWORD and DB_DATABASE in the .env respectively. Note that MYSQL_DATABASE is optional.

From line 36–38, we defined the backend network that we connected the containers in the previous lines. When docker encounters the backend network, it will look for where it’s defined and create it first before continuing.

Next up, we confirm that the correct values are passed to the docker-compose from the .env by running the command below:

$ docker-compose config

The output of the command above should look like the screenshot below:

Below is the look of my .env file:

...
DB_CONNECTION=mysql
DB_HOST=db_mysql
DB_PORT=3306
DB_DATABASE=laravel_dockerization
DB_USERNAME=root
DB_PASSWORD=secret
...

Notice that the DB_HOST is set to the name of the mysql container defined in the docker-compose.yaml.

Step 3 — Building the containers

Now that we have set up the docker-compose.yaml, we are set to build the containers. Run the command below at the root of your project:

$ docker-compose up -d

The command above will build the containers and start them up. The flag -d starts the containers in interactive mode, the processes run in the background and you’ll be able to run other commands subsequently, but if you’d want to monitor the build processes, then just run:

$ docker-compose up

Next up, we need to give full permission to the storage directory so that docker would be able to read and write to it, run the command below:

$ sudo chmod 777 -R ./storage

Now, if the docker-compose command above build successfully, we confirm that the containers are running as supposed by running the command below:

$ docker ps

The output of the command above should look like the screenshot shown below:

The screenshot above shows that all the containers are running as expected. If all of the three containers are not running, it means something has gone wrong. You need to drop the containers and rebuild again removing the -d flag. This will make the build process verbose and you can easily point what went wrong and get it fixed. To do this run the command below:

$ docker-compose down && docker-compose up

Now head to the browser and visit <a href="http://0.0.0.0:44678" target="_blank">http://0.0.0.0:44678</a> and voila! our app is up!

To view the phpmyadmin dashboard visit <a href="http://0.0.0.0:44679" target="_blank">http://0.0.0.0:44679</a>:

Note: if the database is not created automatically, you can manually create it using the PMA GUI or via MySQL command line. Step 4 — Interacting with the containers

Now that the app is up and running, you might want to interact with the container to performs actions like running migration or importing SQL dump into the database. To enter the container, run the command below:

$ docker exec -it core bash

Remember that core is the name of the php and nginx container. You can now run migration inside the container.

$ php artisan migrate

To enter the mysql container, run:

$ docker exec -it db_mysql bash

How to import SQL dump file into the database

There are situations that you might want to import large SQL dump file into your database, in this case, you might want to do it via the terminal. Follow the steps below to achieve that:

  • First copy the SQL dump into db/mysql/initdb.d
  • Enter the mysql container using docker exec -it db_mysql bash
  • run cd docker-entrypoint-initdb.d
  • $ ls // to be sure the sql file is there
  • $ mysql -h localhost -u root -p <database_name> < sql_dump_file.sql
  • You’ll be prompted to enter your mysql password.

    Note that, in copying the SQL dump file to the initdb.d, if you don’t have root access on your machine, you might want to use sudo command to copy the file via the terminal as shown below:

    $ sudo cp /path/to/sql_dump_file.sql db/mysql/initdb.d
    

The screenshot below shows the steps above being applied.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--14DrRZf---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/mtjl17iddo3ga2qhy2py.png)
### **Conclusion**

In this article, we have demonstrated how to dockerize a Laravel application using already built docker images from the docker hub. We tried to explain what goes on in the docker-compose.yaml and also showed how we can interact with the containers and as well as showed how we can import SQL dump into the MySQL container.

***Thanks for reading. If you liked this post, share it with all of your programming buddies!***

*Further reading*

☞ [Docker Containers for Beginners](https://morioh.com/p/c310f568c20d "Docker Containers for Beginners")

☞ [Things You Should Know About Docker Containers](https://morioh.com/p/42da206d6cbe/things-you-should-know-about-docker-containers "Things You Should Know About Docker Containers")

☞ [Deploy Docker Containers With AWS CodePipeline ](https://morioh.com/p/29c31e88340a "Deploy Docker Containers With AWS CodePipeline ")

☞ [Docker Mastery: The Complete Toolset From a Docker Captain](http://learnstartup.net/p/r18lJJ_1Te "Docker Mastery: The Complete Toolset From a Docker Captain")

☞ [Docker and Kubernetes: The Complete Guide](http://learnstartup.net/p/7bXEiVS7Q "Docker and Kubernetes: The Complete Guide")

☞ [Docker for the Absolute Beginner - Hands On - DevOps](http://learnstartup.net/p/rkb9C-KiZ "Docker for the Absolute Beginner - Hands On - DevOps")

☞ [Docker Crash Course for busy DevOps and Developers](http://learnstartup.net/p/Sy8T4CfkM "Docker Crash Course for busy DevOps and Developers")

☞ [The Docker for DevOps course: From development to production](http://learnstartup.net/p/rgWjLg9Bx "The Docker for DevOps course: From development to production")

☞ [Docker for Node.js Projects From a Docker Captain](http://learnstartup.net/p/8oetVmxT4 "Docker for Node.js Projects From a Docker Captain")

☞ [Docker Certified Associate 2019](http://learnstartup.net/p/g-0cWZJjr "Docker Certified Associate 2019")

☞ [Selenium WebDriver with Docker](http://learnstartup.net/p/9fGLIrlWl "Selenium WebDriver with Docker")

docker laravel devops web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Laravel Development Company

Skenix Infotech is a top Laravel Website Development Company with Expert Laravel Developers that provides robust Laravel Development Services at fair costs.

Hire Dedicated DevOps Developers

Hire our Dedicated DevOps Developers who have in-depth skills and expertise to develop an interactive and secure web application. Get custom DevOps solutions for your project.

How to Hire Laravel Developers and How Much Does It Cost.

Want to make the most out of the latest Laravel technology? Here is your guide on how to hire the best Laravel developer, and at the right price. 

Hire DevOps Developer

Looking to hire top DevOps developers at affordable prices? **[Hire DevOps Developer](https://hourlydeveloper.io/hire-dedicated-devops-developer/ "Hire DevOps Developer")** from **[HourlyDeveloper.io](https://hourlydeveloper.io/...

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...