commit b326f21a77273ce9b31d23aea1580eb0dc07ad01 Author: bisco Date: Fri Sep 4 23:31:05 2020 +0200 first commit diff --git a/app/Dockerfile b/app/Dockerfile new file mode 100644 index 0000000..1adcf45 --- /dev/null +++ b/app/Dockerfile @@ -0,0 +1,50 @@ +FROM alpine:3.12 +LABEL maintainer = "bisco - " + +RUN addgroup -g 82 www-data &&\ + adduser -u 82 -G www-data -g 'World Wide Web user' \ + -s /sbin/nologin -D www-data + +RUN apk add --update --no-cache \ + bash \ + php7-bcmath \ + php7-bz2 \ + php7-cgi \ + php7-cli \ + php7-common \ + php7-curl \ + php7-fpm \ + php7-gd \ + php7-gmp \ + php7-intl \ + php7-json \ + php7-mbstring \ + php7-mysqli \ + php7-odbc \ + php7-opcache \ + php7-phpdbg \ + php7-pspell \ + php7-recode \ + php7-snmp \ + php7-sqlite3 \ + php7-tidy \ + php7-xml \ + php7-xmlrpc \ + php7-xsl \ + php7-zip \ + php7-pecl-apcu \ + php7-common \ + php7-pecl-igbinary \ + php7-pecl-imagick \ + php7-pecl-memcached \ + php7-pecl-memcache \ + php7-pecl-msgpack + + +ADD docker-entrypoint.sh / + +EXPOSE 9000 + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/app/docker-entrypoint.sh b/app/docker-entrypoint.sh new file mode 100755 index 0000000..7dde19a --- /dev/null +++ b/app/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# This script will be executed every time the container spin up +# +# Author: bisco + +set -e + +echo "Enabling PHP over network" +sed -i 's/listen\ =\ 127.0.0.1:9000/listen\ =\ 0.0.0.0:9000/g' /etc/php7/php-fpm.d/www.conf + +echo "Changing user and group" +sed -i 's/user\ = nobody/user\ = www-data/g' /etc/php7/php-fpm.d/www.conf +sed -i 's/group\ = nobody/group\ = www-data/g' /etc/php7/php-fpm.d/www.conf + +echo "Starting PHP-FPM" +php-fpm7 -F + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..802a7dc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,54 @@ +version: "2" +services: + app: + image: app:latest + build: app + expose: + - "9000" + ports: + - "9000:9000" + volumes: + - /home/bisco/stuff/data/docker/volumes/nginx/htdocs:/var/www/localhost/htdocs + networks: + webnet: + aliases: + - app + db: + image: mariadb:latest + build: mariadb + env_file: mariadb/envs/prod + volumes: + - /home/bisco/stuff/data/docker/volumes/mysql:/var/lib/mysql + expose: + - "3306" + ports: + - "3306:3306" + networks: + webnet: + aliases: + - db + + + www: + image: nginx:latest + build: nginx + expose: + - "80" + - "443" + ports: + - "80:80" + - "443:443" + volumes: + - /home/bisco/stuff/data/docker/volumes/nginx/certs:/etc/nginx/certs + - /home/bisco/stuff/data/docker/volumes/nginx/htdocs:/var/www/localhost/htdocs + networks: + webnet: + aliases: + - www + depends_on: + - app + - db + + +networks: + webnet: \ No newline at end of file diff --git a/mariadb/Dockerfile b/mariadb/Dockerfile new file mode 100644 index 0000000..5f6ddd7 --- /dev/null +++ b/mariadb/Dockerfile @@ -0,0 +1,17 @@ +FROM alpine:3.12 +LABEL maintainer = "bisco - " + +RUN apk add --update --no-cache \ + bash \ + mariadb \ + mariadb-client + +ADD docker-entrypoint.sh / + +EXPOSE 3306 + +VOLUME ["/var/lib/mysql"] + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/mariadb/docker-entrypoint.sh b/mariadb/docker-entrypoint.sh new file mode 100755 index 0000000..bdf096d --- /dev/null +++ b/mariadb/docker-entrypoint.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# This script will be executed every time the container spin up +# It will check if the database is properly set up: +# - main schema is present +# - anonymous login is disabled +# - remote root login is disabled +# - remote login is allowed +# +# TODO: +# - import every SQL file found into a specific volume +# +# Author: bisco + +set -e + +if [ -z $(ls -A /var/lib/mysql) ]; +then + echo "MySQL Datadir not found. Creating a new MySQL database" + mysql_install_db --user=mysql --datadir=/var/lib/mysql + + echo "Starting MySQL for setup process...." + $(which mysqld_safe) --no-defaults --syslog --nowatch --pid-file=/tmp/mysqld.pid + sleep 3 + + echo "Disallow anonymous login...." + $(which mysql) -e "DELETE FROM mysql.global_priv WHERE User='';" + + echo "Disallow remote root login...." + $(which mysql) -e "DELETE FROM mysql.global_priv WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" + + echo "Deleting test database...." + $(which mysql) -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'" + + echo "Creating new database...." + $(which mysql) -e "CREATE DATABASE IF NOT EXISTS \`${MYSQL_DATABASE}\` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';" + $(which mysql) -e "GRANT ALL ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';" + + echo "Flushing all privileges...." + $(which mysql) -e "FLUSH PRIVILEGES;" + + echo "Enabling remote login...." + sed -i 's/^skip-networking/#skip-networking/g' /etc/my.cnf.d/mariadb-server.cnf + sed -i 's/#bind-address/bind-address/g' /etc/my.cnf.d/mariadb-server.cnf + + echo "Stopping MySQL for setup process...." + kill -9 $(cat /tmp/mysqld.pid) + + echo "Starting MySQL with production environment...." + $(which mysqld_safe) --syslog + +else + echo "MySQL Datadir found. Skipping creation..." + + echo "Enabling remote login...." + sed -i 's/^skip-networking/#skip-networking/g' /etc/my.cnf.d/mariadb-server.cnf + sed -i 's/#bind-address/bind-address/g' /etc/my.cnf.d/mariadb-server.cnf + + echo "Starting MySQL with production environment...." + $(which mysqld_safe) --syslog + +fi + + + diff --git a/mariadb/envs/prod b/mariadb/envs/prod new file mode 100644 index 0000000..6644b0a --- /dev/null +++ b/mariadb/envs/prod @@ -0,0 +1,3 @@ +MYSQL_DATABASE=mysql_db_1 +MYSQL_USER=mysql_user_1 +MYSQL_PASSWORD=cicciopasticcio123 \ No newline at end of file diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..80529ba --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,25 @@ +FROM alpine:3.12 +LABEL maintainer = "bisco - " + +RUN addgroup -g 82 www-data &&\ + adduser -u 82 -G www-data -g 'World Wide Web user' \ + -s /sbin/nologin -D www-data + +RUN apk add --update --no-cache \ + bash \ + nginx nginx-mod-http-image-filter \ + nginx-mod-http-headers-more \ + nginx-mod-http-xslt-filter + + +COPY nginx.conf ssl_params gzip_params /etc/nginx/ + +COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf + +VOLUME ["/etc/nginx/"] + +EXPOSE 80 443 + +STOPSIGNAL SIGTERM + +CMD ["nginx", "-g", "daemon off;"] diff --git a/nginx/gzip_params b/nginx/gzip_params new file mode 100644 index 0000000..4fecce4 --- /dev/null +++ b/nginx/gzip_params @@ -0,0 +1,46 @@ +# Compression + +# Enable Gzip compressed. +gzip on; + +# Enable compression both for HTTP/1.0 and HTTP/1.1. +gzip_http_version 1.1; + +# 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/rss+xml + application/vnd.ms-fontobject + application/x-font-ttf + application/x-web-app-manifest+json + application/xhtml+xml + application/xml + font/opentype + image/svg+xml + image/x-icon + text/css + text/plain + text/x-component; + # text/html is always compressed by HttpGzipModule \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..5104eaf --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,31 @@ +user www-data; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +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; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} \ No newline at end of file diff --git a/nginx/nginx.vh.default.conf b/nginx/nginx.vh.default.conf new file mode 100644 index 0000000..3929db7 --- /dev/null +++ b/nginx/nginx.vh.default.conf @@ -0,0 +1,43 @@ +server { + listen 80; + server_name localhost; + + #charset koi8-r; + #access_log /var/log/nginx/host.access.log main; + + location / { + root /var/www/localhost/htdocs/; + index index.html index.htm index.php; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /var/www/localhost/htdocs/; + } + + # proxy the PHP scripts to Apache listening on 127.0.0.1:80 + # + #location ~ \.php$ { + # proxy_pass http://127.0.0.1; + #} + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + # + location ~ .*\.php$ { + fastcgi_pass app:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME /var/www/localhost/htdocs$fastcgi_script_name; + include fastcgi_params; + } + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} +} \ No newline at end of file diff --git a/nginx/ssl_params b/nginx/ssl_params new file mode 100644 index 0000000..b393c78 --- /dev/null +++ b/nginx/ssl_params @@ -0,0 +1,24 @@ +ssl_session_timeout 1d; +ssl_session_cache shared:SSL:50m; +ssl_session_tickets off; + +# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits +## ssl_dhparam /path/to/dhparam.pem; + +# intermediate configuration. tweak to your needs. +ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; +ssl_prefer_server_ciphers on; + +# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) +add_header Strict-Transport-Security max-age=15768000; + +# OCSP Stapling --- +# fetch OCSP records from URL in ssl_certificate and cache them +ssl_stapling on; +ssl_stapling_verify on; + +# verify chain of trust of OCSP response using Root CA and Intermediate certs +## ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; + +## resolver ; \ No newline at end of file