🐳 🐘 🚀 Easily setup a PHP project with Docker
Clone or download
Latest commit cc822f1 Mar 8, 2018

README.md

kickoff-docker-php's logo

kickoff-docker-php

A complete stack for your PHP project powered by Docker

Stable release: v2.5.1 Unstable release: master Travis CI


We're working on a lot of projects at TheCodingMachine and we needed a tool to easily start a PHP project with Docker. That's why we started working on the kickoff-docker-php stack with the following goals in mind:

  • One project = one technical environment
  • A local environment as close as possible to our distant environment
  • Switching quickly between our projects
  • Easy to use

Menu

Features

  • Cross-platform: Windows, Mac, Linux
  • A complete stack: NGINX, PHP-FPM 7.2, MySQL 5.7, phpMyAdmin, Redis, RabbitMQ
  • Centralized logging with Graylog
  • Automatic HTTPS on your local environment
  • A powerful reverse-proxy (Traefik) which can handle automatic HTTPS (via Let's Encrypt) on your production environment
  • Performance gains on Mac and Windows using Docker Sync or Docker for Mac's user-guided cache
  • Lightweight images, mostly based on Alpine
  • Easily configurable: disable the modules you don't need, set your own users and so on!
  • Customizable thanks to Orbit

And more! 😃

Install

Download and install Docker (>= 17.06) for your platform.

Note: This project won't work using the legacy desktop solution, aka Docker Toolbox.

On Linux, you also have to install Docker compose (>= 1.14.0) as it does not come with by default. Also add your current user to the docker group and don't forget to logout/login from your current session.

Then download and install Orbit (>= 3.0.0), a tool for generating files from templates and running commands.

You may now fork this project and clone it or download the latest release from the releases page.

Optional install for performance gains with Docker Sync (Mac and Windows)

Download and install the latest release of Docker Sync.

Note: On Windows, it only works with Windows Subsystem for Linux.

Quick start

Once you've downloaded this project, move to the config folder and copy the file .env.blueprint and paste it to a file named .env.

Linux/Mac Windows
cp .env.blueprint .env copy .env.blueprint .env

Note: If you wish to enable Docker Sync, don't forget to set ENABLE_DOCKER_SYNC to true in your .env file.

In the same folder, open the file project.yml and set the following variables:

  • virtualhost.local with your own virtual host
  • name with your project name

Now open your hosts file...

Linux/Mac Windows
sudo nano /etc/hosts Run Notepad as administrator and open the file located at C:\Windows\System32\drivers\etc\hosts

...and add the following lines at the end of the file:

127.0.0.1   your-virtualhost.local
127.0.0.1   www.your-virtualhost.local
127.0.0.1   traefik.your-virtualhost.local
127.0.0.1   phpadmin.your-virtualhost.local
127.0.0.1   rabbitmq.your-virtualhost.local
127.0.0.1   graylog.your-virtualhost.local

Tip: Don't want to update your hosts file? Set virtualhost.local with your-virtualhost.127.0.0.1.xip.io in your project.yml file. Your applications will be available under *.your-virtualhost.127.0.0.1.xip.io/!

Good 😃? We're now done with the configuration! 🤘

Last but not least, move to the root directory, shutdown your local Apache or anything which could use your 80 and 443 ports, and run:

orbit run kickoff

The installation might take some time, so go for a coffee break! ☕️

Once everything has been installed, open your favorite web browser and copy / paste https://www.your-virtualhost.local and check if everything is OK!

Orbit tasks

Note: You can use the -d flag to have a more detailed output.

Main tasks

Command Description
orbit run Displays available tasks.
orbit run kickoff Generates all configuration files, builds the NGINX and PHP-FPM images and starts the containers. It's a combo of build, proxy-up and up commands.
orbit run shutdown Stops all containers. It's a combo of down and proxy-down commands.
orbit run workspace Connects through ash to the PHP-FPM container. This is where you're able to run useful commands like composer and yarn.
orbit run mysql-cli Opens the MySQL cli as root. On environments <> local, it will ask you the MySQL root password.

Others tasks

Note: you should not use them, unless you know what you're doing!

Command Description
orbit run build Generates all configuration files and builds the NGINX and PHP-FPM images.
orbit run proxy-up Starts the Traefik container.
orbit run up Starts all containers without the Traefik container.
orbit run proxy-down Stops the Traefik container.
orbit run down Stops all containers without the Traefik container.

Project structure

├── config  # Kickoff related configuration files
├── modules # Modules related configuration files
└── app     # The source code of your PHP application

Only the configuration files of your modules and the application source code are directly mounted in the containers. The data of modules like MySQL are stored inside named volumes. You can see those named volumes by running docker volume ls command. They are named using the project name, your current environment and the considered module. If you want to locate those volumes on the host, run docker inspect {volume name} command.

Note: For now, the credentials will only be set the first time the Graylog, MySQL, RabbitMQ containers are launched. If you want to update them after, use the considered dashboard. You could also delete the named volumes, but proceed with caution: it will delete all your data.

Tip: Your app folder should be a git submodule.

Configuration

File Description
config/project.yml Your project configuration values.
config/modules.yml The cross-environments configuration values of your modules.
config/.env The sensitive and environment specific configuration values of your modules.
orbit.yml The Orbit's commands of your project.

Don't hesitate to take a look at those files, as they are provided with nice comments!

Note: If you need to update some values in those files, make sure you have stopped your containers using orbit run shutdown.

Modules

Toolbox

The Toolbox is a simple container which is used to:

  • Generates the self-signed certificate on your local environment
  • Generates the .htdigest file for authentication to the Traefik dashboard on environments <> local
  • Generates the SHA2 password and secret pepper for Graylog authentication
  • Checks if Graylog is ready to receive logs from others containers
  • Checks if others containers have been successfully started

Traefik

The Traefik container is used as a reverse-proxy: it's the entry door which will redirect clients requests to the correct frontend.

It provides a nice dashboard (https://traefik.your-virtualhost.local/) which requires an authentication on environments <> local.

HTTPS

On your local environment, the Toolbox container will automatically generate a self-signed certificate according to the virtual host specified in your project.yml file.

On others environment, we provided TRAEFIK_CERT_FILE_PATH and TRAEFIK_KEY_FILE_PATH variables in your .env file to let you specify the absolute path to your certificates. You may also customize the Traefik configuration located at modules/traefik/traefik.blueprint.toml with ACME configuration to enable automatic HTTPS.

How to enable automatic HTTPS on your production environment: https://gist.github.com/gulien/8fe9debbcb30d97091406a24ef5eea82

Configuration

Variable Location Description
virtualhost.* config/project.yml The virtual host to use according to your environments.
traefik.user config/modules.yml The Traefik user used for generating the .htdigest file. Only required for environments <> local.
TRAEFIK_PREFIX config/.env If true, your URLs will be prefixed with your current environment. This is useful if you wish to have many environments on the same host.
TRAEFIK_LOG_LEVEL config/.env Defines the log level of the Traefik container.
TRAEFIK_PASSWORD config/.env The password of the user defined in the modules.yml file. Only required for environments <> local.
TRAEFIK_CERT_FILE_PATH config/.env The .crt absolute file path. Only required for environments <> local.
TRAEFIK_KEY_FILE_PATH config/.env The .key absolute file path. Only required for environments <> local.

Graylog

The Graylog containers centralize the Docker's logs of the NGINX, PHP-FPM, MySQL, phpMyAdmin, Redis and RabbitMQ containers. It's actually composed of three containers: Elasticsearch, MongoDB and the Graylog server.

You may access the Graylog dashboard (https://graylog.your-virtualhost.local/) using the credentials provided in your configuration files.

Configuration

Variable Location Description
graylog.enable config/modules.yml If true, enables Graylog.
graylog.user config/modules.yml The Graylog root user.
GRAYLOG_PORT config/.env The port on which the Graylog server will receive logs from others containers.
GRAYLOG_PASSWORD config/.env The password of the user defined in the modules.yml file.
GRAYLOG_SERVER_JAVA_OPTS config/.env The Java options for the Graylog server.
GRAYLOG_ES_JAVA_OPTS config/.env The Java options for Elasticsearch.

NGINX

NGINX is the web server of your PHP application.

The NGINX configuration located at modules/nginx/conf.d/php-fpm.conf provides good security defaults. Still, you might have to update it according to the PHP framework you wish to use.

Example for a Symfony application: https://gist.github.com/gulien/64d8c94c5d0e294ac121ea810794757e.

PHP-FPM

The PHP-FPM container has many roles. First, it handles requests from the NGINX container to execute your PHP files. Then, it provides a complete set of tools to help you building your application. You can run them by connecting to it with the orbit run workspace command.

Your PHP application will be accessible under https://your-virtualhost.local/ and https://www.your-virtualhost.local/.

Installed PHP extensions

apcu, bcmath, gd, intl, mbstring, pdo_mysql, phpredis, opcache, soap, xdebug, yaml, zip and more!

You are able to find all installed PHP extensions by running php -m inside your workspace.

Xdebug

Xdebug is a tool for easily debugging your PHP code. We provided simple variables in your .env file as described below.

Example with PhpStorm: https://gist.github.com/gulien/d0933d8f90587a95cec5fd750da41b87.

Available tools

Composer - https://getcomposer.org/

Composer helps you declare, manage and install dependencies of PHP projects.

prestissimo - https://github.com/hirak/prestissimo

composer parallel install plugin.

npm - https://www.npmjs.com/

npm is the package manager for JavaScript and the world’s largest software registry.

yarn - https://yarnpkg.com/lang/en/

FAST, RELIABLE, AND SECURE DEPENDENCY MANAGEMENT

PHP Coding Standards Fixer - http://cs.sensiolabs.org/

The PHP Coding Standards Fixer tool fixes most issues in your code when you want to follow the PHP coding standards as defined in the PSR-1 and PSR-2 documents and many more.

Configuration

Variable Location Description
PHP_MEMORY_LIMIT config/.env Defines the PHP memory limit of the PHP-FPM container.
PHP_FPM_MEMORY_LIMIT config/.env Defines the PHP-FPM memory limit of the PHP-FPM container.
XDEBUG_ENABLED config/.env If true, enables Xdebug.
XDEBUG_REMOTE_HOST config/.env If Xdebug is enabled, set this variable with your local IP address.

MySQL

The MySQL container is the DBMS of this stack.

In your PHP-FPM container, the hostname of the MySQL DBMS is mysql. Also, just use the port 3306 and the credentials defined in the modules.yml and .env files.

There are also three ways to manage MySQL:

  • On local environment, you may access the phpMyAdmin dashboard (https://phpadmin.your-virtualhost.local/); you will automatically be connected as root
  • By running orbit run mysql-cli: it will open the MySQL cli and connect you as root. On environments <> local, it will ask you the MySQL root password
  • By mapping the container's port 3306 to a host port, you are able to use a more powerful tool like MySQL Workbench using 127.0.0.1 (or your server IP) as host and the port defined in the variable MYSQL_HOST_PORT_TO_MAP in your .env file

Note: On production environments, we strongly advise to not put the MySQL port on a public facing port. This should be used only in others environments.

Configuration

Variable Location Description
mysql.enable config/modules.yml If true, enables MySQL.
mysql.user config/modules.yml The MySQL user of your PHP application.
mysql.databases config/modules.yml List of the databases of your PHP application. If they do not exist, they will be created when the MySQL container starts. The previous user will have all privileges on these databases.
MYSQL_PASSWORD config/.env The password of the user defined in the modules.yml file.
MYSQL_ROOT_PASSWORD config/.env The MySQL root password.
MYSQL_ENABLE_PORTS_MAPPING config/.env If true, it will map the port 3306 of the MySQL container with the host port defined below.
MYSQL_HOST_PORT_TO_MAP config/.env The host port to map.

Redis

Redis is the cache store of this stack.

The hostname of Redis in your PHP-FPM container is redis. To configure Redis to be the cache handler of your PHP application, you should refer to the documentation provided by your PHP framework.

Note: You should not use predis, as phpredis is installed by default.

Configuration

Variable Location Description
redis.enable config/modules.yml If true, enables Redis.
REDIS_PASSWORD .env The auth used to access the Redis DBMS.

RabbitMQ

RabbitMQ is the message broker of this stack.

The hostname of RabbitMQ in your PHP-FPM container is rabbitmq. To configure RabbitMQ to be the message broker of your PHP application, you should refer to the documentation provided by your PHP framework.

You may access the RabbitMQ dashboard (https://rabbitmq.your-virtualhost.local/) using the credentials provided in your configuration files.

Configuration

Variable Location Description
rabbitmq.enable config/modules.yml If true, enables RabbitMQ.
rabbitmq.user config/modules.yml The RabbitMQ user of your PHP application.
RABBITMQ_PASSWORD config/.env The password of the user defined in the modules.yml file.

Advanced

Restart strategy

On your local environment, your containers will not restart automatically.

On others environments, if you have enable Graylog, they will also not restart automatically. Indeed, we have to check that Graylog is ready to receive logs from others containers before we start them. In your production environment, you should configure your host to restart in the right order your containers after Docker startup. Indeed, your host provider might restart your server from time to time. Of course, if Graylog is not enable, your containers have been configured to restart automatically. 😉

Many environments on the same host

Let's say you want your staging and production environments to run on the same host. You have cloned two projects, one per environment.

First, check that you have the same virtual host on both environments.

Then, start your production environment by running orbit run kickoff.

Once done, move to the staging environment project folder, and update the following variables in your .env file:

  • TRAEFIK_PREFIX to true
  • GRAYLOG_PORT to another port than the one used by your production environment
  • If MYSQL_ENABLE_PORTS_MAPPING=true on both your environments, update MYSQL_HOST_PORT_TO_MAP in your staging environment to another port than the one used by your production environment

Reminder: On production environments, we strongly advise to not put the MySQL port on a public facing port. This should be used only in others environments.

Last but not least, start your staging environment by running orbit run build up.

Note: Don't run kickoff command, as we only want one Traefik container!

If your virtual host is my-awesome-project.com, your production applications will be available under *.my-awesome-project.com while your staging applications will be available under *-staging.my-awesome-project.com! 🤘

Contributing

Please read our contributing guidelines for instructions.

If you've found a security vulnerability, please e-mail directly: j dot neuhart dot thecodingmachine dot com. Provide enough information to reproduce the bug and make a patch!

Credits


Would you like to update this documentation ? Feel free to open an issue.