Home » Php » mysql – Setting up PHP-FPM, Nginx, Mariadb on CentOs using docker

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

Posted by: admin July 12, 2020 Leave a comment


I’m trying to move from from using VirtualBox as my development environment to docker.

With VirtualBox, I mainly install PHP-FPM, Nginx and Mariadb but in Docker, I can’t replicate the same stack despite trying for some days.

Out of all the LEMP/LAMP stack docker guides, only this one chentex/docker-nginx-centos works for me:

Here is the code from the Dockerfile

FROM centos:centos7
LABEL maintainer="Vicente Zepeda <[email protected]>"

ENV nginxversion="1.12.2-1" \
    os="centos" \
    osversion="7" \

RUN yum install -y wget openssl sed &&\
    yum -y autoremove &&\
    yum clean all &&\
    wget http://nginx.org/packages/$os/$osversion/x86_64/RPMS/nginx-$nginxversion.el$elversion.ngx.x86_64.rpm &&\
    rpm -iv nginx-$nginxversion.el$elversion.ngx.x86_64.rpm &&\
    sed -i '1i\
    daemon off;\
    ' /etc/nginx/nginx.conf

CMD ["nginx"]

This works right out of the box, and I can see a default page on http://localhost

The only problem is that, it does not contain PHP-FPM and Mariadb.

I tried to alter the file and add PHP-FPM and Mariadb, but I found out on reddit that each container should have on service, as in one container for nginx, and another for php … and I’m lost on how to make that

How to&Answers:

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


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

  image: phpmyadmin/phpmyadmin
    PMA_HOST: db
    PMA_PORT: 3306
    - '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 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'
    image: nginx:latest
      - "80:80"
      - ./src:/(nginx config root folder)
      - ./config/site.conf:/etc/nginx/conf.d/site.conf
      - php
      - mariadb

      image: php:7-fpm
      image: mariadb
      restart: always
        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!


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
  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.


There are a few answers here suggesting two very accurate things:

  1. Each service should have its own Docker container (as you have discovered)
  2. Popular methods include custom docker-compose files, or adding yet another layer into your stack with provisioning tools like Vagrant, Laravel, Lando, LaraDock, and beyond…

But more to the point is that if you’re experiencing this much difficulty and frustration trying to setup multiple Docker containers for each service for such a simple LEMP stack server (which is complex regardless of your approach), perhaps consider ditching the entire container approach.

Assuming by your profile you are setting up WordPress servers, there are options like Roots Trellis that support PHP Composer, or EasyEngine v4 has Docker already integrated as well.

An even lighter option is my team’s SlickStack which has zero containers and only requires basic knowledge of Bash commands to deploy a LEMP stack server.

You mention wariness of relying on too many third party apps, so these would remove those.