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
FROM centos:centos7 LABEL maintainer="Vicente Zepeda <[email protected]>" ENV nginxversion="1.12.2-1" \ os="centos" \ osversion="7" \ elversion="7_4" 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
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
You can use my docker-compose file (mariadb, php-fpm, nginx)
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
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 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:
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!
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.
There are a few answers here suggesting two very accurate things:
- Each service should have its own Docker container (as you have discovered)
- Popular methods include custom
docker-composefiles, 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.