Skip to content

Instantly share code, notes, and snippets.

@jasperf
Last active March 18, 2023 04:01
Show Gist options
  • Save jasperf/5ec271deb356298efb39fe91a5abb0a4 to your computer and use it in GitHub Desktop.
Save jasperf/5ec271deb356298efb39fe91a5abb0a4 to your computer and use it in GitHub Desktop.
Laravel App in Docker with Traefik, Redis, Horizon and MySQL

docker-composer.yml:

version: '3'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: myapp:latest
    container_name: myapp
    restart: unless-stopped
    environment:
      DB_HOST: mysql
      REDIS_HOST: redis
    depends_on:
      - mysql
      - redis
    volumes:
      - ./:/app
    networks:
      - myapp-network

  redis:
    image: redis:alpine
    container_name: myapp-redis
    restart: unless-stopped
    volumes:
      - redis-data:/data
    networks:
      - myapp-network

  mysql:
    image: mysql:5.7
    container_name: myapp-mysql
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: myapp_db
      MYSQL_USER: myapp_user
      MYSQL_PASSWORD: ${MYAPP_DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYAPP_DB_PASSWORD}
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - myapp-network

  horizon:
    build:
      context: .
      dockerfile: Dockerfile-worker
    container_name: myapp-horizon
    restart: unless-stopped
    environment:
      DB_HOST: mysql
      REDIS_HOST: redis
    depends_on:
      - mysql
      - redis
    volumes:
      - ./:/app
    networks:
      - myapp-network

  traefik:
    image: traefik:v2.4
    container_name: myapp-traefik
    restart: unless-stopped
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - myapp-network

networks:
  myapp-network:

volumes:
  redis-data:
  mysql-data:

We can expand Traefik with

traefik:
  image: traefik:v2.4
  container_name: myapp-traefik
  restart: unless-stopped
  command:
    - "--api.insecure=true"
    - "--providers.docker=true"
    - "--providers.docker.exposedbydefault=false"
    - "--entrypoints.web.address=:80"
  ports:
    - "80:80"
    - "8080:8080"
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
  networks:
    - myapp-network

app:
  ...
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.myapp.rule=Host(`example.com`)"
    - "traefik.http.services.myapp.loadbalancer.server.port=80"
    - "traefik.docker.network=myapp-network"
  ...

networks:
  myapp-network:
    external: true

DockerFile for app

# Dockerfile for Laravel app

# Use an official PHP runtime as a parent image
FROM php:8.2-fpm

# Set the working directory to /var/www/html
WORKDIR /var/www/html

# Copy the composer.json and composer.lock files to the container
COPY composer.json composer.lock ./

# Install the necessary packages
RUN apt-get update && \
    apt-get install -y \
        nginx \
        supervisor \
        libpq-dev \
        libzip-dev \
        libicu-dev \
        libpng-dev \
        libjpeg-dev \
        libfreetype6-dev \
        libxml2-dev \
        libonig-dev \
        unzip \
        curl \
        git \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) \
        pdo \
        pdo_mysql \
        mysqli \
        mbstring \
        zip \
        gd \
        intl \
        bcmath \
        soap \
        exif \
    && pecl install \
        redis \
        xdebug \
    && docker-php-ext-enable \
        redis \
        xdebug

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

# Copy the application code to the container
COPY . .

# Set the permissions for the storage and bootstrap/cache directories
RUN chgrp -R www-data storage bootstrap/cache \
    && chmod -R ug+rwx storage bootstrap/cache

# Copy the Nginx configuration file
COPY nginx.conf /etc/nginx/nginx.conf

# Copy the Supervisor configuration file
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Expose port 80
EXPOSE 80

# Start the Supervisor process manager
CMD ["/usr/bin/supervisord"]

In this modified Dockerfile, we have replaced the CMD ["apache2-foreground"] instruction with CMD ["/usr/bin/supervisord"]. This instructs Docker to start the Supervisor process manager inside the container, which will manage the Nginx and PHP-FPM processes.

We have also added nginx and supervisor to the list of packages to be installed, and copied the Nginx configuration file (nginx.conf) and the Supervisor configuration file (supervisord.conf) to the container.

Note that the Nginx configuration file (nginx.conf) will need to be modified to include the appropriate configuration for your Laravel application. You may also need to modify the supervisord.conf file to customize the way that Supervisor manages the Nginx and PHP-FPM processes.

Docker file worker Dockerfile-worker with Horizon

FROM php:8.2-cli

RUN apt-get update && \
    apt-get install -y \
        libzip-dev \
        zip \
        unzip \
        libonig-dev \
        libxml2-dev \
        libicu-dev \
        libpq-dev

RUN docker-php-ext-install pdo pdo_mysql mbstring exif pcntl bcmath zip intl opcache

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

WORKDIR /app

COPY . .

RUN composer install --no-dev --optimize-autoloader --no-interaction

CMD php artisan horizon

Docker .env

MYAPP_DB_PASSWORD=mysecretpassword

and Laravel .env:

DB_PASSWORD=${MYAPP_DB_PASSWORD}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment