DEV Community

Nehal Hasnayeen
Nehal Hasnayeen

Posted on • Edited on • Originally published at hasnayeen.dev

Local Development Environment with Docker for PHP (Part-1)

Setting Docker, Portainer, Nginx, PHP and Composer

If you work with different language, tools or technology its really hard some time to manage all these different environments in local machine. Docker is a great tool which give us isolated environment to build our application with required tools and libraries without messing with the host machine. You can package up an application with all of the parts it needs, such as libraries and other dependencies, and run it on any machine which have docker installed without installing a single piece of software. You can use different version of any tools separately without any hassle. So let’s see how can we use docker to setup our development environment to build application with Laravel.

Install docker

I’m using antergos which is arch-linux based os, so installation instructions step below are for arch-linux distro. If you are on Mac or Windows or any other linux distro visit here for installation instruction.

$ sudo pacman -S docker
Enter fullscreen mode Exit fullscreen mode

To start the docker service (for any linux OS that use systemctl)

$ sudo systemctl start docker.service
Enter fullscreen mode Exit fullscreen mode

To start on system boot

$ sudo systemctl enable docker.service
Enter fullscreen mode Exit fullscreen mode

Install Portainer

Portainer is a container which gives a nice ui dashboard to use docker easily. We’ll create and run the portainer container like below

$ sudo docker run -d --name portainer -p 8000:8000 -p 9443:9443 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
Enter fullscreen mode Exit fullscreen mode

Above will create a container from portainer image and then run it in background ( -d flag make the container run in background). The command will search for the portainer image in local machine and if it doesn’t find the image then it will pull the image from docker image registry. We’ll run the container in port 9443 so port 9443 should be available, but if you want to use any other port than specify it via the -p flag ( -p 8080:9443 ). Also notice that we have named our container portainer with — name flag. You can name your container whatever you want. When the download is complete we can check that the container is running by $ docker ps command. It’ll show a list of all the running container

CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS                    NAMES
1f5bb115d327        portainer/portainer   "/portainer"        5 seconds ago         Up 1 second         0.0.0.0:9000->9000/tcp   portainer
Enter fullscreen mode Exit fullscreen mode

Now you can visit the dashboard by visiting localhost in your browser. You’ll see below screen

Provide a password for admin user account and then login to the dashboard. You’ll see a screen like below.

Select the first one and connect, you’ll see a nice dashboard

Create a PHP network

First we will create a network for php application only. Click the network menu from sidebar and then give it some name like php and click create.

Create a php networkCreate a php network

Install Nginx

First we will create a container as our server and we’ll use official nginx image from docker hub. Go to Containers page from sidebar menu and click on Add Container button

Add New ContainerAdd New Container

Let’s give our container a name of server and the image name which is nginx. Click the publish all exposed ports which’ll expose port 80. Next click map additional port and map our host machine port 80 to container port 80 like below

Map host port 80 to container port 80Map host port 80 to container port 80

Next create two folders where you will keep your projects. This can be anywhere in your file system. One folders is to keep our application source code and the other is for nginx configuration.

Now under Advanced Container Settings click the volume tab and bind sites directory to /var/www in container and nginx-conf directory to /etc/nginx/conf.d .

Next select the php network we created earlier in network tab. Finally hit the start container button. First portainer will pull the nginx image from registry and then start the container

Install PHP-FPM

Next we will install php fpm to serve our php application. We’ll create a container using official php-fpm image.

We don’t need to bind any port from our host machine to the container, nginx will send traffic to php-fpm, we just need to select the php network in network tab.

Also we need to map our sites directory to the /var/www directory in the container.

Finally in Command tabs put /var/www as value in Working Dir field

Now start the container by hitting start container button.

Add Application

Let’s try to add our first php website. First add a hello.conf file inside nginx-conf directory with below contents

server {
    listen 80;

    server_name hello.local;

    client_max_body_size 108M;

    access_log /var/log/nginx/hello.access.log;
    error_log /var/log/nginx/hello.error.log;

    root /var/www/hello/public;
    index index.php;

    if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PHP_VALUE "error_log=/var/log/nginx/hello-php.log";
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        include fastcgi_params;
    }
}
Enter fullscreen mode Exit fullscreen mode

This file is for routing traffic to php-fpm. Next add a index.php file inside sites/hello/public directory with following contents

<?php
phpinfo();
Enter fullscreen mode Exit fullscreen mode

And finally add a domain for our site in /etc/hosts file

127.0.0.1    hello.local
Enter fullscreen mode Exit fullscreen mode

Now visit http://hello.local and you’ll see

Now let’s add another site, the procedure is same. First we add conf file for nginx configuration and then add our code in a directory under sites and finally add a domain for that site in /etc/hosts file.

Install PHP Extensions

By default only few extensions are installed in the container. If we want we can install more extensions. First let’s connect to the bash terminal of our php container. If you visit the container page you’ll see a console link, click it

You’ll see a connect button to connect to the bash, click it and you’ll be at /var/www directory.

Now let’s install pdo_mysql extension to use mysql pdo driver by following command

$ docker-php-ext-install pdo_mysql
Enter fullscreen mode Exit fullscreen mode

We’ll also install gd and ext-zip extensions

$ docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && docker-php-ext-install gd

$ apt-get install libzip-dev && docker-php-ext-install zip
Enter fullscreen mode Exit fullscreen mode

You can install other extensions in similar way. After installing any extension restart the container.

Install Composer

Before we install composer first install zip & unzip package which’ll be used by composer for laravel installation.

$ apt-get update && apt-get install zip unzip
Enter fullscreen mode Exit fullscreen mode

And now install composer

$ curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
Enter fullscreen mode Exit fullscreen mode

Let’s check composer is installed and in our path

$ composer --version
Composer version 1.4.2 2017-03-10 09:29:45
Enter fullscreen mode Exit fullscreen mode

Install Laravel

Lets install our first laravel application by running following command

$ composer create-project --prefer-dist laravel/laravel example
Enter fullscreen mode Exit fullscreen mode

It’ll create a new laravel app inside example directory. To make it accessible we have to create a example.conf and add example.local domain in /etc/hosts file. Also we need to change the owner of storage and boostrap folder like below

$ chown -R www-data:www-data storage bootstrap
Enter fullscreen mode Exit fullscreen mode

Now if we visit example.local in the browser we’ll see

Adding another application will be same as before: 1) create a new laravel app inside sites directory, 2) add a new .conf file for that application, 3) add a domain in /etc/hosts 4) change owner of storage and bootstrap folder to www-data .

Conclusion

We have one piece of the puzzle still left, that is database. We’ll see in next post how to add any database to our application and persist the data and also some other tools like redis etc. We’ll also see how can we use another php version to test the same application. Stay tuned!

Part-2

Top comments (2)

Collapse
 
valentinprgnd profile image
Valentin Prugnaud 🦊

I see you are using Laravel. If you are looking for a quick way to set up a local docker environment, I wrote a quick command-line tool recently to do just that: Harbor (build with Laravel Zero)

Collapse
 
hasnayeen profile image
Nehal Hasnayeen

Hey, nice tool but it's not for me. I don't install php or node on my host machine so can't use tool like this also I like to build things up manually and configure the way I like. But anyway nice work on the tool.