Skip to content

Commit

Permalink
Merge branch 'docker-support'
Browse files Browse the repository at this point in the history
  • Loading branch information
NFarrington committed Mar 5, 2019
2 parents 1d86f90 + 77bbb3a commit 301f05f
Show file tree
Hide file tree
Showing 27 changed files with 613 additions and 20 deletions.
20 changes: 20 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.*
_*
*.yml
*.sh
*.md
*.xml
Dockerfile
LICENSE

node_modules
vendor

hooks
tests

storage/framework/cache/**
!storage/framework/cache/data/
storage/framework/cache/data/**
storage/framework/sessions/**
storage/framework/views/**
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ Homestead.yaml
npm-debug.log
yarn-error.log
.env
.env.docker
119 changes: 119 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
FROM node:10-alpine AS resources

WORKDIR /home/node/app
RUN chown node:node /home/node/app

USER node

COPY package*.json /home/node/app/

RUN npm install

COPY --chown=node:node public /home/node/app/public
COPY resources/js /home/node/app/resources/js
COPY resources/sass /home/node/app/resources/sass
COPY webpack.mix.js /home/node/app/

RUN npm run production

########################################

FROM nginxinc/nginx-unprivileged:1.14-alpine AS nginx

USER root

RUN apk add --update --no-cache \
su-exec \
curl

COPY ./docker/nginx.conf /etc/nginx/nginx.conf
COPY ./docker/server.conf /etc/nginx/conf.d/default.conf
COPY ./docker/server-ssl.conf /etc/nginx/conf.d/default-ssl.conf.disabled

COPY --from=resources /home/node/app/public /var/www/html/public

HEALTHCHECK --start-period=15s --interval=30s --timeout=5s \
CMD curl -f http://localhost:8081/health || exit 1

EXPOSE 8080 8081 8443

COPY ./docker/nginx-entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

########################################

FROM php:7.3-fpm-alpine AS php-fpm

RUN apk add --update --no-cache --virtual build-dependencies \
autoconf gcc g++ libtool make \
&& apk add --update --no-cache \
libmcrypt-dev \
mysql-client \
libpng-dev \
unzip \
fcgi \
&& pecl install mcrypt-1.0.2 \
&& docker-php-ext-enable mcrypt \
&& docker-php-ext-install pdo_mysql \
&& docker-php-ext-install gd \
&& apk del build-dependencies

WORKDIR /var/www/html

USER www-data

ARG COMPOSER_VERSION=1.8.4
RUN EXPECTED_SIGNATURE="$(curl -s https://composer.github.io/installer.sig)"; \
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"; \
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"; \
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then \
>&2 echo 'ERROR: Invalid installer signature'; \
rm composer-setup.php; \
exit 1; \
fi; \
php composer-setup.php --quiet --version $COMPOSER_VERSION; \
RESULT=$?; \
rm composer-setup.php; \
exit $RESULT

COPY composer.* /var/www/html/

RUN php composer.phar docker-install

COPY . /var/www/html
COPY --from=resources /home/node/app/public /var/www/html/public

USER root
RUN chown -R www-data:www-data \
/var/www/html/storage \
/var/www/html/bootstrap/cache
USER www-data

RUN php composer.phar docker-build

USER root
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
&& echo 'log_errors_max_len = 0' >> $PHP_INI_DIR/conf.d/app.ini \
&& echo 'cgi.fix_pathinfo = 0' >> $PHP_INI_DIR/conf.d/app.ini \
&& echo 'date.timezone = UTC' >> $PHP_INI_DIR/conf.d/app.ini \
&& echo 'expose_php = 0' >> $PHP_INI_DIR/conf.d/app.ini
COPY ./docker/app-fpm.conf /usr/local/etc/php-fpm.d/app-fpm.conf
USER www-data

ARG APP_COMMIT
ENV APP_COMMIT $APP_COMMIT

ARG APP_VERSION
ENV APP_VERSION $APP_VERSION

HEALTHCHECK --start-period=15s --interval=30s --timeout=5s \
CMD \
SCRIPT_NAME=/ping \
SCRIPT_FILENAME=/ping \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000 | tee /dev/stderr | grep pong || exit 1

COPY ./docker/php-fpm-entrypoint.sh /var/www/html/entrypoint.sh
ENTRYPOINT ["/var/www/html/entrypoint.sh"]
CMD ["php-fpm"]
80 changes: 80 additions & 0 deletions app/Console/Commands/QueueHealth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Contracts\Queue\Queue;

class QueueHealth extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'queue:health';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Get the health of the queue.';

/**
* The cache service.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;

/**
* The queue service.
*
* @var \Illuminate\Contracts\Queue\Queue
*/
protected $queue;

/**
* Create a new command instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @param \Illuminate\Contracts\Queue\Queue $queue
* @return void
*/
public function __construct(Cache $cache, Queue $queue)
{
parent::__construct();

$this->cache = $cache;
$this->queue = $queue;
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$queueSize = $this->queue->size();
if ($queueSize == 0) {
$this->line('The queue is empty.');

return 0;
}

/** @var \Illuminate\Support\Carbon $lastProcessed */
$lastProcessed = $this->cache->get('queue.job.last-processed');
if (!$lastProcessed || $lastProcessed->diffInSeconds() > 30) {
$this->line("The queue has $queueSize items, and appears to be stale.");

return 1;
}

echo "The queue has $queueSize items, and is processing.";

return 0;
}
}
39 changes: 39 additions & 0 deletions app/Listeners/RecordJobProcessingListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace App\Listeners;

use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Support\Carbon;

class RecordJobProcessingListener
{
/**
* The cache service.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;

/**
* Create the event listener.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}

/**
* Handle the event.
*
* @param \Illuminate\Queue\Events\JobProcessing $event
* @return void
*/
public function handle(JobProcessing $event)
{
$this->cache->forever('queue.job.last-processed', Carbon::now());
}
}
23 changes: 23 additions & 0 deletions app/Logging/JsonLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Logging;

class JsonLogger
{
/**
* Customize the given logger instance.
*
* @param \Illuminate\Log\Logger $logger
* @return void
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->pushProcessor(function ($record) {
$record['log_type'] = 'laravel_app';

return $record;
});
}
}
}
6 changes: 6 additions & 0 deletions app/Providers/EventServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use App\Events\PrefixApplicationCreatedEvent;
use App\Listeners\DeleteEmailVerificationListener;
use App\Listeners\NotifyApplicationSubmittedListener;
use App\Listeners\RecordJobProcessingListener;
use App\Listeners\VerifyEmailListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Queue\Events\JobProcessing;

class EventServiceProvider extends ServiceProvider
{
Expand All @@ -26,6 +28,10 @@ class EventServiceProvider extends ServiceProvider
DeleteEmailVerificationListener::class,
],

JobProcessing::class => [
RecordJobProcessingListener::class,
],

PrefixApplicationCreatedEvent::class => [
NotifyApplicationSubmittedListener::class,
],
Expand Down
4 changes: 3 additions & 1 deletion app/Providers/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ class RouteServiceProvider extends ServiceProvider
*/
public function boot()
{
//
if ($forceScheme = config('app.force_scheme')) {
$this->app['url']->forceScheme($forceScheme);
}

parent::boot();
}
Expand Down
17 changes: 17 additions & 0 deletions app/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ function breadcrumbs_array()
return $segments;
}

/**
* Retrieves a Docker secret.
*
* @param string $name
* @return string|null
*/
function docker_secret($name)
{
$file = "/run/secrets/$name";

if (empty($name) || !file_exists($file)) {
return null;
}

return trim(file_get_contents($file));
}

/**
* Replace hyphens with non-breaking hyphens.
*
Expand Down
16 changes: 15 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"type": "project",
"require": {
"php": "^7.1.3",
"ext-gd": "*",
"bacon/bacon-qr-code": "^1.0",
"bugsnag/bugsnag-laravel": "^2.0",
"doctrine/dbal": "^2.7",
Expand Down Expand Up @@ -87,16 +88,29 @@
"@php artisan migrate --step --force --no-interaction",
"npm run production",
"@log-rotate",
"@php artisan queue:restart",
"@php artisan up"
],
"docker-install": [
"@composer install --no-dev --optimize-autoloader --classmap-authoritative --no-suggest --no-autoloader --no-scripts"
],
"docker-build": [
"@install-prod"
],
"docker-entrypoint": [
"@php artisan config:cache",
"@php artisan route:cache",
"@php artisan cache:clear",
"@php artisan migrate --step --force --no-interaction"
],
"deploy-prod-basic": [
"@update-version",
"@php artisan config:cache",
"@php artisan route:cache",
"@php artisan cache:clear",
"@log-rotate"
],
"install-prod": "composer install --no-dev --optimize-autoloader --classmap-authoritative",
"install-prod": "@composer install --no-dev --optimize-autoloader --classmap-authoritative --no-suggest",
"deploy-dev": [
"npm install",
"@update-version",
Expand Down
Loading

0 comments on commit 301f05f

Please sign in to comment.