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

Docker for PHP developers - Tips, Tricks & Lessons learned

Docker for PHP developers - Tips, Tricks & Lessons learned

Vladimír Kriška

June 23, 2018

More Decks by Vladimír Kriška

Other Decks in Programming


  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. Example (development) services: my-app: build: . volumes: - ./:/code working_dir:

    /code ports: - "4321:80" command: bash tty: true 11
  7. Example (testing, CI) services: - docker script: - ... -

    docker-compose up -d udp-listener - php tests/run.php - docker-compose logs udp-listener | grep 'Some text' 12
  8. 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
  9. 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
  10. 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
  11. Example (part 1) FROM ruby:2 RUN gem install travis -v

    1.8.2 --no-rdoc --no-ri ARG USER_NAME ARG USER_UID ARG USER_GID RUN groupadd --gid $USER_GID $USER_NAME RUN useradd --uid $USER_UID --gid $USER_GID $USER_NAME ENTRYPOINT ["travis"] $ docker build -t travis \ --build-arg USER_UID=`id -u` \ --build-arg USER_GID=`id -g` \ --build-arg USER_NAME=`id -un` \ . 16
  12. 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
  13. 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
  14. Example (part 1) services: syslog: build: docker/syslog volumes: - ./docker/.syslog-datadir/socket:/syslog-socket

    - ./docker/.syslog-datadir/log:/var/log syslog-watcher: image: debian:8 volumes_from: - syslog command: tail -f /var/log/syslog 19
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 32