PHP+Nginx+Docker
Tags: php, docker, nginx, xdebug
Published: 2022-09-05 20:01:23

At one time or another I have to create a project from scratch, but sometimes I end up wasting a lot of time just creating the environment, so to make it easier I'll leave something ready with php and nginx using docker

## Readme

Start by adding a `README` to the project and as the project progresses you will edit it until it looks really cool

```shell
touch README.md
```

## Makefile

Now let's organize docker in a folder for that we will use the `Makefile`

```shell
touch Makefile
```

## Docker-composer

And let's create a docker folder and inside it for now only the `docker-composer.yml` file

```shell
mkdir docker && touch docker-composer.yml
```

In my `docker-compose.yml` we will only have **nginx** and **php-fpm** for now

```yml
version: "3.9"
name: default
services:
 nginx_default:
   container_name: nginx_default
   image: nginx:1.17.8
   ports:
     - 80:80
   volumes:
     - ./default.conf:/etc/nginx/conf.d/default.conf
     - ../:/var/www
   links:
     - php_default
 php_default:
   container_name: php_default
   build: ./php
   working_dir: /var/www
   volumes:
     - ../:/var/www
```

_💡Remembering that I like to rename the container's name to have a certain organization, in this one as the project is default, I'll leave `{imagename}_default`_

_💡Remembering that if you put a `.env` file with the project name, avoid creating orfan containers_

```shell
COMPOSE_PROJECT_NAME=mvc
```

If you prefer (I prefer) add the name to your project and it becomes simpler and more organized

## Nginx

One more configuration is the default.conf that we will also put in the docker folder

```conf
server {
   listen 80;

   server_name default.localhost;
   error_log  /var/log/nginx/error.system-default.log;
   access_log /var/log/nginx/access.system-default.log;
   root /var/www/public;

   index index.html index.htm index.php;

   charset utf-8;

   location / {
       #try to get file directly, try it as a directory or fall back to modx
       try_files $uri $uri/ @mod_rewrite;
   }

   location @mod_rewrite {
       #including ? in second rewrite argument causes nginx to drop GET params, so append them again
       rewrite ^/(.*)$ /index.php?route=/$1;
   }

       # You may need this to prevent return 404 recursion.
   location = /404.html {
       internal;
   }

   location ~ \.php$ {
       try_files $uri =404;
       fastcgi_split_path_info ^(.+\.php)(/.+)$;
       fastcgi_pass php_default:9000;
       fastcgi_read_timeout 6000;
       fastcgi_index index.php;
       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       fastcgi_param PATH_INFO $fastcgi_path_info;
   }
}
```

_💡Remembering that I'm changing the names to default_

## Xdebug and Composer

As I like to debug with **xdebug**, so I'll leave it ready together with composer, so that the php dockerfile looks like this

```Dockerfile
# Image and version
FROM php:7.4-fpm
 
# Call PHP images script `docker-php-ext-install` and install language extensions
RUN docker-php-ext-install pdo_mysql
 
# copy the Composer PHAR from the Composer image into the PHP image
COPY --from=composer /usr/bin/composer /usr/bin/composer
 
# Install xdebug
RUN pecl install xdebug && docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
```

and the `xdebug.ini` file that will be copied to the container

```ini
[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal

```

Before finishing, let's adjust the make, looking like this:

```Makefile
up:
    docker-compose up -d

stop:
    docker-compose stop

destroy:
    docker-compose down

build:
    docker-compose up --build -d

```

Here's a little secret, as the docker project is in a separate folder, so for the makefile to find, we can simply create a `.env` file and add our la file, looking like this:

```env
# Docker
COMPOSE_FILE=docker/docker-compose.yml

```

## Composer.json

and finally let's create a `composer.json` file just to inform that I use psr-4, so the autoload is ready

```json
{
   "autoload": {
       "psr-4": {
           "App\\": "app/"
       }
   }
}
```

and let's create an `index.php` just to see if everything is working fine remembering that as in the **nginx** configuration file I am looking for a folder called public, so we have to create it in the public folder

```shell
mkdir public && touch index.php
```

and in `index.php` we will have

```php
<?php
 
require __DIR__ . '/../vendor/autoload.php';

phpinfo();
```

## Conclusion

now we just have to do

```
make build
make composer
```

## Extras

### gitignore

before submitting the project to git remember to add a `.gitignore` file and inform the vendor folder

```
touch .gitignore
```

and as I always use **vscode** I will also inform the folder that it automatically generates

```
vendor
.vscode
```

### Editconfig

I also like to use the **editorconfig**, but before using it I like to activate the format on save of vscode First go to vscode settings
`Code > Preferences > Settings  e ative a função “Format on Save”`

And finally, install the editorconfig extension.

For now we are going to use this configuration

{% gist https://gist.github.com/walternascimentobarroso/7c6ac0e38187ee59ee78bc7883c0327a %}

### LICENSE

finally, as this project is open I will leave the license as MIT

## Project

If you want to use this project as a template for your next projects go to:

https://github.com/walternascimentobarroso/php-nginx-docker

***

## Thanks for reading!

If you have any questions, complaints or tips, you can leave them here in the comments. I will be happy to answer!
😊😊 See you! 😊😊

***

## Support Me

[Youtube - WalterNascimentoBarroso](https://www.youtube.com/channel/UCXm0xRtDRrdnvkW24WmkBqA)
[Github - WalterNascimentoBarroso](https://github.com/walternascimentobarroso)
[Codepen - WalterNascimentoBarroso](https://codepen.io)