Slide 1

Slide 1 text

How to Create PHP Development Environments with Docker Compose

Slide 2

Slide 2 text

DevOps Tech Writer @DigitalOcean @erikaheidi

Slide 3

Slide 3 text

● Part 1: PHP development environments in the wild, how Docker Compose fits in ● Part 2: Building a multi-container environment for Laravel with Docker Compose ● Part 3: Demo Talk Goals

Slide 4

Slide 4 text

Introduction Development Environments, PHP, and Docker Compose

Slide 5

Slide 5 text

PHP Development Environments

Slide 6

Slide 6 text

2000's

Slide 7

Slide 7 text

~2010

Slide 8

Slide 8 text

● Pros: ○ Share, dispose and replicate full envs ○ Easy to Understand ● Cons: ○ Big Footprint ○ Depends on Automation Tools ~2012

Slide 9

Slide 9 text

● Pros: ○ Small footprint, fast and lightweight ○ Eliminates need for heavy automation ● Cons: ○ Not as intuitive as VMs ○ Defining and managing (micro) services ~2014

Slide 10

Slide 10 text

Docker Compose

Slide 11

Slide 11 text

Docker Compose is a tool that allows you to run multi-container application environments based on definitions set in a YAML file. It uses service definitions to build fully customizable environments with multiple containers that can share networks and data volumes. ● Easy to set up and manage ● Multiple composed envs on a single host ● Preserves volume data ● Variables to allow customization

Slide 12

Slide 12 text

Example docker-compose.yml version: '3.7' services: web: image: nginx ports: - "8000:80" This simple docker-compose.yml file creates a service container based on an "nginx" image, redirecting all requests on local port 8000 to port 80 in the container.

Slide 13

Slide 13 text

Up and Running

Slide 14

Slide 14 text

● Controlling the Environment ○ up | down | stop | start ● Monitoring & Troubleshooting ○ ps | logs | top | kill ● Executing Commands on containers ○ exec service_name command Using Docker Compose docker-compose [ command ]

Slide 15

Slide 15 text

Case Study Travellist: a Laravel demo application

Slide 16

Slide 16 text

Travellist

Slide 17

Slide 17 text

Environment Needs Web Server: Nginx We'll use Nginx to serve the application in our development environment. Database: MySQL The application uses a MySQL database to store places and mark them as "visited" or "to go". PHP-FPM PHP-FPM is required to parse the PHP content and return the results to Nginx.

Slide 18

Slide 18 text

Application Needs PHP Extensions Laravel requires a few different PHP extensions that should be installed on the application container. Artisan Commands We need the ability to run Artisan and Composer commands from the host machine. Composer PHP In order to install and update Laravel's dependencies, we'll need Composer installed on the application container.

Slide 19

Slide 19 text

● Nginx ○ pre-built image ● MySQL ○ pre-built image ● App (PHP-FPM) ○ Image based on custom Dockerfile

Slide 20

Slide 20 text

● Application files ○ host app, nginx ● Nginx configuration file ○ host nginx ● MySQL database dump ○ host mysql

Slide 21

Slide 21 text

● host app, nginx, mysql

Slide 22

Slide 22 text

Setting Up a docker-compose.yml

Slide 23

Slide 23 text

App+PHP docker-compose.yml app: build: context: ./ dockerfile: Dockerfile image: travellist container_name: travellist-app restart: unless-stopped working_dir: /var/www/ volumes: - ./:/var/www networks: - travellist This service will be responsible for parsing all PHP requests and command-line calls made with Composer and Artisan. It will build a new image based on the provided Dockerfile.

Slide 24

Slide 24 text

Nginx docker-compose.yml nginx: image: nginx:1.17-alpine container_name: travellist-nginx restart: unless-stopped ports: - 8000:80 volumes: - ./:/var/www - ./docker-compose/nginx:/etc/nginx/conf.d networks: - travellist This service will be responsible for serving the application via Nginx. A port redirection will allow us to access port 80 inside the container through port 8000 in the host.

Slide 25

Slide 25 text

DB docker-compose.yml db: image: mysql:5.7 container_name: travellist-db restart: unless-stopped environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_USER: ${DB_USERNAME} SERVICE_TAGS: dev SERVICE_NAME: mysql ... This service will run a MySQL database to store the application's data. It will extract values from the .env Laravel file to create a new DB and user.

Slide 26

Slide 26 text

DB (cont) docker-compose.yml ... volumes: - ./docker-compose/mysql:/docker-entrypoint-initdb.d networks: - travellist The shared volume contains a .sql file that will be automatically imported (a feature provided by this image).

Slide 27

Slide 27 text

App Dockerfile

Slide 28

Slide 28 text

Dockerfile Dockerfile FROM php:7.4-fpm ARG uid=1000 ARG user=sammy RUN apt-get update && apt-get install -y \ git \ curl \ libpng-dev \ libonig-dev \ libxml2-dev \ zip \ unzip ... This Dockerfile will build a new image based on the php:7.4-fpm official PHP image. We start by installing some required system packages.

Slide 29

Slide 29 text

Dockerfile Dockerfile … RUN apt-get clean && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd # Create system user to run Composer and Artisan Commands RUN useradd -G www-data,root -u $uid -d /home/$user $user RUN mkdir -p /home/$user/.composer && \ chown -R $user:$user /home/$user ... Variables are used to create a new user and grant them the same privileges as your current system user on the host, so that you don't run into permission issues with synced files.

Slide 30

Slide 30 text

Dockerfile Dockerfile ... # Install Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Set working directory WORKDIR /var/www USER $user We then install Composer, set the work dir and change to the new user, so that when we run commands via docker-compose exec, they are executed as the new system user.

Slide 31

Slide 31 text

Directory Tree TERMINAL application/ ├── docker-compose │ ├── mysql │ │ └── init_db.sql │ └── nginx | └── travellist.conf ├── Dockerfile └── docker-compose.yml Here's an overview of what our Docker Compose setup looks like, excluding the application files.

Slide 32

Slide 32 text

Demo Time

Slide 33

Slide 33 text

THANK YOU! @erikaheidi