Docker Usage for Local Development

This documents hwo to use docker for local development on OSX but can be modified to run under windows, it uses a multi stage build process and the latest alpine images to keep the container sizes to a minimum. it fully supports xdebug and a server version of mysql server. This presents a very fast development experience that does not pollute the host operating system.

Why I Use Docker

Docker plays a crucial role in my deployment strategy. It allows me to containerize my Laravel applications, ensuring consistency across different environments and across multiple services that I need to run a production Laravel app - Queue workers, Schedulers, Nightwatch agent, etc..

  1. Consistent Environments: Every deployment maintains the same configurations, reducing bugs and deployment issues.

  2. Scalability: Docker’s lightweight containers.

  3. The possibility for automated deployment, Integration with Git allows for continuous deployment workflows.

Docker Compose

  1. We assume you have docker installed and running
  2. and also docker-compose installed
  3. you can also use laravel sail *** the configuration overrides the default sail definitions
services:
  php-fpm:
    build:
      context: ./docker/php-fpm
      dockerfile: Dockerfile
    container_name: laravel-php
    working_dir: /var/www/html
    volumes:
      # ##########################################################
      # Source code via bind mount (fast reads on mac:delegated)
      # This makes docker much faster
      # ##########################################################
      - ./:/var/www/html:delegated
      # ##########################################################
      # Hot paths on named volumes (fast writes, Linux FS)
      # This means we have very fast writes as they are not replicated
      # to the host file system, this means that they must be recreated
      # when built and also you must run composer install as well
      # ##########################################################
      - vendor:/var/www/html/vendor
      - storage:/var/www/html/storage
      - cache:/var/www/html/bootstrap/cache
    environment:
      PHP_OPCACHE_ENABLE: "1"
      PHP_OPCACHE_MEMORY: "256"
      PHP_FPM_MAX_CHILDREN: "16"
      XDEBUG_MODE: "debug,develop"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    expose:
      - "9000"
      - "9003"
    networks:
      web:
      shared:
        aliases: [ api.medidev.vm, nginx, gateway ]
  nginx:
    image: nginx:alpine
    container_name: laravel-nginx
    entrypoint: [ "nginx", "-g", "daemon off;" ]
    depends_on: [ php-fpm ]
    volumes:
      - ./:/var/www/html:ro,delegated
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./docker/nginx/logs:/var/log/nginx
      - ./docker/nginx/ssl:/etc/nginx/ssl:ro
    ports:
      - "80:80"
      - "443:443"
    networks:
      web:
      shared:
        aliases:
          - nginx
          - gateway
          - api.medidev.vm
  redis:
    image: redis:alpine
    container_name: laravel-redis
    command: [ "redis-server", "--save", "", "--appendonly", "no", "--loglevel", "warning" ]
    ports:
      - "6379:6379"
    networks: [ web ]
  mysql:
    image: mysql:9.0
    container_name: laravel-mysql
    command: [ "mysqld", "--log-error-verbosity=2","--mysqlx=0","--defaults-file=/etc/mysql/conf.d/my.cnf" ]
    logging:
      driver: "none"
    environment:
      MYSQL_ROOT_PASSWORD: "987400Kmh"
      MYSQL_DATABASE: "AAMEDIUK"
      MYSQL_LOG_CONSOLE: "false"
      #>/dev/null 2>&1
    entrypoint: [ "sh","-lc","exec mysqld --datadir=/var/lib/mysql --user=mysql --mysqlx=0 --log-error-verbosity=2 " ]
    ports:
      - "3306:3306"
    volumes:
      - dbdata_medidev:/var/lib/mysql/
      # ##########################################################
      # Optional custom config / init files:
      # ##########################################################
      - ./docker/mysql/conf.d:/etc/mysql/conf.d:ro
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-p987400Kmh" ]
      interval: 10s
      timeout: 5s
      retries: 10
    networks: [ web ]
  queue:
    build:
      context: ./docker/php-fpm
      dockerfile: Dockerfile
    container_name: laravel-queue
    command: [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ]
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html:delegated
      - vendor:/var/www/html/vendor
      - storage:/var/www/html/storage
      - cache:/var/www/html/bootstrap/cache
    depends_on:
      - redis
      - mysql
    networks: [ web ]
    restart: unless-stopped
networks:
  web:
    driver: bridge
  shared:
    external: true
    name: shared-frontend
volumes:
  vendor:
  storage:
  cache:
  dbdata_medidev:

You need to create a docker directory from the project root and add the following files to this directory once downloaded.

Download docker.zip

you will also need to contact the author for a copy of the mysql databases;

Once all the files are in place you can execute

 sail up --build
 or 
 docker-compose build --no-cache

Fix invalid cache path after rebuild as were using names paths

You can also use this command

docker exec -it laravel-php bash -lc \
"mkdir -p bootstrap/cache storage/framework/{cache,sessions,views} \
&& chown -R www-data:www-data bootstrap storage \
&& chmod -R ug+rwX bootstrap storage"
`````

NB also run composer install

docker network create shared-frontend


This makes the necessary cache dirs etc

mkdir -p bootstrap/cache storage/framework/{cache,sessions,views,testing,cache/data} && chown -R www-data:www-data bootstrap storage ````