Building a Dockerized Laravel Application with Serversideup Image and Redis Integration
    A Step-by-Step Guide to Setting Up a Scalable Laravel Environment with Docker, Redis, and ServerSideUp Image
    July 11, 2024

    Building a Laravel App Using ServerSideUp Image with Docker

    Docker provides a powerful way to containerize your Laravel application, making it easier to manage dependencies, environments, and deployments. In this guide, we'll walk through setting up a Laravel application using a custom Dockerfile, the ServerSideUp image, and Redis integration via Docker Compose.

    Step 1: Laravel Setup

    Before diving into Docker, make sure you have a basic Laravel project set up. If you haven't already installed Laravel, you can do so with Composer:

    composer create-project --prefer-dist laravel/laravel my-laravel-app
    cd my-laravel-app
    

    This will create a fresh Laravel application in the my-laravel-app directory.

    Step 2: Understanding the Dockerfile

    The Dockerfile is the blueprint for building Docker images. Let's break down the Dockerfile we'll be using:

    ARG BASE="apache"
    ARG PHP_VERSION="8.3"
    
    # Base Stage for Apache and PHP Extensions
    FROM php:${PHP_VERSION}-apache AS apache-php-ext-base
    
    # Adding Redis Extension
    FROM ${BASE}-php-ext-base AS php-ext-redis
    RUN yes no | pecl install redis-6.0.2 && \
        docker-php-ext-enable redis
    
    # Building Frontend Assets
    FROM node:alpine AS node
    COPY ./package.json ./package-lock.json ./vite.config.js ./yarn.lock ./.eslintrc.json  app/
    COPY ./resources/assets app/resources/assets
    WORKDIR app
    RUN npm install && npm run build
    
    # Creating the Production Image
    FROM php:${PHP_VERSION}-apache AS prod
    RUN apt-get -y update --fix-missing && \
        apt-get upgrade -y && \
        apt-get install -y apt-utils zip unzip curl \
        && apt-get install -y libzip-dev \
        && apt-get install cron -y \
        && apt-get install -y libpng-dev \
        && apt-get install -y supervisor \
        && a2enmod rewrite \
        && docker-php-ext-install pdo_mysql bcmath mysqli zip exif
    
    # PHP Extension for Redis
    COPY --from=php-ext-redis /usr/local/etc/php/conf.d/docker-php-ext-redis.ini /usr/local/etc/php/conf.d/docker-php-ext-redis.ini
    COPY --from=php-ext-redis /usr/local/lib/php/extensions/no-debug-non-zts-20230831/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/redis.so
    
    # Copying files and setting up the application
    COPY --chown=www-data:www-data ./ /var/www/html
    COPY --chown=www-data:www-data --from=node /app/public /var/www/html/public
    
    # Cleaning up and installing Composer dependencies
    RUN rm -rf tests/
    RUN composer install --no-dev --optimize-autoloader
    
    # Setting up Apache configuration, Supervisor, and Cron jobs
    COPY default.conf /etc/apache2/sites-enabled/000-default.conf
    RUN mkdir -p /etc/supervisor/conf.d
    COPY supervisord.conf /etc/supervisor/conf.d/
    COPY cron-jobs /etc/cron.d/cron-jobs
    RUN chmod 0644 /etc/cron.d/cron-jobs
    RUN crontab /etc/cron.d/cron-jobs
    
    # Exposing port 80 and enabling Apache modules
    EXPOSE 80
    RUN a2enmod rewrite headers deflate
    
    # Custom start script
    COPY start.sh /usr/local/bin/start
    USER www-data
    CMD [ "/usr/local/bin/start" ]
    
    # CI Stage
    FROM serversideup/php:8.3-cli AS ci
    ENV PHP_MEMORY_LIMIT=2G
    USER root
    RUN install-php-extensions intl gd xsl exif pcov
    

    Dockerfile Explained

    1. Base Stage for Apache and PHP Extensions:

      • We begin by creating a base stage using php:${PHP_VERSION}-apache, where we install PHP and Apache, making it easier to extend this stage later.
    2. Adding Redis Extension:

      • The next stage (php-ext-redis) installs the Redis PHP extension. This stage uses pecl to install Redis and then enables it.
    3. Building Frontend Assets:

      • The node stage handles frontend dependencies and asset compilation. We copy the necessary frontend files, run npm install, and build the assets.
    4. Production Image:

      • This is the main stage where we prepare the production environment. We install necessary PHP extensions like pdo_mysql, bcmath, mysqli, zip, and exif. Redis is also enabled in this stage.
      • After copying the application code and built assets, we clean up the workspace, install Composer dependencies with optimization flags, and configure Apache, Supervisor, and Cron jobs.
    5. Continuous Integration (CI) Stage:

      • The final stage uses the ServerSideUp CLI image, configured with extended memory and additional PHP extensions like intl, gd, xsl, exif, and pcov. This stage is tailored for running tests or CI processes.

    Step 3: Adding Redis and Setting Up docker-compose.yml

    To fully utilize Redis and manage your Laravel application's environment, you'll want to add Redis to the Docker Compose setup and streamline the environment configuration.

    Here’s the updated docker-compose.yml file:

    version: "3.8"
    
    services:
      app:
        build:
          context: .
          dockerfile: Dockerfile
          target: prod
        image: my-laravel-app:latest
        container_name: laravel_app
        ports:
          - "8000:80"
        volumes:
          - .:/var/www/html
        env_file:
          - .env
        depends_on:
          - db
          - redis
    
      db:
        image: mysql:8.0
        container_name: laravel_db
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: secret
          MYSQL_DATABASE: laravel
          MYSQL_USER: laravel
          MYSQL_PASSWORD: secret
        volumes:
          - db_data:/var/lib/mysql
    
      redis:
        image: redis:alpine
        container_name: laravel_redis
        ports:
          - "6379:6379"
    
    volumes:
      db_data:
    

    Adding Redis

    • The redis service is added to the docker-compose.yml file, running the Redis server in a container. This service is lightweight and uses the alpine variant of Redis for efficiency.

    Step 4: Running the Application

    Once your docker-compose.yml is set up, and your Dockerfile is ready, you can bring up your application with the following command:

    docker-compose up -d
    

    This command starts up all the services defined in the docker-compose.yml, including your Laravel app, MySQL, and Redis. The environment variables are loaded from the .env file, making configuration management straightforward.

    Step 5: Testing Redis Integration

    To test if Redis is working correctly with your Laravel application, you can try caching something via the Laravel Artisan CLI:

    docker-compose exec app php artisan tinker
    

    In the Tinker shell:

    Cache::put('foo', 'bar', 600);
    Cache::get('foo'); // should return 'bar'
    

    If Redis is properly integrated, you'll be able to store and retrieve values from the cache successfully.

    Conclusion

    By following this guide, you've set up a Dockerized Laravel application using a custom Dockerfile and the ServerSideUp image, with Redis integration via Docker Compose. This setup not only ensures a consistent environment across development and production but also simplifies managing dependencies and configurations.

    Whether you're developing locally, running tests in CI, or deploying to production, Docker offers a powerful and flexible way to handle your Laravel application's infrastructure. With Redis added, your app is now more powerful, capable of handling session storage, caching, and queues more efficiently.

    Happy coding! 🚀

    Share with the post url and description