-
-
Save anhdiepmmk/13c21fe9c4769905966b95593c955df7 to your computer and use it in GitHub Desktop.
WIP sample Laravel php_fpm plus nginx plus supervisor Docker setup with npm, composer, bower, and more
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM php:7.0-fpm | |
# this is a sample BASE image, that php_fpm projects can start FROM | |
# it's got a lot in it, but it's designed to meet dev and prod needs in single image | |
# I've tried other things like splitting out php_fpm and nginx containers | |
# or multi-stage builds to keep it lean, but this is my current design for | |
## single image that does nginx and php_fpm | |
## usable with bind-mount and unique dev-only entrypoint file that builds | |
## some things on startup when developing locally | |
## stores all code in image with proper default builds for production | |
# install apt dependencies | |
# some of these are not needed in all php projects | |
RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -y \ | |
ca-certificates \ | |
curl \ | |
dos2unix \ | |
git \ | |
g++ \ | |
jq \ | |
libedit-dev \ | |
libfcgi0ldbl \ | |
libfreetype6-dev \ | |
libicu-dev \ | |
libjpeg62-turbo-dev \ | |
libmcrypt-dev \ | |
libpng12-dev \ | |
libpq-dev \ | |
libssl-dev \ | |
mcrypt \ | |
openssh-client \ | |
supervisor \ | |
unzip \ | |
zip \ | |
&& rm -r /var/lib/apt/lists/* | |
#gnupg1 \ | |
# help docker-php-ext-install find ldap libs | |
RUN ln -s /usr/lib/x86_64-linux-gnu/libldap.so /usr/lib/libldap.so \ | |
&& ln -s /usr/lib/x86_64-linux-gnu/liblber.so /usr/lib/liblber.so | |
# Install extensions using the helper script provided by the base image | |
RUN docker-php-ext-install \ | |
mcrypt \ | |
pdo_mysql \ | |
mysqli \ | |
json \ | |
readline \ | |
gd \ | |
intl | |
# configure gd | |
RUN docker-php-ext-configure gd \ | |
--enable-gd-native-ttf \ | |
--with-freetype-dir=/usr/include/freetype2 \ | |
--with-jpeg-dir=/usr/include/ | |
# configure intl | |
RUN docker-php-ext-configure intl | |
# install nginx (copied from official nginx Dockerfile) | |
ENV NGINX_VERSION 1.12.1-1~jessie | |
ENV NJS_VERSION 1.12.1.0.1.10-1~jessie | |
RUN NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ | |
found=''; \ | |
for server in \ | |
ha.pool.sks-keyservers.net \ | |
hkp://keyserver.ubuntu.com:80 \ | |
hkp://p80.pool.sks-keyservers.net:80 \ | |
pgp.mit.edu \ | |
; do \ | |
echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ | |
apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ | |
done; \ | |
test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ | |
echo "deb http://nginx.org/packages/debian/ jessie nginx" >> /etc/apt/sources.list \ | |
&& apt-get update \ | |
&& apt-get install --no-install-recommends --no-install-suggests -y \ | |
nginx=${NGINX_VERSION} \ | |
nginx-module-xslt=${NGINX_VERSION} \ | |
nginx-module-geoip=${NGINX_VERSION} \ | |
nginx-module-image-filter=${NGINX_VERSION} \ | |
nginx-module-njs=${NJS_VERSION} \ | |
gettext-base \ | |
&& rm -rf /var/lib/apt/lists/* | |
# forward nginx request and error logs to docker log collector | |
RUN ln -sf /dev/stdout /var/log/nginx/access.log \ | |
&& ln -sf /dev/stderr /var/log/nginx/error.log | |
# install composer so we can run dump-autoload at entrypoint startup in dev | |
# copied from official composer Dockerfile | |
ENV PATH="/composer/vendor/bin:$PATH" \ | |
COMPOSER_ALLOW_SUPERUSER=1 \ | |
COMPOSER_VENDOR_DIR=/var/www/vendor \ | |
COMPOSER_HOME=/composer \ | |
COMPOSER_VERSION=1.4.3 | |
RUN curl -s -f -L -o /tmp/installer.php https://raw.githubusercontent.com/composer/getcomposer.org/da290238de6d63faace0343efbdd5aa9354332c5/web/installer \ | |
&& php -r " \ | |
\$signature = '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410'; \ | |
\$hash = hash('SHA384', file_get_contents('/tmp/installer.php')); \ | |
if (!hash_equals(\$signature, \$hash)) { \ | |
unlink('/tmp/installer.php'); \ | |
echo 'Integrity check failed, installer is either corrupt or worse.' . PHP_EOL; \ | |
exit(1); \ | |
}" \ | |
&& php /tmp/installer.php --no-ansi --install-dir=/usr/bin --filename=composer --version=${COMPOSER_VERSION} \ | |
&& rm /tmp/installer.php \ | |
&& composer --ansi --version --no-interaction | |
# install node for running gulp at container entrypoint startup in dev | |
# copied from official node Dockerfile | |
# gpg keys listed at https://github.com/nodejs/node#release-team | |
RUN set -ex \ | |
&& for key in \ | |
9554F04D7259F04124DE6B476D5A82AC7E37093B \ | |
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ | |
FD3A5288F042B6850C66B31F09FE44734EB7990E \ | |
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ | |
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ | |
B9AE9905FFD7803F25714661B63B535A4C206CA9 \ | |
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ | |
56730D5401028683275BD23C23EFEFE93C4CFFFE \ | |
; do \ | |
gpg --keyserver pgp.mit.edu --recv-keys "$key" || \ | |
gpg --keyserver keyserver.pgp.com --recv-keys "$key" || \ | |
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" ; \ | |
done | |
ENV NPM_CONFIG_LOGLEVEL info | |
ENV NODE_VERSION 6.11.2 | |
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ | |
&& curl -SLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ | |
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ | |
&& grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ | |
&& tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ | |
&& rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \ | |
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs | |
ENV PATH /var/www/node_modules/.bin:$PATH | |
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf | |
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: '3.3' | |
services: | |
php: | |
# note you need to manually build this image from base dockerfile above FIRST! | |
image: yourdockername/base-php-nginx | |
build: | |
context: . | |
args: | |
BUILDKEY: | | |
-----BEGIN RSA PRIVATE KEY----- | |
lakdjfladjlkjadflkjadflajdfkja | |
-----END RSA PRIVATE KEY----- | |
volumes: | |
- .:/var/www/app:delegated | |
- ./supervisord.conf:/etc/supervisor/conf.d/supervisord.conf | |
- ./nginx/nginx.conf:/etc/nginx/nginx.conf | |
- ./nginx/nginx-site.conf:/etc/nginx/conf.d/default.conf | |
- ./nginx/dev-cert.crt:/etc/nginx/ssl/cert.crt | |
- ./nginx/dev-key.pem:/etc/nginx/ssl/key.pem | |
entrypoint: /usr/local/bin/docker-php-entrypoint-dev | |
command: ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"] | |
ports: | |
- "${PI_PORT_HTTP:-8080}:80" | |
- "${PI_PORT_HTTPS:-8443}:443" | |
- "${PORT_XDEBUG:-9001}:9001" | |
depends_on: | |
- mysql | |
environment: | |
APP_NAME: Laravel | |
APP_ENV: local | |
APP_DEBUG: true | |
APP_KEY: KEYGOESHERE | |
APP_LOG: errorlog | |
APP_URL: "http://localhost" | |
DB_CONNECTION: mysql | |
DB_HOST: mysql | |
DB_PORT: 3306 | |
DB_DATABASE: homestead | |
DB_USERNAME: homestead | |
DB_PASSWORD: secret | |
mysql: | |
image: mysql:5.7 | |
volumes: | |
- mysql:/var/lib/mysql | |
ports: | |
- "${PORT_MYSQL:-3306}:3306" | |
environment: | |
MYSQL_DATABASE: ${DB_DATABASE:-homestead} | |
MYSQL_USER: ${DB_USERNAME:-homestead} | |
MYSQL_PASSWORD: ${DB_PASSWORD:-secret} | |
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-secret} | |
# using this named volume ensures db's hang around between "up's" | |
volumes: | |
mysql: | |
# secrets: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
# first arg is `-f` or `--some-option` | |
if [ "${1#-}" != "$1" ]; then | |
set -- php-fpm "$@" | |
fi | |
# write the .env config | |
{ \ | |
echo APP_NAME="$APP_NAME"; \ | |
echo APP_ENV="$APP_ENV"; \ | |
echo APP_DEBUG="$APP_DEBUG"; \ | |
echo APP_KEY="$APP_KEY"; \ | |
echo APP_LOG="$APP_LOG"; \ | |
echo APP_URL="$APP_URL"; \ | |
echo DB_CONNECTION="$DB_CONNECTION"; \ | |
echo DB_HOST="$DB_HOST"; \ | |
echo DB_PORT="$DB_PORT"; \ | |
echo DB_DATABASE="$DB_DATABASE"; \ | |
echo DB_USERNAME="$DB_USERNAME"; \ | |
echo DB_PASSWORD="$DB_PASSWORD"; | |
} > /var/www/app/.env | |
# write the php-fpm config | |
{ \ | |
echo listen = /var/run/php-fpm.sock; \ | |
echo listen.owner = www-data; \ | |
echo listen.group = www-data; \ | |
echo ping.path = /ping; \ | |
echo pm.status_path = /status; \ | |
echo pm.max_children = "$FPM_PM_MAX_CHILDREN"; \ | |
echo pm.start_servers = "$FPM_PM_START_SERVERS"; \ | |
echo pm.min_spare_servers = "$FPM_PM_MIN_SPARE_SERVERS"; \ | |
echo pm.max_spare_servers = "$FPM_PM_MAX_SPARE_SERVERS"; \ | |
} > /usr/local/etc/php-fpm.d/zzz-app.conf | |
exec "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
# run last minute build tools just for local dev | |
# this file should just be used to override on local dev in a compose file | |
# first arg is `-f` or `--some-option` | |
if [ "${1#-}" != "$1" ]; then | |
set -- php-fpm "$@" | |
fi | |
# run default entrypoint | |
/usr/local/bin/docker-php-entrypoint | |
# run last minute build tools just for local dev | |
cd /var/www/app | |
composer dump-autoload | |
cd /var/www/app/public | |
exec "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM yourdockername/base-php-nginx:latest AS build | |
# BUILD STAGE | |
# the primary reason we have two build stages is so SSH key of private repo's will never | |
# be in final image | |
# COPY IN BUILD SSH KEY | |
# It won't be copied to final image | |
# add this build arg to compose file | |
ARG BUILDKEY | |
RUN if [ -z "$BUILDKEY" ]; then echo "BUILDKEY SSH NOT SET - ERROR"; exit 1; else : ; fi | |
WORKDIR /root/.ssh | |
RUN echo "$BUILDKEY" > id_rsa && chmod 600 id_rsa | |
# add bitbucket and github to known hosts for ssh needs | |
RUN ssh-keyscan -t rsa bitbucket.org >> /root/.ssh/known_hosts \ | |
&& ssh-keyscan -t rsa github.com >> /root/.ssh/known_hosts | |
## | |
## compose build tools | |
## | |
# install composer dependencies | |
WORKDIR /var/www/app | |
COPY ./composer.json ./composer.lock ./ | |
ENV COMPOSER_VENDOR_DIR=/var/www/vendor | |
# RUN composer config github-oauth.github.com YOUROAUTHKEYHERE | |
RUN composer install --no-scripts --no-autoloader --ansi --no-interaction | |
## | |
## Node Build Tools | |
## | |
# we hardcode to develop so all tools are there for npm build | |
ENV NODE_ENV=develop | |
# install dependencies first, in a different location for easier app bind mounting for local development | |
WORKDIR /var/www | |
COPY ./package.json . | |
RUN npm install | |
# no need to cache clean in non-final build steps | |
ENV PATH /var/www/node_modules/.bin:$PATH | |
ENV NODE_PATH=/var/www/node_modules | |
WORKDIR /var/www/app | |
## | |
## Go for Bower | |
## | |
COPY ./bower.json . | |
RUN bower install --allow-root | |
################ | |
FROM yourdockername/base-php-nginx:latest AS php | |
# FINAL STAGE | |
WORKDIR /var/www | |
COPY --from=build /var/www . | |
# ensure node can reach our modules | |
ENV PATH /var/www/node_modules/.bin:$PATH | |
ENV NODE_PATH=/var/www/node_modules | |
# ensure compose can fine its vendor | |
ENV COMPOSER_VENDOR_DIR=/var/www/vendor | |
# add custom php-fpm pool settings, these get written at entrypoint startup | |
ENV FPM_PM_MAX_CHILDREN=20 \ | |
FPM_PM_START_SERVERS=2 \ | |
FPM_PM_MIN_SPARE_SERVERS=1 \ | |
FPM_PM_MAX_SPARE_SERVERS=3 | |
# Laravel App Config | |
# setup app config environment at runtime | |
# gets put into ./.env at startup | |
ENV APP_NAME=Laravel \ | |
APP_ENV=local \ | |
APP_DEBUG=true \ | |
APP_KEY=KEYGOESHERE \ | |
APP_LOG=errorlog \ | |
APP_URL=http://localhost \ | |
DB_CONNECTION=mysql \ | |
DB_HOST=mysql \ | |
DB_PORT=3306 \ | |
DB_DATABASE=homestead \ | |
DB_USERNAME=homestead \ | |
DB_PASSWORD=secret | |
# Many more ENV may be needed here, and updated in docker-php-entrypoint file | |
# update the entrypoint to write config files and do last minute builds on startup | |
# notice we have a -dev version, which does different things on local docker-compose | |
# but we'll default to entrypoint of running the non -dev one | |
COPY docker-php-* /usr/local/bin/ | |
RUN dos2unix /usr/local/bin/docker-php-entrypoint | |
RUN dos2unix /usr/local/bin/docker-php-entrypoint-dev | |
# copy in nginx config | |
# NOTE, we're copying in default dev self-signed certs | |
# for prod, use Swarm secrets and overwrite these files with proper cert | |
COPY ./nginx.conf /etc/nginx/nginx.conf | |
COPY ./nginx-site.conf /etc/nginx/conf.d/default.conf | |
COPY ./dev-cert.crt /etc/nginx/ssl/cert.crt | |
COPY ./dev-key.pem /etc/nginx/ssl/key.pem | |
# copy in app code as late as possible, as it changes the most | |
WORKDIR /var/www/app | |
COPY . . | |
RUN chown -R www-data:www-data /var/www/app/cache | |
RUN chown -R www-data:www-data /var/www/app/storage | |
RUN composer dump-autoload -o | |
# NOTE: need a valid health URL to make this work | |
# this is one for php_fpm but we can do a nginx curl much easier | |
# HEALTHCHECK --interval=10s --timeout=3s \ | |
# CMD \ | |
# SCRIPT_NAME=/ping \ | |
# SCRIPT_FILENAME=/ping \ | |
# REQUEST_METHOD=GET \ | |
# cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1 | |
WORKDIR /var/www/app/public | |
EXPOSE 80 443 9000 9001 | |
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
server { | |
listen 80; | |
listen 443 ssl; | |
ssl_certificate /etc/nginx/ssl/cert.crt; | |
ssl_certificate_key /etc/nginx/ssl/key.pem; | |
root /var/www/app/public; | |
index index.php index.html index.htm; | |
server_name nginx; | |
#App paths | |
location / { | |
try_files $uri $uri/ /index.php$is_args$args; | |
} | |
location ~ \.php$ { | |
try_files $uri /index.php =404; | |
fastcgi_split_path_info ^(.+\.php)(/.+)$; | |
fastcgi_pass unix:/var/run/php-fpm.sock; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_param PATH_INFO $fastcgi_path_info; | |
include fastcgi_params; | |
# Mitigate https://httpoxy.org/ vulnerabilities | |
fastcgi_param HTTP_PROXY ""; | |
} | |
# nginx status page | |
location /status-nginx { | |
stub_status on; | |
access_log off; | |
} | |
# fpm status page and ping page | |
location ~ ^/(status|ping)$ { | |
access_log off; | |
include fastcgi_params; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_pass unix:/var/run/php-fpm.sock; | |
} | |
location ~ /\.ht { | |
deny all; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user www-data; | |
worker_processes auto; | |
worker_rlimit_nofile 8192; | |
error_log /var/log/nginx/error.log warn; | |
pid /var/run/nginx.pid; | |
events { | |
worker_connections 4096; | |
multi_accept on; | |
} | |
http { | |
include /etc/nginx/mime.types; | |
default_type application/octet-stream; | |
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' | |
'$status $body_bytes_sent "$http_referer" ' | |
'"$http_user_agent" "$http_x_forwarded_for"'; | |
access_log /var/log/nginx/access.log main; | |
sendfile on; | |
tcp_nopush on; | |
tcp_nodelay on; | |
types_hash_max_size 2048; | |
keepalive_timeout 65; | |
gzip on; | |
include /etc/nginx/conf.d/*.conf; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[supervisord] | |
nodaemon=true | |
logfile=/dev/null | |
logfile_maxbytes=0 | |
pidfile=/var/run/supervisord.pid | |
loglevel = INFO | |
[program:php-fpm] | |
command = /usr/local/sbin/php-fpm | |
autostart=true | |
autorestart=true | |
priority=5 | |
stdout_logfile=/dev/stdout | |
stdout_logfile_maxbytes=0 | |
stderr_logfile=/dev/stderr | |
stderr_logfile_maxbytes=0 | |
[program:nginx] | |
command=/usr/sbin/nginx -g "daemon off;" | |
autostart=true | |
autorestart=true | |
priority=10 | |
stdout_events_enabled=true | |
stderr_events_enabled=true | |
stdout_logfile=/dev/stdout | |
stdout_logfile_maxbytes=0 | |
stderr_logfile=/dev/stderr | |
stderr_logfile_maxbytes=0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment