Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to Create PHP Development Environments with...

How to Create PHP Development Environments with Docker Compose

In this talk, presented at DockerCon Online 2020, I demonstrate how you can create a PHP development environment with multiple services using Docker Compose, and a Laravel demo application as case study.

Erika Heidi

May 27, 2020
Tweet

More Decks by Erika Heidi

Other Decks in Technology

Transcript

  1. • 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
  2. • Pros: ◦ Share, dispose and replicate full envs ◦

    Easy to Understand • Cons: ◦ Big Footprint ◦ Depends on Automation Tools ~2012
  3. • Pros: ◦ Small footprint, fast and lightweight ◦ Eliminates

    need for heavy automation • Cons: ◦ Not as intuitive as VMs ◦ Defining and managing (micro) services ~2014
  4. 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
  5. 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.
  6. • 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 ]
  7. 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.
  8. 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.
  9. • Nginx ◦ pre-built image • MySQL ◦ pre-built image

    • App (PHP-FPM) ◦ Image based on custom Dockerfile
  10. • Application files ◦ host app, nginx • Nginx configuration

    file ◦ host nginx • MySQL database dump ◦ host mysql
  11. 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.
  12. 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.
  13. 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.
  14. 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).
  15. 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.
  16. 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.
  17. 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.
  18. 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.