diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..d71ede0 --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,7 @@ +# Git +.git/ +.gitignore +config/ + +# OSX +.DS_Store diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 0000000..f733c4b --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +config/ diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..e89d8c7 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,62 @@ +FROM php:fpm-stretch + +# Setup necessary env vars +ENV DEBIAN_FRONTEND=noninteractive +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 + +# Basic Prep +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl supervisor + +# Setup locales +RUN apt-get install -y --no-install-recommends locales +COPY locale/default /etc/default/locale +COPY locale/locale.gen /etc/locale.gen +RUN locale-gen + +# PHP dependencies +RUN apt-get install -y --no-install-recommends \ + zlib1g-dev libicu-dev build-essential libcurl4-openssl-dev \ + && docker-php-ext-install -j$(nproc) intl \ + && docker-php-ext-install -j$(nproc) mbstring \ + && docker-php-ext-install -j$(nproc) curl \ + && docker-php-ext-install gettext \ + && apt-get remove -y --purge zlib1g-dev libicu-dev build-essential libcurl4-openssl-dev \ + && apt-get autoremove -y --purge + +# Halcyon +RUN apt-get install -y --no-install-recommends git \ + && git clone https://notabug.org/halcyon-suite/halcyon.git /var/www/html/ \ + && git checkout `git describe --tags` \ + && cp -r /var/www/html/config /var/www/html/config.example \ + && chown -R www-data: /var/www + +# PHP-fpm + nginx +RUN apt-get install -y --no-install-recommends nginx \ +# Remove (some of the) default nginx config + && rm -f /etc/nginx.conf \ + && rm -f /etc/nginx/conf.d/default.conf \ + && rm -rf /etc/nginx/sites-* \ + && rm -rf /var/log/nginx \ +# Ensure nginx logs, even if the config has errors, are written to stderr + && mkdir -p /var/log/nginx \ + && chown www-data: /var/log/nginx \ + && ln -s /dev/stderr /var/log/nginx/error.log \ +# Create folder where the user hook into our default configs + && mkdir -p /etc/nginx/server.d/ \ + && mkdir -p /etc/nginx/location.d/ \ +# Bring php-fpm configs into a more controallable state + && rm /usr/local/etc/php-fpm.d/www.conf.default \ + && mv /usr/local/etc/php-fpm.d/docker.conf /usr/local/etc/php-fpm.d/00-docker.conf \ + && mv /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/10-www.conf \ + && mv /usr/local/etc/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/20-docker.conf + +# Copy necessary configs +ADD etc/ /etc/ +ADD usr/ /usr/ + +EXPOSE 80 + +ENTRYPOINT ["/usr/bin/supervisord","-c","/etc/supervisord.conf"] + diff --git a/docker/etc/nginx/conf.d/access_log.conf b/docker/etc/nginx/conf.d/access_log.conf new file mode 100644 index 0000000..a54704b --- /dev/null +++ b/docker/etc/nginx/conf.d/access_log.conf @@ -0,0 +1,5 @@ +# Log access to this file +# This is only used when you don't override it on a server{} level +access_log /dev/stdout main; + +# Note: Feel free to overwrite this file if you want a custom logging format! diff --git a/docker/etc/nginx/conf.d/cache-file-descriptors.conf b/docker/etc/nginx/conf.d/cache-file-descriptors.conf new file mode 100644 index 0000000..ed312c0 --- /dev/null +++ b/docker/etc/nginx/conf.d/cache-file-descriptors.conf @@ -0,0 +1,19 @@ +# This tells Nginx to cache open file handles, "not found" errors, metadata about files and their permissions, etc. +# +# The upside of this is that Nginx can immediately begin sending data when a popular file is requested, +# and will also know to immediately send a 404 if a file is missing on disk, and so on. +# +# However, it also means that the server won't react immediately to changes on disk, which may be undesirable. +# +# In the below configuration, inactive files are released from the cache after 20 seconds, whereas +# active (recently requested) files are re-validated every 30 seconds. +# +# Descriptors will not be cached unless they are used at least 2 times within 20 seconds (the inactive time). +# +# A maximum of the 1000 most recently used file descriptors can be cached at any time. +# +# Production servers with stable file collections will definitely want to enable the cache. +open_file_cache max=1000 inactive=20s; +open_file_cache_valid 30s; +open_file_cache_min_uses 2; +open_file_cache_errors on; diff --git a/docker/etc/nginx/conf.d/compression.conf b/docker/etc/nginx/conf.d/compression.conf new file mode 100644 index 0000000..26537ad --- /dev/null +++ b/docker/etc/nginx/conf.d/compression.conf @@ -0,0 +1,56 @@ +# Enable gzip compression. +gzip on; + +# Compression level (1-9). +# 5 is a perfect compromise between size and CPU usage, offering about +# 75% reduction for most ASCII files (almost identical to level 9). +gzip_comp_level 5; + +# Don't compress anything that's already small and unlikely to shrink much +# if at all (the default is 20 bytes, which is bad as that usually leads to +# larger files after gzipping). +gzip_min_length 256; + +# Compress data even for clients that are connecting to us via proxies, +# identified by the "Via" header (required for CloudFront). +gzip_proxied any; + +# Tell proxies to cache both the gzipped and regular version of a resource +# whenever the client's Accept-Encoding capabilities header varies; +# Avoids the issue where a non-gzip capable client (which is extremely rare +# today) would display gibberish if their proxy gave them the gzipped version. +gzip_vary on; + +# Compress all output labeled with one of the following MIME-types. +gzip_types + application/atom+xml + application/javascript + application/json + application/ld+json + application/manifest+json + application/rss+xml + application/vnd.geo+json + application/vnd.ms-fontobject + application/x-font-ttf + application/x-web-app-manifest+json + application/xhtml+xml + application/xml + font/opentype + image/bmp + image/svg+xml + image/x-icon + text/cache-manifest + text/css + text/plain + text/vcard + text/vnd.rim.location.xloc + text/vtt + text/x-component + text/x-cross-domain-policy; + # text/html is always compressed by gzip module + +# This should be turned on if you are going to have pre-compressed copies (.gz) of +# static files available. If not it should be left off as it will cause extra I/O +# for the check. It is best if you enable this in a location{} block for +# a specific directory, or on an individual server{} level. +# gzip_static on; diff --git a/docker/etc/nginx/nginx.conf b/docker/etc/nginx/nginx.conf new file mode 100644 index 0000000..4b72170 --- /dev/null +++ b/docker/etc/nginx/nginx.conf @@ -0,0 +1,75 @@ +# Run as a unique, less privileged user for security reasons. +user www-data www-data; + +# Sets the worker threads to the number of CPU cores available in the system for best performance. +# Should be > the number of CPU cores. +# Maximum number of connections = worker_processes * worker_connections +worker_processes auto; + +# Maximum number of open files per worker process. +# Should be > worker_connections. +worker_rlimit_nofile 8192; + +events { + # If you need more connections than this, you start optimizing your OS. + # That's probably the point at which you hire people who are smarter than you as this is *a lot* of requests. + # Should be < worker_rlimit_nofile. + worker_connections 8000; +} + +# Log errors and warnings to this file +# This is only used when you don't override it on a server{} level +error_log /dev/stderr warn; + +# The file storing the process ID of the main process +pid /var/run/nginx.pid; + +# The process is managed in the docker-env +daemon off; + +# Free some CPU cycles +timer_resolution 500ms; + +http { + # Specify MIME types for files. + include mime.types; + default_type application/octet-stream; + + # Update charset_types to match updated mime.types. + # text/html is always included by charset module. + charset_types text/css text/plain text/vnd.wap.wml application/javascript application/json application/rss+xml application/xml; + + # Include $http_x_forwarded_for within default format used in log files + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + # Hide used software + server_tokens off; + + # Default charset + charset utf-8; + + # How long to allow each connection to stay idle. + # Longer values are better for each individual client, particularly for SSL, + # but means that worker connections are tied up longer. + keepalive_timeout 20s; + + # Speed up file transfers by using sendfile() to copy directly + # between descriptors rather than using read()/write(). + # For performance reasons, on FreeBSD systems w/ ZFS + # this option should be disabled as ZFS's ARC caches + # frequently used files in RAM by default. + sendfile on; + + # Don't send out partial frames; this increases throughput + # since TCP frames are filled up before being sent out. + tcp_nopush on; + + # Allow up to 3 MiB payload, privatebin defaults to 2 MiB. + client_max_body_size 3M; + + # Load even moar configs + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*.conf; +} diff --git a/docker/etc/nginx/sites-available/site.conf b/docker/etc/nginx/sites-available/site.conf new file mode 100644 index 0000000..3716e44 --- /dev/null +++ b/docker/etc/nginx/sites-available/site.conf @@ -0,0 +1,24 @@ +server { + listen 80 default_server; + + root /var/www/html; + index index.php index.html index.htm; + + location / { + include /etc/nginx/location.d/*.conf; + try_files $uri $uri/ /index.php$is_args$args; + } + + location ~ \.php$ { + include /etc/nginx/location.d/*.conf; + fastcgi_pass unix:/run/php-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + + # Prevent exposing nginx + version to $_SERVER + fastcgi_param SERVER_SOFTWARE ""; + } + + include /etc/nginx/server.d/*.conf; +} diff --git a/docker/etc/nginx/sites-enabled/site.conf b/docker/etc/nginx/sites-enabled/site.conf new file mode 120000 index 0000000..35141db --- /dev/null +++ b/docker/etc/nginx/sites-enabled/site.conf @@ -0,0 +1 @@ +/etc/nginx/sites-available/site.conf \ No newline at end of file diff --git a/docker/etc/supervisord.conf b/docker/etc/supervisord.conf new file mode 100644 index 0000000..633eae4 --- /dev/null +++ b/docker/etc/supervisord.conf @@ -0,0 +1,23 @@ +[supervisord] +nodaemon=true +pidfile=/var/run/supervisord.pid + +[program:php-fpm] +command=/usr/local/sbin/php-fpm +autostart=true +autorestart=true +priority=10 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:nginx] +command=/usr/sbin/nginx +autostart=true +autorestart=true +priority=20 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/example b/docker/example new file mode 100644 index 0000000..5abd7c3 --- /dev/null +++ b/docker/example @@ -0,0 +1,12 @@ +docker build -t halcyon/halcyon:latest . +docker run --rm -it -p 9081:80 -v ${PWD}/config:/var/www/html/config test/halcyon:latest +docker run \ + --name halcyon \ + --restart unless-stopped \ + --net docker-private \ + --ip 172.30.12.13 \ + -e TZ=UTC \ + -e DEBUG=1 \ + -v /opt/halcyon/config:/var/www/html/config \ + test/halcyon:latest + diff --git a/docker/locale/default b/docker/locale/default new file mode 100644 index 0000000..a66d814 --- /dev/null +++ b/docker/locale/default @@ -0,0 +1 @@ +en_US.UTF-8 UTF-8 diff --git a/docker/locale/locale.gen b/docker/locale/locale.gen new file mode 100644 index 0000000..03ff5f0 --- /dev/null +++ b/docker/locale/locale.gen @@ -0,0 +1,7 @@ +en_US.UTF-8 UTF-8 +de_DE.UTF-8 UTF-8 +pt_BR.UTF-8 UTF-8 +ja_JP.EUC-JP EUC-JP +ko_KR.UTF-8 UTF-8 +pl_PL.UTF-8 UTF-8 +gl_ES.UTF-8 UTF-8 diff --git a/docker/usr/local/etc/php-fpm.d/50-clear-env.conf b/docker/usr/local/etc/php-fpm.d/50-clear-env.conf new file mode 100644 index 0000000..4f0d61c --- /dev/null +++ b/docker/usr/local/etc/php-fpm.d/50-clear-env.conf @@ -0,0 +1,2 @@ +[www] +clear_env = On diff --git a/docker/usr/local/etc/php-fpm.d/50-no-access-log.conf b/docker/usr/local/etc/php-fpm.d/50-no-access-log.conf new file mode 100644 index 0000000..0aa7e1d --- /dev/null +++ b/docker/usr/local/etc/php-fpm.d/50-no-access-log.conf @@ -0,0 +1,2 @@ +[www] +access.log = /dev/null diff --git a/docker/usr/local/etc/php-fpm.d/50-socket.conf b/docker/usr/local/etc/php-fpm.d/50-socket.conf new file mode 100644 index 0000000..081fb58 --- /dev/null +++ b/docker/usr/local/etc/php-fpm.d/50-socket.conf @@ -0,0 +1,5 @@ +[www] +listen = /run/php-fpm.sock +listen.owner = www-data +listen.group = www-data +listen.mode = 0660 diff --git a/docker/usr/local/etc/php/conf.d/00-best-practices.ini b/docker/usr/local/etc/php/conf.d/00-best-practices.ini new file mode 100644 index 0000000..a872af6 --- /dev/null +++ b/docker/usr/local/etc/php/conf.d/00-best-practices.ini @@ -0,0 +1,8 @@ +; Disable deprecated short open tags ("