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