July 17, 2019

Laravel in docker (with Blackfire Profiler)

Blackfire profiler
  1. Prepare docker-compose.yml
version: "3"

services:
  #Laravel App
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: hakase-labs/laravel
    container_name: 'laracasts-forum-app'
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
      BLACKFIRE_CLIENT_ID: "${BLACKFIRE_CLIENT_ID}"
      BLACKFIRE_CLIENT_TOKEN: "${BLACKFIRE_CLIENT_TOKEN}"
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html
    networks:
      - laracasts-forum-network

  #Nginx Service
  nginx:
    image: nginx:alpine
    container_name: 'laracasts-forum-nginx'
    restart: unless-stopped
    tty: true
    ports:
      - "3000:80"
      - "443:443"
    volumes:
      - ./:/var/www/html
      - ./docker/conf.d/:/etc/nginx/conf.d/
      - ./docker/ssl/:/etc/nginx/ssl/
    networks:
      - laracasts-forum-network

  #MySQL Service
  mysql:
    image: mysql:5.7.22
    container_name: 'laracasts-forum-mysql'
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: root
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    networks:
      - laracasts-forum-network

  #PhpMyAdmin Service
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: 'laracasts-forum-pma'
    environment:
      PMA_HOST: mysql
      PMA_PORT: 3306
      MYSQL_ROOT_PASSWORD: root
    ports:
      - '8080:80'
    networks:
      - laracasts-forum-network

  #Blackfire Service
  blackfire:
    image: blackfire/blackfire
    container_name: 'laracasts-forum-blackfire'
    environment:
      BLACKFIRE_SERVER_ID: "${BLACKFIRE_SERVER_ID}"
      BLACKFIRE_SERVER_TOKEN: "${BLACKFIRE_SERVER_TOKEN}"
    networks:
      - laracasts-forum-network

#Docker Networks
networks:
  laracasts-forum-network:
    driver: bridge

And Dockerfile

# Set master image
FROM php:7.2-fpm-alpine

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/html/

# Set working directory
WORKDIR /var/www/html

# Install Additional dependencies
RUN apk update && apk add --no-cache \
    build-base shadow vim curl \
    php7 \
    php7-fpm \
    php7-common \
    php7-pdo \
    php7-pdo_mysql \
    php7-mysqli \
    php7-mcrypt \
    php7-mbstring \
    php7-xml \
    php7-openssl \
    php7-json \
    php7-phar \
    php7-zip \
    php7-gd \
    php7-dom \
    php7-session \
    php7-zlib

# Add and Enable PHP-PDO Extenstions
RUN docker-php-ext-install pdo pdo_mysql
RUN docker-php-ext-enable pdo_mysql

# Install php-brobe for Blackfire
ENV current_os=alpine
RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
    && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/$current_os/amd64/$version \
    && mkdir -p /tmp/blackfire \
    && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \
    && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get('extension_dir');")/blackfire.so \
    && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8707\n" > $PHP_INI_DIR/conf.d/blackfire.ini \
    && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz

# Install PHP Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Remove Cache
RUN rm -rf /var/cache/apk/*

# Add UID '1000' to www-data
RUN usermod -u 1000 www-data

# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www/html

# Change current user to www
USER www-data

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Create ini file for nginx

docker/conf.d/lalaravel.conf

And add to laravel.conf

server {
    listen 80;
    server_name php-docker.local;

    # return 301 https://php-docker.local$request_uri;
# }


# server {
    # listen 443 ssl http2;
    # server_name php-docker.local;

    # ssl_certificate /etc/nginx/ssl/fullchain.pem;
    # ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    # Log files for Debug
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    # Laravel web root directory
    root /var/www/html/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }

    # Nginx Pass requests to PHP-FPM
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

2. Create env file from env.dist, sign up Blackfire profile and add Blackfire varaible to env

If you use MacOS - be careful with sql host

APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=192.168.99.101 // for MacOS, docker-machine ip
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

BLACKFIRE_CLIENT_ID=
BLACKFIRE_CLIENT_TOKEN=
BLACKFIRE_SERVER_ID=
BLACKFIRE_SERVER_TOKEN=

3.

docker-compose up -d

4.

docker-compose exec app composer install

5.

docker-compose exec app php artisan migrate

6.

docker-compose exec app composer require omentes/blackfire-laravel-provider

7. Modify your config/app.php

    ...
    'providers' => [
    ...
            omentes\Blackfire\Providers\BlackfireServiceProvider::class,
    ]

8. Install Blackfire chrome extension or add to request X-Blackfire-Query Blackfire Docs

9. Enjoy!

Special for @response418