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

How to Create PHP Development Environments with Docker Compose

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. How to Create PHP
    Development
    Environments with
    Docker Compose

    View Slide

  2. DevOps Tech Writer
    @DigitalOcean
    @erikaheidi

    View Slide

  3. ● 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

    View Slide

  4. Introduction
    Development Environments,
    PHP, and
    Docker Compose

    View Slide

  5. PHP Development
    Environments

    View Slide

  6. 2000's

    View Slide

  7. ~2010

    View Slide

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

    View Slide

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

    View Slide

  10. Docker Compose

    View Slide

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

    View Slide

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

    View Slide

  13. Up and
    Running

    View Slide

  14. ● 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 ]

    View Slide

  15. Case Study
    Travellist: a Laravel demo
    application

    View Slide

  16. Travellist

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. ● host app, nginx, mysql

    View Slide

  22. Setting Up a
    docker-compose.yml

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. 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).

    View Slide

  27. App Dockerfile

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. Demo Time

    View Slide

  33. THANK YOU!
    @erikaheidi

    View Slide