Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dd3015e
commit 610f33e
Showing
10 changed files
with
520 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
FROM yourdockername/base-php-nginx:latest | ||
|
||
# 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 Package Manager | ||
## | ||
|
||
# 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 | ||
|
||
## | ||
## We Are Go for Bower | ||
## | ||
|
||
COPY ./bower.json . | ||
RUN bower install --allow-root | ||
|
||
# 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 | ||
COPY ./nginx.conf /etc/nginx/nginx.conf | ||
COPY ./nginx-site.conf /etc/nginx/conf.d/default.conf | ||
|
||
|
||
# copy in app code as late as possible, as it changes the most | ||
WORKDIR /var/www/app | ||
COPY --chown=www-data:www-data . . | ||
RUN composer dump-autoload -o | ||
|
||
# be sure nginx is properly passing to php-fpm and fpm is responding | ||
HEALTHCHECK --interval=5s --timeout=3s \ | ||
CMD curl -f http://localhost/ping || 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
## PHP (Laravel) + Docker Hello World, for Showing Good Defaults for Using A PHP Stack in Docker | ||
|
||
> This tries to be a "good defaults" example of using PHP, Nginx, PHP-FPM, Laravel, and Composer in Docker for local development and shipping to production with all the bells, whistles, and best practices. Issues/PR welcome. | ||
**NOTE:** This is not a full PHP sample project. It's a collection of the Docker and Nginx related things you'll need to have this sort of setup fully in Docker. I'm not a PHP/Laravel developer, but rather an ops guy working with many smart PHP dev's. I continue to refine this repo as I work with teams to dev with, test on, and deploy production containers on PHP. | ||
|
||
### Local Development Features | ||
|
||
- **Dev as close to prod as you can**. docker-compose builds a local development image that is just like production image except for the below dev-only features needed in image. Goal is to have dev env be as close to test and prod as possible while still giving all the nice tools to make you a happy dev. | ||
- **Prevent needing node/npm on host**. Installs `node_modules` outside app root in container so local development won't run into a problem of bind-mounting over it with local source code. This means it will run `npm install` once on container build and you don't need to run npm on host or on each docker run. It will re-run on build if you change `package.json`. | ||
- **One line startup**. Uses `docker-compose up` for single-line build and run of local development server. | ||
- **Edit locally while code runs in container**. docker-compose uses proper bind-mounts of host source code into container so you can edit locally while running code in Linux container. | ||
- **Enable debug from host to container**. opens the legacy debug port 5858 and new inspect port 9229 for using host-based debugging like chrome tools or VS Code. Nodemon enables `--inspect` by default in docker-compose, but you can change to `--debug` for < 6.3 debugging. | ||
- **Quick re-builds**. `COPY` in `package.json` and run `npm install && npm cache clean` **before** `COPY` in your source code. This saves big on build time and keep container lean. Same for Composer and Bower. | ||
|
||
|
||
### Production-minded Features | ||
|
||
- **Use Docker build-in healthchecks**. uses Dockerfile `HEALTHCHECK` with php-fpm `/ping` route to help Docker know if your container is running properly. | ||
|
||
|
||
### Assumptions | ||
|
||
- You have Docker and Docker-Compose installed (Docker for Mac, Docker for Windows, get.docker.com and manual Compose installed for Linux). | ||
- You want to use Docker for local development (i.e. never need to install php or npm on host) and have dev and prod Docker images be as close as possible. | ||
- You don't want to loose fidelity in your dev workflow. You want a easy environment setup, using local editors, debug/inspect, local code repo, while web server runs in a container. | ||
- You use `docker-compose` for local development only (docker-compose was never intended to be a production deployment tool anyway). | ||
- The `docker-compose.yml` is not meant for `docker stack deploy` in Docker Swarm, it's meant for happy local development. | ||
|
||
|
||
### Getting Started | ||
|
||
If this was your app, to start local development you would: | ||
|
||
- Running `docker-compose up` is all you need. It will: | ||
- Build custom local image enabled for development. | ||
- Start container from that image with ports 80, 443, 9000, and 9001 open (on localhost or docker-machine). | ||
- Mounts the pwd to the app dir in container. | ||
- If you need other services like databases, just add to compose file and they'll be added to the custom Docker network for this app on `up`. | ||
- If you need to add packages to Composer, npm, bower, etc. then stop docker-compose and run `docker-compose up --build` to ensure image is updated. | ||
- Be sure to use `docker-compose down` to cleanup after your done dev'ing. | ||
|
||
|
||
|
||
MIT License, | ||
|
||
Copyright (c) Bret Fisher | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
FROM php:7.2-fpm | ||
|
||
|
||
ENV COMPOSER_VERSION=1.5.5 \ | ||
NGINX_VERSION=1.12.2-1~jessie \ | ||
NJS_VERSION=1.12.2.0.1.14-1~jessie \ | ||
NODE_VERSION=6.12.1 | ||
|
||
# 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 | ||
# NOTE: you should prob use specific versions of some of these so you don't break your app | ||
RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -y \ | ||
ca-certificates \ | ||
curl \ | ||
dos2unix \ | ||
git \ | ||
gnupg2 \ | ||
g++ \ | ||
jq \ | ||
libedit-dev \ | ||
libfcgi0ldbl \ | ||
libfreetype6-dev \ | ||
libicu-dev \ | ||
libjpeg62-turbo-dev \ | ||
libmcrypt-dev \ | ||
libpq-dev \ | ||
libssl-dev \ | ||
openssh-client \ | ||
supervisor \ | ||
unzip \ | ||
zip \ | ||
&& rm -r /var/lib/apt/lists/* | ||
|
||
|
||
# Install extensions using the helper script provided by the base image | ||
RUN docker-php-ext-install \ | ||
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) | ||
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 | ||
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 | ||
|
||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
version: '3.3' | ||
|
||
services: | ||
php: | ||
# note you need to manually build this image from base dockerfile above FIRST! | ||
image: yourdockername/base-php-nginx | ||
build: . | ||
volumes: | ||
# used delegated mode here on docker for mac for faster disk I/O | ||
- .:/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 | ||
# mount in dev certs if you want to dev over ssl | ||
#- ./dev-cert.crt:/etc/nginx/ssl/cert.crt | ||
#- ./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: | ||
- "8080:80" | ||
- "8443:443" | ||
- "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: | ||
# we only expose this port in local dev for using mysql tools/guis on your host | ||
- "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: | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/bin/sh | ||
set -e | ||
|
||
# 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 "$@" |
Oops, something went wrong.