DEV Community

loading...
Cover image for PHP + MySQL using Docker Compose

PHP + MySQL using Docker Compose

alysivji profile image Aly Sivji Originally published at alysivji.github.io ・2 min read

This post was originally published on Siv Scripts

Being a Software Engineer isn't just about being effective in a specific programming language, it's about being able to solve any given problem using the tools at hand.

This week at work I have to extend the functionality of a WordPress plug-in so it can fit into our microservices-based backend architecture. This means learning enough PHP to write some production-grade code.

I don't want to install PHP on my local machine so this is the perfect use case for Docker! In this Quick Hit, I will describe how to create a containerized PHP + MySQL development environment using Docker Compose.

The LAMP Stack is back!


Instructions

  • We'll start by creating a folder for this project:

    mkdir lamp-stack && cd lamp-stack

  • Create another subdirectory, /php which contains the following index.php file:

<!-- ./php/index.php -->

<html>
    <head>
        <title>Hello World</title>
    </head>

    <body>
        <?php
            echo "Hello, World!";
        ?>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode
  • Populate docker-compose.yml with the following configuration:
# ./docker-compose.yml

version: '3'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: my_secret_pw_shh
      MYSQL_DATABASE: test_db
      MYSQL_USER: devuser
      MYSQL_PASSWORD: devpass
    ports:
      - "9906:3306"
  web:
    image: php:7.2.2-apache
    container_name: php_web
    depends_on:
      - db
    volumes:
      - ./php/:/var/www/html/
    ports:
      - "8100:80"
    stdin_open: true
    tty: true
Enter fullscreen mode Exit fullscreen mode
  • Our directory structure should look as follows:
$ tree
.
├── docker-compose.yml
└── php
    └── index.php
Enter fullscreen mode Exit fullscreen mode

Time to learn some PHP!

Notes
  • We use port-forwarding to connect to the inside of containers from our local machine.
    • webserver: http://localhost:8100
    • db: mysql://devuser:devpasslocalhost:9906/test_db
  • Our local directory, ./php, is mounted inside of the webserver container as /var/www/html/
    • The files within in our local folder will be served when we access the website inside of the container

Discussion (6)

pic
Editor guide
Collapse
ripsup profile image
Richard Orelup • Edited

Thanks for the article. While trying to run through the above I ran into this error


ERROR: In file './docker-compose.yml', service must be a mapping, not a NoneType.

which I solved by updating docker-compose.yml to this

version: '3'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: my_secret_pw_shh
      MYSQL_DATABASE: test_db
      MYSQL_USER: devuser
      MYSQL_PASSWORD: devpass
    ports:
      - "9906:3306"
  web:
    image: php:7.2.2-apache
    container_name: php_web
    depends_on:
      - db
    volumes:
      - ./php/:/var/www/html/
    ports:
      - "8100:80"
    stdin_open: true
    tty: true

The indentation matters and this finally got it working. Hope this helps anyone else trying to use this.

Collapse
alysivji profile image
Aly Sivji Author

Thanks for the heads up!

Didn't realize the indentation got messed up as I copied this over. It has been corrected.

Collapse
ripsup profile image
Richard Orelup

I'm just getting in to Docker so I'm actually glad it had that issue so I'm now aware that I have to get the indentation correct. :)

Collapse
valenzuelatalo profile image
Gonzalo Valenzuela

Thanks, Aly. I have a question: if the container is restarted, are the MySQL databases lost? In other words, is there persistence in the database?

Collapse
alysivji profile image
Aly Sivji Author • Edited

The setup I describe above stores data inside of the container. This data is lost when the container is deleted (docker-compose down)

You could mount a volume so the data is persisted on your local machine.

Looking at hub.docker.com/_/mysql/ (search for Where to Store Data), we can update the docker-compose.yml with another volume mount as follows:

# ./docker-compose.yml

version: '3'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: my_secret_pw_shh
      MYSQL_DATABASE: test_db
      MYSQL_USER: devuser
      MYSQL_PASSWORD: devpass
    volumes:
      - ./sql:/var/lib/mysql
    ports:
      - "9906:3306"
  web:
    image: php:7.2.2-apache
    container_name: php_web
    depends_on:
      - db
    volumes:
      - ./php/:/var/www/html/
    ports:
      - "8100:80"
    stdin_open: true
    tty: true

Now data will persist in the ./sql directory.

Collapse
valenzuelatalo profile image
Gonzalo Valenzuela

Thank you very much!