Setting up PHP-FPM, Nginx, Mariadb on CentOs using docker

Docker containers are designed to have a single service running within them, not be an entire virtual system (as you might see with virtual box and virtual machines).

This means ideally you want a single container for each:

  • Nginx
  • PHP
  • Mariadb

Additionally the Centos docker image is designed as a base for others to inherit from, or to perform an OS specific task (for example cURL calls, or a shell) which is not really what you are needing.

I would recommend for your case, using docker-compose which will allow you to easily setup intermediate containers, and manage them all as one project.

I would recommend a docker-compose.yml file setup as such:

version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./src:/(nginx config root folder)
      - ./config/site.conf:/etc/nginx/conf.d/site.conf
    links:
      - php
      - mariadb

  php:
      image: php:7-fpm
  mariadb:
      image: mariadb
      restart: always
      environment:
        MYSQL_ROOT_PASSWORD: example

You would then have a /config/ folder in your project folder, which you'll need a site.conf file for the nginx settings.

You will also need a /src/ folder in your project folder, which would contain all the php/web code for your project.

The volume mounts in the docker-compose.yml file will load those into the container for you. Volume mounts work by mapping host folder path:container folder path when something changes in one, it is updated in the other, almost as if copy/pasting. Keep in mind you may need to update file permissions.

For the Mariadb you could add another volume to map the data files in the container to your host folder. Additionally you can open the mysql port so you could interrogate the database with a tool like mysql workbench by adding a ports section for port 3306 as shown in the web section. The value for mysql_root_password will set the root user password.

You can start this up with the command docker-compose up from your project directory.

When you need to manually restart nginx (or other services) you would stop, and start the containers . you can do that with the commands:

  • docker-compose up - Starts containers
  • docker-compose down - Stops containers

If you wish to send the running container to the background (so it wont take up a terminal window) you would use: docker-compose up -d

Let me know if you have any questions or if something is unclear I'd be happy to update my answer!


You can use my docker-compose file (mariadb, php-fpm, nginx)

https://github.com/matchish/skeleton

Just run

docker-compose up -d

and you will see "Hello world" on http://localhost You can edit environment variables in .env file

Also, I recommend https://laradock.io/

You can run terminal in any service

docker-compose exec db bash
docker-compose exec php-fpm bash
docker-compose exec nginx bash 

Also, you can add database init file. Read manual in this file https://github.com/matchish/skeleton/blob/master/mariadb/docker-entrypoint-initdb.d/createdb.sql.example

To restart services stop container then start it again

docker-compose stop nginx 
docker-compose up -d nginx

if you need edit nginx conf you should rebuild image

docker-compose build nginx 
docker-compose up -d

If you need phpmyadmin you can add it to compose file

phpmyadmin:
  image: phpmyadmin/phpmyadmin
  environment:
    PMA_HOST: db
    PMA_PORT: 3306
  ports:
    - '8181:80'

Now you can access it on http://localhost:8181

The easiest way to use compose in production is just copying project directory to a production server and run docker-compose up -d. You can exclude logs directory. It is good practice to have multiple compose files (https://docs.docker.com/compose/production/)

Don't forget to preserve file permissions when deploy to production


Docker-compose is fine but not the easiest to use. You should really look into Lando as it makes dev environments an absolute cinch to set up. It's basically a usability layer over Docker and it sure is slick.

Before I go any farther, I do need to mention that Lando doesn't really work with Windows 10 Home because the Windows version of Docker uses Hyper-V, which only comes with Win10 Pro. Mac and Linux work fine, though.

Lando has "recipes" which are starting points that reduce the amount of configuration you have to write. If you're developing a Drupal or WordPress site, there are recipes for that. Or if you're writing something from scratch, there are also LAMP and LEMP recipes.

All you have to do after installing Lando is create a config file for your app and launch it. There is a lando init command that generates a config by asking you a few questions, but I prefer to just write the .lando.yml config file by hand as it's not hard.

So if you want a LEMP setup, your config would look something like this:

name: put-your-site-name-here
recipe: lemp
config:
  php: '7.1'        # optional; defaults to the latest version
  webroot: web      # optional; defaults to the same directory as this file
  database: mariadb # technically optional but you did say you wanted this
  xdebug: true      # optional
  conf:             # optional; specify your own configs for nginx and/or php as follows
    server: my-config-path/nginx.conf
    php: my-config-path/php.ini

and that's it! Dump that in a .lando.yml file, run lando start, and you'll have a running app in no time.

Currently the latest beta is the most stable release, but it's nothing to worry about. I use it at work every day. Download it from GitHub.