Skip to content

Instantly share code, notes, and snippets.

@themightychris
Created September 24, 2019 22:55
Show Gist options
  • Save themightychris/51a63a1c2bf6f3be82c9e85481106fa0 to your computer and use it in GitHub Desktop.
Save themightychris/51a63a1c2bf6f3be82c9e85481106fa0 to your computer and use it in GitHub Desktop.

Revisions

  1. themightychris created this gist Sep 24, 2019.
    130 changes: 130 additions & 0 deletions Dockerfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    #
    # Multi-Stage Docker build:
    # Laravel 5.8 + PHP73 + Postgres || MySQL
    #
    # @link https://laravel.com/docs/5.8
    # @link https://hub.docker.com/_/php
    # @link https://hub.docker.com/_/mysql
    # @link https://hub.docker.com/_/postgres
    #


    #
    # Stage 1 - Prep App's PHP Dependencies
    #
    FROM composer:1.8 as vendor

    COPY database/ database/

    COPY composer.json composer.json
    COPY composer.lock composer.lock

    RUN composer install \
    --ignore-platform-reqs \
    --no-interaction \
    --no-plugins \
    --no-scripts \
    --prefer-dist \
    --quiet

    # end Stage 1 #


    #
    # Stage 2 - Prep App's Frontend CSS & JS
    #
    FROM node:10.15-jessie as frontend

    RUN mkdir -p /app/public

    COPY package.json webpack.mix.js yarn.lock /app/
    COPY resources/assets/ /app/resources/assets/
    COPY resources/js/ /app/resources/js/
    COPY resources/sass/ /app/resources/sass/

    WORKDIR /app

    RUN yarn install --silent \
    && yarn production

    # end Stage 2 #


    #
    # Stage 3 - Build Final App
    #
    FROM php:7.3-fpm-alpine3.8

    # write version information into container
    ARG SOURCE_COMMIT
    LABEL SOURCE_COMMIT="${SOURCE_COMMIT}"
    ENV SOURCE_COMMIT="${SOURCE_COMMIT}"

    ARG SOURCE_TAG
    LABEL SOURCE_TAG="${SOURCE_TAG}"
    ENV SOURCE_TAG="${SOURCE_TAG}"


    # add cli tools
    RUN apk update \
    && apk upgrade \
    && apk add bash \
    && apk add nano \
    && apk add nginx \
    && apk add npm


    # silently install 'docker-php-ext-install' extensions
    RUN set -x

    # Database option: postgres
    RUN apk add --no-cache postgresql-dev
    RUN docker-php-ext-install pdo_pgsql bcmath > /dev/null

    # Database option: mysql
    # RUN docker-php-ext-install pdo_mysql bcmath > /dev/null

    # copy app source folder (less .dockerignore exclusions)
    COPY . /srv/app

    # add app dependencies from multi-stage builds
    COPY --from=vendor /app/vendor/ /srv/app/vendor/
    COPY --from=frontend /app/public/js/ /srv/app/public/js/
    COPY --from=frontend /app/public/css/ /srv/app/public/css/
    COPY --from=frontend /app/public/fonts/ /srv/app/public/fonts/
    COPY --from=frontend /app/public/mix-manifest.json /srv/app/public/mix-manifest.json

    # misc...
    WORKDIR /srv/app

    # nginx - nginx app permissions
    RUN mkdir -p /run/nginx
    RUN chown -R www-data:www-data *

    # nging - nginx permissions for laravel storage & cache
    RUN adduser nginx www-data \
    && chgrp -R www-data storage bootstrap/cache \
    && chmod -R 775 storage bootstrap/cache

    # nginx - config file
    COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf

    # cleanup apk
    RUN rm -rf /var/cache/apk/*

    # cleanup docker
    RUN rm -rf /srv/app/docker

    # bash alias for 'php artisan'
    RUN touch ~/.bashrc \
    && echo 'source ~/.bash_profile' >> ~/.bashrc \
    && echo 'alias art="php artisan"' >> ~/.bash_profile \
    && echo 'alias watch="npm run watch &"' >> ~/.bash_profile

    ENV LOG_CHANNEL=stderr

    # docker entrypoint
    COPY ./docker/php73/entrypoint.sh /entrypoint.sh
    CMD ["/entrypoint.sh"]

    # end Stage 3 #
    56 changes: 56 additions & 0 deletions entrypoint.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    #!/usr/bin/env bash

    # inspired by https://github.com/formapro/docker-nginx-php-fpm/blob/master/base/entrypoint.sh


    ## start nginx and php in the background, kill both on exit
    TRAPPED_SIGNAL=false

    echo 'Starting NGINX';
    nginx -g 'daemon off;' 2>&1 &
    NGINX_PID=$!

    echo 'Starting PHP-FPM';
    php-fpm 2>&1 &
    PHP_FPM_PID=$!

    trap "TRAPPED_SIGNAL=true; kill -15 $NGINX_PID; kill -15 $PHP_FPM_PID;" SIGTERM SIGINT


    ## initialize config cache
    php artisan config:cache


    ## watch nginx and php in an ongoing loop
    while :
    do
    kill -0 $NGINX_PID 2> /dev/null
    NGINX_STATUS=$?

    kill -0 $PHP_FPM_PID 2> /dev/null
    PHP_FPM_STATUS=$?

    if [ "$TRAPPED_SIGNAL" = "false" ]; then
    if [ $NGINX_STATUS -ne 0 ] || [ $PHP_FPM_STATUS -ne 0 ]; then
    if [ $NGINX_STATUS -eq 0 ]; then
    kill -15 $NGINX_PID;
    wait $NGINX_PID;
    fi
    if [ $PHP_FPM_STATUS -eq 0 ]; then
    kill -15 $PHP_FPM_PID;
    wait $PHP_FPM_PID;
    fi

    exit 1;
    fi
    else
    if [ $NGINX_STATUS -ne 0 ] && [ $PHP_FPM_STATUS -ne 0 ]; then
    exit 0;
    fi
    fi

    # trigger laravel scheduler every 60s
    php artisan schedule:run --verbose --no-interaction &

    sleep 60
    done