Docker for PHP developers
Tips, Tricks & Lessons learned
PhpPrague 2018
Vladimír Kriška
@ujovlado
Slide 2
Slide 2 text
whoami
Programmer (mostly PHP, but also JS)
Developer at Keboola
building ETL platform Keboola Connection
writing about it at 500.keboola.com
technologies: // TODO insert cool words here
twitter.com/ujovlado
ujovlado.com
medium.com/@ujovlado
2
Slide 3
Slide 3 text
How I started with Docker?
I was in a mood to get rid of "host installations"
I was playing with Vagrant and default setup was too slow for me
3
Slide 4
Slide 4 text
Proof
4
Slide 5
Slide 5 text
Now I want everyone to use Docker
5
Slide 6
Slide 6 text
Past
6
Slide 7
Slide 7 text
Past
New computer
Install Apache/Nginx, MySQL/PostgreSQL, PHP, MongoDB, etc.
Start services, start coding
After few weeks:
OMG, this project needs different version of MySQL and PHP ...
Problems
(vedle pasti)
7
Slide 8
Slide 8 text
Future
New computer
Prepare Docker le, build services
Run them, start coding
After few weeks:
OMG, this project needs different version of MySQL and PHP ...
Never mind, I'll add or update services and rebuild images
8
Slide 9
Slide 9 text
Tips & tricks
9
Slide 10
Slide 10 text
Docker Compose
Must have for development
docker-compose up my-app
docker-compose run --rm my-app bash
Very good for testing
docker-compose run --rm my-app ./vendor/bin/phpunit
1. docker-compose up -d
2. run tests
3. docker-compose down
10
Images with option to run sh/bash instantly
Very handy for debugging
Easier than overriding entrypoint
Just append what you need to run
This is very easy:
docker run -i -t --rm debian bash
Shouldn't we prepare every service like this?
13
Slide 14
Slide 14 text
Example
docker-compose run --rm my-app composer install
docker-compose run --rm my-app ./cli.php migrations:migrate
or just:
docker-compose run --rm my-app bash
to enter container and play inside
14
Slide 15
Slide 15 text
Run common CLI commands in Docker
Don't install php locally, you have containers
Don't install tools like travis CLI localy
Prepare images and run commands in container to keep your host
system clean
If you need something, then mount volume
Remember that your PC is only a resource
15
Example (part 2)
#!/bin/bash
docker run -i -t --rm \
-v "/home/vlado/workspace/travis-cli/.travis
:/home/`id -un`/.travis" \
-v "$PWD:$PWD" \
-w $PWD \
-u `id -u` \
travis "$@"
Magic here is volumes section
and $@ which will proxy all passed args to container
17
Slide 18
Slide 18 text
Everything is le and can be mounted as
volume
You want to log something using syslog
Hey, but there's no syslog running in my container
Let's create new service to provide syslog for me
18
Example (part 2)
services:
my-app:
image: debian
volumes:
- ./docker/.syslog-datadir/socket/log:/dev/log
links:
- syslog
command: bash
now you can log to syslog and will see logs using "watcher" service
20
Slide 21
Slide 21 text
Docker in Docker (almost)
Very similar to syslog part, but we mount Docker socket
With mounted socket, container has access to Docker on host
machine
So you can have application running in container and executing
commands like docker run in container
21
Slide 22
Slide 22 text
Example
docker run -i -t docker sh -c 'docker ps -q'
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is
the docker daemon running?
docker run -i -t \
-v /var/run/docker.sock:/var/run/docker.sock \
docker \
sh -c 'docker ps -q'
5a11cca86782
22
Slide 23
Slide 23 text
Lessons learned
23
Slide 24
Slide 24 text
It's easier to start with Apache than with
Nginx
Apache only needs vhost con guration and php.ini -> 1 service
Nginx needs the same plus php-fpm -> 2 services
So if you don't care, use Apache.
24
Slide 25
Slide 25 text
Do not run database in containers
Databases are critical to your businness
You probably won't get it right (me neither)
How would you solve:
backups?
replication?
Probably the best is:
buy database as a service (AWS RDS, etc.)
have databases server (managed by someone)
25
Slide 26
Slide 26 text
Same image for development and production
environment
Only difference should be the code and environment variables
composer install should be run during image build
On localhost, it'll load all dependencies from cache
Code should be copied in image
On localhost override code with volume
Test should run in container
26
Slide 27
Slide 27 text
One Docker image to rule them all
If more programs need your PHP code, it's better to add all these
programs to one image. And than only change program to run.
Apache: FROM php:7-apache (this can be default service)
Cron: RUN apt-get instal cron (to run, override command to cron -f )
PHP CLI: already in Apache image (to run, override command to
php some-script.php )
27
Slide 28
Slide 28 text
Custom PHP builds
Try to avoid building PHP (use FROM php:7 , not
apt-get install php7-cli and similar)
For extensions use docker-php-ext-install
Do not reinvent a wheel - there's a big community behind of cial
images
Of cial images are based on Debian - very common and stable
distribution
Alpine is smaller, but can cause problems (we had one - with
memory)
28
Slide 29
Slide 29 text
Do not try to enter the container
It looks real but with bigger amount of containers starting/stopping
it's almost impossible
You probably only need logs, so send them to stdout
If you need some les from container, use volume or send them to S3
Run another service with mounted Docker socket to collect these
logs
Use logspout to forward logs to 3rd party service like Papertrail
29
Slide 30
Slide 30 text
How to enter the container
To running container with your service (not recommended):
docker exec -i -t 5a11cca86782 - it's very dangerous, because
executing "wrong" commands can kill whole container
If you really need to chcek what's going on - e.g. to be in same
environment, just start one container with long running process - e.g.
tail -f /xyz .
Then docker exec to this container and play.
30