What are Docker Containers
Docker is a simple standard to define the environment your code requires to run.
Unlike a virtual machine (VM), containers do not have high overhead and hence enable more efficient usage of the underlying system and resources. Containers use low-level mechanics of the host operating system, containers provide most of the isolation of a VM at a fraction of the computing power.
Containers offer a way to abstract applications from the environment they actually run in. Decoupling allows container-based applications to deployed consistently, regardless of whether the target environment is a private data center, the public cloud, or even a developer’s personal laptop. This gives developers the ability to create predictable, isolated environments that can run anywhere.
Install
See guides to install Docker on Mac, Windows, and Linux.
Setting up a repo to use Docker
Anatomy of a Dockerfile
FROM
defines the base images to extend e.g.FROM php:7.2-apache-stretch
an image with php and apache already install.RUN
is for running bash commands to install or configure your docker environment e.gRUN a2enmod rewrite
will enable the apache rewrite module.
Below is an example of the simple Dockerfile
I use to run simple PHP projects.
FROM php:7.2-apache-stretch
RUN docker-php-ext-install mysqli
RUN a2enmod rewrite
RUN apt-get update
RUN apt-get upgrade -y
RUN update-ca-certificates
To use the Dockerfile
run docker build daim/php:beta .
and docker run daim/php:beta
.
Anatomy of docker-compose.yml
services
define containers to run you can see in the below file PHP and MySQL containers defined.volumes
mount your local files to sync into the container so when you update a file it's synced into the container. Volumes can also save data from a container to your computer e.g. save your mysql database so it doesn't get deleted with the container.ports
exposes the container to your host system on that port.
version: '3.1'
services:
php:
build:
context: .
image: php:7.2-apache-stretch
ports:
- 80:80
volumes:
- ./:/var/www/html/
mysql:
image: 'mysql:8'
volumes:
- 'mysql:/var/lib/mysql'
Running docker-compose up
creates the containers defined in docker-compose.yml
. It's simpler to run docker-compose
rather than passing all the arguments via cli to docker run
.
View the running containers with VSCode docker extension (recommended) or using the docker ps
command.
Benefits
The environment you deploy code to in production is the same you test and run it on your machine. Every developer can share the same environment definition.
Run more than one version of PHP at the same time
Let’s say you have three different PHP applications that you plan to host on a single server (which could either be a physical or a virtual machine). Each of these applications makes use of a different version of PHP, as well as the associated libraries and dependencies, differ from one application to another. Since we cannot have different versions of PHP installed on the same machine, this prevents us from hosting all three applications on the same computer.
Using Docker we can have 3 versions of PHP running at the same time on one computer.
Issues
Mounted volume speed
MacOS can have issues with file system speed, most visible when running NPM or Composer install.
Some solutions offered in this article Docker on MacOS is slow and how to fix it.
Solutions
- Mutagen Moves code in real-time with fast two-way file synchronization. I've used it for Magento 2 Development. I've had issues getting Mutagen to run and with slow builds taking 30 minutes to copy files. But once copied the container file system did run faster.
- VSCode Dev Container are a promising standard for running dev environments that might be worth exploring.
- New Docker for Mac VirtioFS file sync is 4x faster
Root user
Docker runs as a root user which gives it privileged accessed to your computer which can be exploited by malicious docker containers.
Solutions
- 🤷 Does it matter? This hasn't been an issue for me. It means sometimes I need to change ownership of files from root to user.
- Run docker in rootless mode
- Dev container define non root user
- Define a non root user in Dockerfile
- Use Podman rather than Docker.
Alternatives
- XAMPP is an easy to install Apache distribution containing MariaDB, PHP, and Perl.
- Laravel Valet is a development environment for macOS minimalists.
- Laravel Homestead is an official, pre-packaged Vagrant box that provides you a wonderful development environment without requiring you to install PHP, a web server, and any other server software on your local machine.
Feature | Docker | Homestead | Valet | XAMPP |
---|---|---|---|---|
Windows | ✔️ | ✔️ | ❌ | ✔️ |
Linux | ✔️ | ✔️ | ❌ | ✔️ |
MacOS | ✔️ | ✔️ | ✔️ | ✔️ |
Dependency Isolation | ✔️ | ✔️ | ❌ | ❌ |
Share Dependency Definition | ✔️ | 🤷 | ❌ | ❌ |
Runs Anywhere (Production) | ✔️ | ❌ | ❌ | ❌ |