From 29d9ea41932553de85692b7fad2dd7f5d2ac55a7 Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Mon, 22 Jul 2019 00:38:49 +0200 Subject: [PATCH] inital commit --- .dockerignore | 8 + .drone.jsonnet | 135 ++++++++ .drone.yml | 123 +++++++ Dockerfile.linux.amd64 | 37 +++ LICENSE | 21 ++ README.md | 157 +++++++++ docker-compose.yml | 18 ++ manifest.tmpl | 12 + overlay/etc/crontabs/nginx | 1 + overlay/etc/nginx/nginx.conf | 76 +++++ overlay/etc/php7/php-fpm.conf | 21 ++ overlay/etc/php7/php.ini | 391 +++++++++++++++++++++++ overlay/etc/services.d/.s6-svscan/crash | 4 + overlay/etc/services.d/.s6-svscan/finish | 2 + overlay/etc/services.d/cron/run | 2 + overlay/etc/services.d/nginx/run | 2 + overlay/etc/services.d/php/run | 2 + overlay/etc/templates/config.php.tmpl | 245 ++++++++++++++ overlay/etc/templates/php.ini.tmpl | 391 +++++++++++++++++++++++ overlay/usr/local/bin/entrypoint.sh | 8 + overlay/usr/local/bin/healthcheck.sh | 17 + 21 files changed, 1673 insertions(+) create mode 100644 .dockerignore create mode 100644 .drone.jsonnet create mode 100644 .drone.yml create mode 100644 Dockerfile.linux.amd64 create mode 100644 LICENSE create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 manifest.tmpl create mode 100644 overlay/etc/crontabs/nginx create mode 100644 overlay/etc/nginx/nginx.conf create mode 100644 overlay/etc/php7/php-fpm.conf create mode 100644 overlay/etc/php7/php.ini create mode 100755 overlay/etc/services.d/.s6-svscan/crash create mode 100755 overlay/etc/services.d/.s6-svscan/finish create mode 100755 overlay/etc/services.d/cron/run create mode 100755 overlay/etc/services.d/nginx/run create mode 100755 overlay/etc/services.d/php/run create mode 100644 overlay/etc/templates/config.php.tmpl create mode 100644 overlay/etc/templates/php.ini.tmpl create mode 100755 overlay/usr/local/bin/entrypoint.sh create mode 100755 overlay/usr/local/bin/healthcheck.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e46e3b4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +.git* +.drone.* +*.md +.dockerignore +Dockerfile +Dockerfile.* +docker-compose.yml diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 0000000..01f3e96 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,135 @@ +local PipelineBuild(os='linux', arch='amd64') = { + local tag = os + '-' + arch, + local version_tag = os + '-' + arch, + local file_suffix = std.strReplace(version_tag, '-', '.'), + kind: "pipeline", + name: version_tag, + platform: { + os: os, + arch: arch, + }, + steps: [ + { + name: 'dryrun', + image: 'plugins/docker:' + tag, + pull: 'always', + settings: { + dry_run: true, + tags: version_tag, + dockerfile: './Dockerfile.' + file_suffix, + repo: ' xoxys/kanboard', + username: { from_secret: "docker_username" }, + password: { from_secret: "docker_password" }, + build_args: { + KANBOARD_ORG_VERSION: "${DRONE_TAG##v}", + KANBOARD_VERSION: "${KANBOARD_ORG_VERSION%.*}", + }, + }, + }, + { + name: 'publish', + image: 'plugins/docker:' + tag, + pull: 'always', + settings: { + auto_tag: true, + auto_tag_suffix: version_tag, + dockerfile: './Dockerfile.' + file_suffix, + repo: ' xoxys/kanboard', + username: { from_secret: "docker_username" }, + password: { from_secret: "docker_password" }, + build_args: { + KANBOARD_ORG_VERSION: "${DRONE_TAG##v}", + KANBOARD_VERSION: "${KANBOARD_ORG_VERSION%.*}", + }, + }, + when: { + ref: [ + 'refs/heads/master', + 'refs/tags/**', + ], + }, + }, + ], +}; + +local PipelineNotifications(depends_on=[]) = { + kind: "pipeline", + name: "notifications", + platform: { + os: "linux", + arch: "amd64", + }, + steps: [ + { + image: "plugins/manifest", + name: "manifest", + pull: "always", + settings: { + auto_tag: true, + ignore_missing: true, + username: { from_secret: "docker_username" }, + password: { from_secret: "docker_password" }, + spec: "./manifest.tmpl", + }, + when: { + ref: [ + 'refs/heads/master', + 'refs/tags/**', + ], + }, + }, + { + name: "readme", + image: "sheogorath/readme-to-dockerhub", + pull: "always", + environment: { + DOCKERHUB_USERNAME: { from_secret: "docker_username" }, + DOCKERHUB_PASSWORD: { from_secret: "docker_password" }, + DOCKERHUB_REPO_PREFIX: "xoxys", + DOCKERHUB_REPO_NAME: "kanboard", + README_PATH: "README.md", + SHORT_DESCRIPTION: "Tiny Tiny RSS - free and open source news feed reader and aggregator" + }, + when: { + ref: [ + 'refs/heads/master', + 'refs/tags/**', + ], + }, + }, + { + name: "microbadger", + image: "plugins/webhook", + pull: "always", + settings: { + urls: { from_secret: "microbadger_url" }, + }, + }, + { + image: "plugins/matrix", + name: "matrix", + pull: 'always', + settings: { + homeserver: "https://matrix.rknet.org", + roomid: "MtidqQXWWAtQcByBhH:rknet.org", + template: "Status: **{{ build.status }}**
Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}
Message: {{ build.message }}", + username: { from_secret: "matrix_username" }, + password: { from_secret: "matrix_password" }, + }, + when: { + status: [ "success", "failure" ], + }, + }, + ], + trigger: { + status: [ "success", "failure" ], + }, + depends_on: depends_on, +}; + +[ + PipelineBuild(os='linux', arch='amd64'), + PipelineNotifications(depends_on=[ + "linux-amd64", + ]) +] diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..081c107 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,123 @@ +--- +kind: pipeline +name: linux-amd64 + +platform: + os: linux + arch: amd64 + +steps: +- name: dryrun + pull: always + image: plugins/docker:linux-amd64 + settings: + build_args: + KANBOARD_ORG_VERSION: "${DRONE_TAG##v}" + KANBOARD_VERSION: "${KANBOARD_ORG_VERSION%.*}" + dockerfile: ./Dockerfile.linux.amd64 + dry_run: true + password: + from_secret: docker_password + repo: xoxys/kanboard + tags: linux-amd64 + username: + from_secret: docker_username + +- name: publish + pull: always + image: plugins/docker:linux-amd64 + settings: + auto_tag: true + auto_tag_suffix: linux-amd64 + build_args: + KANBOARD_ORG_VERSION: "${DRONE_TAG##v}" + KANBOARD_VERSION: "${KANBOARD_ORG_VERSION%.*}" + dockerfile: ./Dockerfile.linux.amd64 + password: + from_secret: docker_password + repo: xoxys/kanboard + username: + from_secret: docker_username + when: + ref: + - refs/heads/master + - "refs/tags/**" + +--- +kind: pipeline +name: notifications + +platform: + os: linux + arch: amd64 + +steps: +- name: manifest + pull: always + image: plugins/manifest + settings: + auto_tag: true + ignore_missing: true + password: + from_secret: docker_password + spec: ./manifest.tmpl + username: + from_secret: docker_username + when: + ref: + - refs/heads/master + - "refs/tags/**" + +- name: readme + pull: always + image: sheogorath/readme-to-dockerhub + environment: + DOCKERHUB_PASSWORD: + from_secret: docker_password + DOCKERHUB_REPO_NAME: kanboard + DOCKERHUB_REPO_PREFIX: xoxys + DOCKERHUB_USERNAME: + from_secret: docker_username + README_PATH: README.md + SHORT_DESCRIPTION: Tiny Tiny RSS - free and open source news feed reader and aggregator + when: + ref: + - refs/heads/master + - "refs/tags/**" + +- name: microbadger + pull: always + image: plugins/webhook + settings: + urls: + from_secret: microbadger_url + +- name: matrix + pull: always + image: plugins/matrix + settings: + homeserver: https://matrix.rknet.org + password: + from_secret: matrix_password + roomid: MtidqQXWWAtQcByBhH:rknet.org + template: "Status: **{{ build.status }}**
Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}
Message: {{ build.message }}" + username: + from_secret: matrix_username + when: + status: + - success + - failure + +trigger: + status: + - success + - failure + +depends_on: +- linux-amd64 + +--- +kind: signature +hmac: 8e1ef31eafeeeac65a4a5cf9689dd6e66a97f8724a371e7e4b1319fbedc9276f + +... diff --git a/Dockerfile.linux.amd64 b/Dockerfile.linux.amd64 new file mode 100644 index 0000000..9ae58f6 --- /dev/null +++ b/Dockerfile.linux.amd64 @@ -0,0 +1,37 @@ +FROM alpine:3.10.0 + +LABEL maintainer="Robert Kaussow " \ + org.label-schema.name="TT-RSS" \ + org.label-schema.version="1.2" \ + org.label-schema.vendor="Robert Kaussow" \ + org.label-schema.schema-version="1.0" + +ARG KANBOARD_VERSION=master +ARG KANBOARD_TARBALL=https://github.com/kanboard/kanboard/archive/${KANBOARD_VERSION}.tar.gz + +RUN apk --update add --virtual .build-deps tar curl && \ + apk --update add nginx ca-certificates s6 ssmtp mailx php7 php7-phar php7-curl \ + php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \ + php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \ + php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml && \ + rm -rf /var/www/localhost && \ + rm -f /etc/php7/php-fpm.d/www.conf && \ + mkdir -p /var/www/app && \ + curl -SsL -o /usr/local/bin/gomplate https://github.com/hairyhenderson/gomplate/releases/download/v3.5.0/gomplate_linux-amd64-slim && \ + chmod 755 /usr/local/bin/gomplate && \ + curl -SsL ${KANBOARD_TARBALL} | tar xz -C /var/www/app/ --strip-components=1 && \ + curl -SsL -o /etc/php7/browscap.ini https://browscap.org/stream?q=Lite_PHP_BrowsCapINI && \ + apk del .build-deps && \ + rm -rf /var/cache/apk/* && \ + rm -rf /tmp/* + +ADD overlay/ / + +VOLUME /var/www/app/plugins + +EXPOSE 80 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD /usr/local/bin/healthcheck.sh +WORKDIR /var/www/app +CMD [] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c6674cc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Robert Kaussow + +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 (including the next +paragraph) 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b07ad27 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# [kanboard](https://gitea.rknet.org/docker/kanboard) + +[![Build Status](https://drone.rknet.org/api/badges/docker/kanboard/status.svg)](https://drone.rknet.org/docker/kanboard/) +[![Microbadger](https://images.microbadger.com/badges/image/xoxys/kanboard.svg)](https://microbadger.com/images/xoxys/kanboard "Get your own image badge on microbadger.com") + +Kanboard is project management software that focuses on the Kanban methodology. + +## Usage + +Here are some example snippets to help you get started creating a container. + +> **WARNING**: For production usage you should secure your database and NOT use the default credentials! + +### Docker + +```Shell +docker create \ + --name=kanboard \ + -p 80:80 \ + xoxys/kanboard +``` + +### Docker Compose + +Compatible with docker-compose v2 schemas. + +```Yaml +--- +version: '2.1' + +services: + kanboard: + image: kanboard/kanboard:latest + ports: + - "80:80" + volumes: + - kanboard_data:/var/www/app/data + - kanboard_plugins:/var/www/app/plugins + +volumes: + kanboard_data: + driver: local + kanboard_plugins: + driver: local +``` + +## Environment variables + +### TT-RSS + +```Shell +KANBOARD_PLUGIN_INSTALLER=false +KANBOARD_CACHE_DRIVER=memory +KANBOARD_MAIL_CONFIGURATION=true +KANBOARD_MAIL_FROM= +KANBOARD_MAIL_TRANSPORT=mail +KANBOARD_MAIL_SMTP_HOSTNAME +KANBOARD_MAIL_SMTP_PORT=25 +KANBOARD_MAIL_SMTP_USERNAME= +KANBOARD_MAIL_SMTP_PASSWORD= +KANBOARD_MAIL_SMTP_ENCRYPTION=null +KANBOARD_MAIL_SENDMAIL_COMMAND=/usr/sbin/sendmail -bs +KANBOARD_DB_RUN_MIGRATIONS=true +KANBOARD_DB_DRIVER=sqlite +KANBOARD_DB_USERNAME=root +KANBOARD_DB_PASSWORD=root +KANBOARD_DB_HOSTNAME=localhost +KANBOARD_DB_NAME=kanboard +KANBOARD_DB_PORT=null +KANBOARD_DB_SSL_KEY=null +KANBOARD_DB_SSL_CERT=null +KANBOARD_DB_SSL_CA=null +KANBOARD_DB_VERIFY_SERVER_CERT=null +KANBOARD_DB_TIMEOUT=null +KANBOARD_LDAP_AUTH=false +KANBOARD_LDAP_SERVER +KANBOARD_LDAP_PORT=389 +KANBOARD_LDAP_SSL_VERIFY=true +KANBOARD_LDAP_START_TLS=false +KANBOARD_LDAP_USERNAME_CASE_SENSITIVE=false +KANBOARD_LDAP_BIND_TYPE=anonymous +KANBOARD_LDAP_USERNAME=null +KANBOARD_LDAP_PASSWORD=null +KANBOARD_LDAP_USER_BASE_DN= +KANBOARD_LDAP_USER_FILTER= +KANBOARD_LDAP_USER_ATTRIBUTE_USERNAME=uid +KANBOARD_LDAP_USER_ATTRIBUTE_FULLNAME=cn +KANBOARD_LDAP_USER_ATTRIBUTE_EMAIL=mail +KANBOARD_LDAP_USER_ATTRIBUTE_GROUPS=memberof +KANBOARD_LDAP_USER_ATTRIBUTE_PHOTO= +KANBOARD_LDAP_USER_ATTRIBUTE_LANGUAGE= +KANBOARD_LDAP_USER_CREATION=true +KANBOARD_LDAP_GROUP_ADMIN_DN= +KANBOARD_LDAP_GROUP_MANAGER_DN= +KANBOARD_LDAP_GROUP_PROVIDER=false +KANBOARD_LDAP_GROUP_BASE_DN= +KANBOARD_LDAP_GROUP_FILTER= +KANBOARD_LDAP_GROUP_USER_FILTER= +KANBOARD_LDAP_GROUP_ATTRIBUTE_NAME=cn +KANBOARD_REVERSE_PROXY_AUTH=false +KANBOARD_REVERSE_PROXY_USER_HEADER=REMOTE_USER +KANBOARD_REVERSE_PROXY_DEFAULT_ADMIN= +KANBOARD_REVERSE_PROXY_DEFAULT_DOMAIN= +KANBOARD_REMEMBER_ME_AUTH=true +KANBOARD_MARKDOWN_ESCAPE_HTML=true +KANBOARD_API_AUTHENTICATION_HEADER= +KANBOARD_ENABLE_URL_REWRITE=false +KANBOARD_HIDE_LOGIN_FORM=false +KANBOARD_DISABLE_LOGOUT=false +KANBOARD_BRUTEFORCE_CAPTCHA=3 +KANBOARD_BRUTEFORCE_LOCKDOWN=6 +KANBOARD_BRUTEFORCE_LOCKDOWN_DURATION=15 +KANBOARD_SESSION_DURATION=0 +KANBOARD_HTTP_PROXY_HOSTNAME= +KANBOARD_HTTP_PROXY_PORT=3128 +KANBOARD_HTTP_PROXY_USERNAME= +KANBOARD_HTTP_PROXY_PASSWORD= +KANBOARD_HTTP_PROXY_EXCLUDE=localhost +KANBOARD_HTTP_VERIFY_SSL_CERTIFICATE=true +KANBOARD_TOTP_ISSUER=Kanboard +KANBOARD_EXTERNAL_AUTH_EXCLUDE_FIELDS=username +``` + +### PHP + +```Shell +PHP_EXPOSE_PHP=Off +PHP_MAX_EXECUTION_TIME=30 +PHP_MAX_INPUT_TIME=60 +PHP_MEMORY_LIMIT=50M +PHP_ERROR_REPORTING=E_ALL & ~E_DEPRECATED & ~E_STRICT +PHP_DISPLAY_ERRORS=Off +PHP_DISPLAY_STARTUP_ERRORS=Off +PHP_LOG_ERRORS=On +PHP_LOG_ERRORS_MAX_LEN=1024 +PHP_IGNORE_REPEATED_ERRORS=Off +PHP_IGNORE_REPEATED_SOURCE=Off +PHP_REPORT_MEMLEAKS=On +PHP_HTML_ERRORSOn +PHP_ERROR_LOG=/proc/self/fd/2 +PHP_POST_MAX_SIZE=8M +PHP_FILE_UPLOADS=Off +PHP_UPLOAD_MAX_FILESIZE=2M +PHP_MAX_FILE_UPLOADS=2 +PHP_ALLOW_URL_FOPEN=On +PHP_ALLOW_URL_INCLUDE=Off +PHP_DATE_TIMEZONE=Europe/Berlin +PHP_SQL_SAFE_MODE=On +``` + +### License + +This project is licensed under the MIT License - see the [LICENSE](https://gitea.rknet.org/docker/kanboard/src/branch/master/LICENSE) file for details. + +### Maintainers and Contributors + +[Robert Kaussow](https://gitea.rknet.org/xoxys) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0154cdd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: '2.1' + +services: + kanboard: + image: xoxys/kanboard:latest + ports: + - "80:80" + volumes: + - kanboard_data:/var/www/app/data + - kanboard_plugins:/var/www/app/plugins + environment: + KANBOARD_PLUGIN_INSTALLER: "true" + +volumes: + kanboard_data: + driver: local + kanboard_plugins: + driver: local diff --git a/manifest.tmpl b/manifest.tmpl new file mode 100644 index 0000000..8a71b34 --- /dev/null +++ b/manifest.tmpl @@ -0,0 +1,12 @@ +image: xoxys/kanboard:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - image: xoxys/kanboard:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64 + platform: + architecture: amd64 + os: linux diff --git a/overlay/etc/crontabs/nginx b/overlay/etc/crontabs/nginx new file mode 100644 index 0000000..9cc07ad --- /dev/null +++ b/overlay/etc/crontabs/nginx @@ -0,0 +1 @@ +0 8 * * * cd /var/www/app && ./cli cronjob >/dev/null 2>&1 diff --git a/overlay/etc/nginx/nginx.conf b/overlay/etc/nginx/nginx.conf new file mode 100644 index 0000000..4b24902 --- /dev/null +++ b/overlay/etc/nginx/nginx.conf @@ -0,0 +1,76 @@ +user nginx; +worker_processes 1; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + server_tokens off; + access_log off; + error_log /dev/stderr; + + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + + server { + listen 80; + server_name localhost; + index index.php; + root /var/www/app; + client_max_body_size 32M; + + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php-fpm.sock; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_index index.php; + include fastcgi_params; + } + + location ~ /data { + return 404; + } + + location ~* ^.+\.(log|sqlite)$ { + return 404; + } + + location ~ /\.ht { + return 404; + } + + location ~* ^.+\.(ico|jpg|gif|png|css|js|svg|eot|ttf|woff|woff2|otf)$ { + log_not_found off; + expires 7d; + etag on; + } + + gzip on; + gzip_comp_level 3; + gzip_disable "msie6"; + gzip_vary on; + gzip_types + text/javascript + application/javascript + application/json + text/xml + application/xml + application/rss+xml + text/css + text/plain; + } +} diff --git a/overlay/etc/php7/php-fpm.conf b/overlay/etc/php7/php-fpm.conf new file mode 100644 index 0000000..31caf98 --- /dev/null +++ b/overlay/etc/php7/php-fpm.conf @@ -0,0 +1,21 @@ +[global] +error_log = /proc/self/fd/2 +log_level = warning +daemonize = no + +[www] +catch_workers_output = yes + +user = nginx +group = nginx + +listen.owner = nginx +listen.group = nginx +listen = /var/run/php-fpm.sock + +pm = dynamic +pm.max_children = 20 +pm.start_servers = 1 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +pm.max_requests = 2048 diff --git a/overlay/etc/php7/php.ini b/overlay/etc/php7/php.ini new file mode 100644 index 0000000..607e30c --- /dev/null +++ b/overlay/etc/php7/php.ini @@ -0,0 +1,391 @@ +[PHP] +user_ini.filename = ".user.ini" +user_ini.cache_ttl = 300 + +engine = On +short_open_tag = Off + +precision = 14 + +output_buffering = 0 +;output_handler = + +zlib.output_compression = Off +;zlib.output_compression_level = -1 +;zlib.output_handler = + +implicit_flush = Off + +unserialize_callback_func = +serialize_precision = 17 + +open_basedir = "/var/www/app:/var/lib/php/tmp_upload:/var/lib/php/session:/var/lib/php/soap_cache" + +disable_functions = system, exec, shell_exec, phpinfo, show_source, highlight_file, popen, proc_open, fopen_with_path, dbmopen, dbase_open, putenv, move_uploaded_file, mkdir, rmdir, chmod, rename, filepro, filepro_rowcount, filepro_retrieve, posix_mkfifo +disable_classes = + +;highlight.string = #DD0000 +;highlight.comment = #FF9900 +;highlight.keyword = #007700 +;highlight.default = #0000BB +;highlight.html = #000000 + +;ignore_user_abort = On + +;realpath_cache_size = 16k +;realpath_cache_ttl = 120 + +zend.enable_gc = On +;zend.multibyte = Off +;zend.script_encoding = + +expose_php = Off + +max_execution_time = 30 +max_input_time = 60 +;max_input_nesting_level = 64 +max_input_vars = 100 +memory_limit = 50M + +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +display_errors = Off +display_startup_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +;report_zend_debug = 0 +;xmlrpc_errors = 0 +;xmlrpc_error_number = 0 +html_errors = On +;docref_root = "/phpmanual/" +;docref_ext = .html +;error_prepend_string = "" +;error_append_string = "" +error_log = /proc/self/fd/2 +;windows.show_crt_warning + +;arg_separator.output = "&" +;arg_separator.input = ";&" + +variables_order = "GPCS" +request_order = "GP" + +register_argc_argv = Off +auto_globals_jit = On +;enable_post_data_reading = Off +post_max_size = 8M + +auto_prepend_file = +auto_append_file = + +default_mimetype = "text/html" +default_charset = "UTF-8" +;internal_encoding = +;input_encoding = +;output_encoding = + +;include_path = ".:/php7/includes" + +doc_root = +user_dir = + +extension_dir = "/usr/lib/php7/modules" +;sys_temp_dir = "/tmp" +enable_dl = Off + +cgi.force_redirect = 1 +;cgi.nph = 1 +;cgi.redirect_status_env = +cgi.fix_pathinfo = 0 +cgi.discard_path = 1 + +;fastcgi.impersonate = 1 +;fastcgi.logging = 0 +;cgi.rfc2616_headers = 0 +;cgi.check_shebang_line = 1 + +file_uploads = Off +upload_tmp_dir = /var/lib/php/tmp_upload +upload_max_filesize = 2M +max_file_uploads = 2 + +allow_url_fopen = On +allow_url_include = Off + +;from="john@doe.com" +;user_agent="PHP" + +default_socket_timeout = 60 +;auto_detect_line_endings = Off + +[CLI Server] +cli_server.color = On + +[Date] +date.timezone = Europe/Berlin +;date.default_latitude = 31.7667 +;date.default_longitude = 35.2333 +;date.sunrise_zenith = 90.583333 +;date.sunset_zenith = 90.583333 + +[filter] +;filter.default = unsafe_raw +;filter.default_flags = + +[iconv] +;iconv.input_encoding = +;iconv.internal_encoding = +;iconv.output_encoding = + +[intl] +;intl.default_locale = +;intl.error_level = E_WARNING +;intl.use_exceptions = 0 + +[sqlite3] +;sqlite3.extension_dir = + +[Pcre] +;pcre.backtrack_limit = 100000 +;pcre.recursion_limit = 100000 +;pcre.jit = 1 + +[Pdo] +;pdo_odbc.connection_pooling = strict +;pdo_odbc.db2_instance_name + +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket = + +[Phar] +;phar.readonly = On +;phar.require_hash = On +;phar.cache_list = + +[mail function] +SMTP = localhost +smtp_port = 25 +;sendmail_path = + +;mail.force_extra_parameters = +mail.add_x_header = On +;mail.log = +;mail.log = syslog + +[SQL] +sql.safe_mode = On + +[ODBC] +;odbc.default_db = Not yet implemented +;odbc.default_user = Not yet implemented +;odbc.default_pw = Not yet implemented +;odbc.default_cursortype +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 +;birdstep.max_links = -1 + +[Interbase] +ibase.allow_persistent = 1 +ibase.max_persistent = -1 +ibase.max_links = -1 +;ibase.default_db = +;ibase.default_user = +;ibase.default_password = +;ibase.default_charset = +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" +ibase.dateformat = "%Y-%m-%d" +ibase.timeformat = "%H:%M:%S" + +[MySQLi] +;mysqli.allow_local_infile = On +mysqli.max_persistent = -1 +mysqli.allow_persistent = On +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off + +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off +;mysqlnd.debug = +;mysqlnd.log_mask = 0 +;mysqlnd.mempool_default_size = 16000 +;mysqlnd.net_cmd_buffer_size = 2048 +;mysqlnd.net_read_buffer_size = 32768 +;mysqlnd.net_read_timeout = 31536000 +;mysqlnd.sha256_server_public_key = + +[OCI8] +;oci8.privileged_connect = Off +;oci8.max_persistent = -1 +;oci8.persistent_timeout = -1 +;oci8.ping_interval = 60 +;oci8.connection_class = +;oci8.events = Off +;oci8.statement_cache_size = 20 +;oci8.default_prefetch = 100 +;oci8.old_oci_close_semantics = Off + +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 + +[bcmath] +bcmath.scale = 0 + +[browscap] +browscap = /etc/php7/browscap.ini + +[Session] +session.save_handler = files +session.save_path = "/var/lib/php/session" +session.use_strict_mode = 1 +session.use_cookies = 1 +session.cookie_secure = 0 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = Off +session.cookie_lifetime = 14400 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = 1 +session.serialize_handler = php +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.referer_check = +;session.entropy_length = 32 +;session.entropy_file = /dev/urandom +session.cache_limiter = nocache +session.cache_expire = 30 +session.use_trans_sid = 0 +session.hash_function = sha512 +session.hash_bits_per_character = 5 +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" +;session.upload_progress.enabled = On +;session.upload_progress.cleanup = On +;session.upload_progress.prefix = "upload_progress_" +;session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" +;session.upload_progress.freq = "1%" +;session.upload_progress.min_freq = "1" +;session.lazy_write = On + +[Assertion] +zend.assertions = -1 +;assert.active = On +;assert.exception = On +;assert.warning = On +;assert.bail = Off +;assert.callback = 0 +;assert.quiet_eval = 0 + +[COM] +;com.typelib_file = +;com.allow_dcom = true +;com.autoregister_typelib = true +;com.autoregister_casesensitive = false +;com.autoregister_verbose = true +;com.code_page= + +[mbstring] +;mbstring.language = Japanese +;mbstring.internal_encoding = +;mbstring.http_input = +;mbstring.http_output = +;mbstring.encoding_translation = Off +;mbstring.detect_order = auto +;mbstring.substitute_character = none +;mbstring.func_overload = 0 +;mbstring.strict_detection = On +;mbstring.http_output_conv_mimetype = + +[gd] +;gd.jpeg_ignore_warning = 0 + +[exif] +;exif.encode_unicode = ISO-8859-15 +;exif.decode_unicode_motorola = UCS-2BE +;exif.decode_unicode_intel = UCS-2LE +;exif.encode_jis = +;exif.decode_jis_motorola = JIS +;exif.decode_jis_intel = JIS + +[Tidy] +;tidy.default_config = /usr/local/lib/php7/default.tcfg +tidy.clean_output = Off + +[soap] +soap.wsdl_cache_enabled = 1 +soap.wsdl_cache_dir = "/var/lib/php/soap_cache" +soap.wsdl_cache_ttl = 86400 +soap.wsdl_cache_limit = 5 + +[sysvshm] +;sysvshm.init_mem = 10000 + +[ldap] +ldap.max_links = -1 + +[mcrypt] +;mcrypt.algorithms_dir = +;mcrypt.modes_dir = + +[dba] +;dba.default_handler = + +[opcache] +;opcache.enable = 0 +;opcache.enable_cli = 0 +;opcache.memory_consumption = 64 +;opcache.interned_strings_buffer = 4 +;opcache.max_accelerated_files = 2000 +;opcache.max_wasted_percentage = 5 +;opcache.use_cwd = 1 +;opcache.validate_timestamps = 1 +;opcache.revalidate_freq = 2 +;opcache.revalidate_path = 0 +;opcache.save_comments = 1 +;opcache.fast_shutdown = 0 +;opcache.enable_file_override = 0 +;opcache.optimization_level = 0xffffffff +;opcache.dups_fix = 0 +;opcache.blacklist_filename = +;opcache.max_file_size = 0 +;opcache.consistency_checks = 0 +;opcache.force_restart_timeout = 180 +;opcache.error_log = +;opcache.log_verbosity_level = 1 +;opcache.preferred_memory_model = +;opcache.protect_memory = 0 +;opcache.restrict_api = +;opcache.mmap_base = +;opcache.file_cache = +;opcache.file_cache_only = 0 +;opcache.file_cache_consistency_checks = 1 +;opcache.file_cache_fallback = 1 +;opcache.huge_code_pages = 1 +;opcache.validate_permission = 0 +;opcache.validate_root = 0 + +[curl] +curl.cainfo = /etc/ssl/certs/ca-certificates.crt + +[openssl] +openssl.cafile = /etc/ssl/certs/ca-certificates.crt +openssl.capath = /etc/ssl/certs diff --git a/overlay/etc/services.d/.s6-svscan/crash b/overlay/etc/services.d/.s6-svscan/crash new file mode 100755 index 0000000..3c3a189 --- /dev/null +++ b/overlay/etc/services.d/.s6-svscan/crash @@ -0,0 +1,4 @@ +#!/bin/sh +set -e +echo "Container crashed. Exiting..." +exit 1 diff --git a/overlay/etc/services.d/.s6-svscan/finish b/overlay/etc/services.d/.s6-svscan/finish new file mode 100755 index 0000000..039e4d0 --- /dev/null +++ b/overlay/etc/services.d/.s6-svscan/finish @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 diff --git a/overlay/etc/services.d/cron/run b/overlay/etc/services.d/cron/run new file mode 100755 index 0000000..2cc28e5 --- /dev/null +++ b/overlay/etc/services.d/cron/run @@ -0,0 +1,2 @@ +#!/bin/execlineb -P +crond -f diff --git a/overlay/etc/services.d/nginx/run b/overlay/etc/services.d/nginx/run new file mode 100755 index 0000000..7bb9132 --- /dev/null +++ b/overlay/etc/services.d/nginx/run @@ -0,0 +1,2 @@ +#!/bin/execlineb -P +nginx -g "daemon off;" diff --git a/overlay/etc/services.d/php/run b/overlay/etc/services.d/php/run new file mode 100755 index 0000000..21dd010 --- /dev/null +++ b/overlay/etc/services.d/php/run @@ -0,0 +1,2 @@ +#!/bin/execlineb -P +php-fpm7 -F diff --git a/overlay/etc/templates/config.php.tmpl b/overlay/etc/templates/config.php.tmpl new file mode 100644 index 0000000..1594dc0 --- /dev/null +++ b/overlay/etc/templates/config.php.tmpl @@ -0,0 +1,245 @@ +" +;error_append_string = "" +error_log = {{ getenv "PHP_ERROR_LOG" "/proc/self/fd/2"}} +;windows.show_crt_warning + +;arg_separator.output = "&" +;arg_separator.input = ";&" + +variables_order = "GPCS" +request_order = "GP" + +register_argc_argv = Off +auto_globals_jit = On +;enable_post_data_reading = Off +post_max_size = {{ getenv "PHP_POST_MAX_SIZE" "8M" }} + +auto_prepend_file = +auto_append_file = + +default_mimetype = "text/html" +default_charset = "UTF-8" +;internal_encoding = +;input_encoding = +;output_encoding = + +;include_path = ".:/php7/includes" + +doc_root = +user_dir = + +extension_dir = "/usr/lib/php7/modules" +;sys_temp_dir = "/tmp" +enable_dl = Off + +cgi.force_redirect = 1 +;cgi.nph = 1 +;cgi.redirect_status_env = +cgi.fix_pathinfo = 0 +cgi.discard_path = 1 + +;fastcgi.impersonate = 1 +;fastcgi.logging = 0 +;cgi.rfc2616_headers = 0 +;cgi.check_shebang_line = 1 + +file_uploads = {{ getenv "PHP_FILE_UPLOADS" "Off" }} +upload_tmp_dir = /var/lib/php/tmp_upload +upload_max_filesize = {{ getenv "PHP_UPLOAD_MAX_FILESIZE" "2M" }} +max_file_uploads = {{ getenv "PHP_MAX_FILE_UPLOADS" "2" }} + +allow_url_fopen = {{ getenv "PHP_ALLOW_URL_FOPEN" "On" }} +allow_url_include = {{ getenv "PHP_ALLOW_URL_INCLUDE" "Off" }} + +;from="john@doe.com" +;user_agent="PHP" + +default_socket_timeout = 60 +;auto_detect_line_endings = Off + +[CLI Server] +cli_server.color = On + +[Date] +date.timezone = {{ getenv "PHP_DATE_TIMEZONE" "Europe/Berlin" }} +;date.default_latitude = 31.7667 +;date.default_longitude = 35.2333 +;date.sunrise_zenith = 90.583333 +;date.sunset_zenith = 90.583333 + +[filter] +;filter.default = unsafe_raw +;filter.default_flags = + +[iconv] +;iconv.input_encoding = +;iconv.internal_encoding = +;iconv.output_encoding = + +[intl] +;intl.default_locale = +;intl.error_level = E_WARNING +;intl.use_exceptions = 0 + +[sqlite3] +;sqlite3.extension_dir = + +[Pcre] +;pcre.backtrack_limit = 100000 +;pcre.recursion_limit = 100000 +;pcre.jit = 1 + +[Pdo] +;pdo_odbc.connection_pooling = strict +;pdo_odbc.db2_instance_name + +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket = + +[Phar] +;phar.readonly = On +;phar.require_hash = On +;phar.cache_list = + +[mail function] +SMTP = localhost +smtp_port = 25 +;sendmail_path = + +;mail.force_extra_parameters = +mail.add_x_header = On +;mail.log = +;mail.log = syslog + +[SQL] +sql.safe_mode = {{ getenv "PHP_SQL_SAFE_MODE" "On" }} + +[ODBC] +;odbc.default_db = Not yet implemented +;odbc.default_user = Not yet implemented +;odbc.default_pw = Not yet implemented +;odbc.default_cursortype +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 +;birdstep.max_links = -1 + +[Interbase] +ibase.allow_persistent = 1 +ibase.max_persistent = -1 +ibase.max_links = -1 +;ibase.default_db = +;ibase.default_user = +;ibase.default_password = +;ibase.default_charset = +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" +ibase.dateformat = "%Y-%m-%d" +ibase.timeformat = "%H:%M:%S" + +[MySQLi] +;mysqli.allow_local_infile = On +mysqli.max_persistent = -1 +mysqli.allow_persistent = On +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off + +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off +;mysqlnd.debug = +;mysqlnd.log_mask = 0 +;mysqlnd.mempool_default_size = 16000 +;mysqlnd.net_cmd_buffer_size = 2048 +;mysqlnd.net_read_buffer_size = 32768 +;mysqlnd.net_read_timeout = 31536000 +;mysqlnd.sha256_server_public_key = + +[OCI8] +;oci8.privileged_connect = Off +;oci8.max_persistent = -1 +;oci8.persistent_timeout = -1 +;oci8.ping_interval = 60 +;oci8.connection_class = +;oci8.events = Off +;oci8.statement_cache_size = 20 +;oci8.default_prefetch = 100 +;oci8.old_oci_close_semantics = Off + +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 + +[bcmath] +bcmath.scale = 0 + +[browscap] +browscap = /etc/php7/browscap.ini + +[Session] +session.save_handler = files +session.save_path = "/var/lib/php/session" +session.use_strict_mode = 1 +session.use_cookies = 1 +session.cookie_secure = 0 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = Off +session.cookie_lifetime = 14400 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = 1 +session.serialize_handler = php +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.referer_check = +;session.entropy_length = 32 +;session.entropy_file = /dev/urandom +session.cache_limiter = nocache +session.cache_expire = 30 +session.use_trans_sid = 0 +session.hash_function = sha512 +session.hash_bits_per_character = 5 +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" +;session.upload_progress.enabled = On +;session.upload_progress.cleanup = On +;session.upload_progress.prefix = "upload_progress_" +;session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" +;session.upload_progress.freq = "1%" +;session.upload_progress.min_freq = "1" +;session.lazy_write = On + +[Assertion] +zend.assertions = -1 +;assert.active = On +;assert.exception = On +;assert.warning = On +;assert.bail = Off +;assert.callback = 0 +;assert.quiet_eval = 0 + +[COM] +;com.typelib_file = +;com.allow_dcom = true +;com.autoregister_typelib = true +;com.autoregister_casesensitive = false +;com.autoregister_verbose = true +;com.code_page= + +[mbstring] +;mbstring.language = Japanese +;mbstring.internal_encoding = +;mbstring.http_input = +;mbstring.http_output = +;mbstring.encoding_translation = Off +;mbstring.detect_order = auto +;mbstring.substitute_character = none +;mbstring.func_overload = 0 +;mbstring.strict_detection = On +;mbstring.http_output_conv_mimetype = + +[gd] +;gd.jpeg_ignore_warning = 0 + +[exif] +;exif.encode_unicode = ISO-8859-15 +;exif.decode_unicode_motorola = UCS-2BE +;exif.decode_unicode_intel = UCS-2LE +;exif.encode_jis = +;exif.decode_jis_motorola = JIS +;exif.decode_jis_intel = JIS + +[Tidy] +;tidy.default_config = /usr/local/lib/php7/default.tcfg +tidy.clean_output = Off + +[soap] +soap.wsdl_cache_enabled = 1 +soap.wsdl_cache_dir = "/var/lib/php/soap_cache" +soap.wsdl_cache_ttl = 86400 +soap.wsdl_cache_limit = 5 + +[sysvshm] +;sysvshm.init_mem = 10000 + +[ldap] +ldap.max_links = -1 + +[mcrypt] +;mcrypt.algorithms_dir = +;mcrypt.modes_dir = + +[dba] +;dba.default_handler = + +[opcache] +;opcache.enable = 0 +;opcache.enable_cli = 0 +;opcache.memory_consumption = 64 +;opcache.interned_strings_buffer = 4 +;opcache.max_accelerated_files = 2000 +;opcache.max_wasted_percentage = 5 +;opcache.use_cwd = 1 +;opcache.validate_timestamps = 1 +;opcache.revalidate_freq = 2 +;opcache.revalidate_path = 0 +;opcache.save_comments = 1 +;opcache.fast_shutdown = 0 +;opcache.enable_file_override = 0 +;opcache.optimization_level = 0xffffffff +;opcache.dups_fix = 0 +;opcache.blacklist_filename = +;opcache.max_file_size = 0 +;opcache.consistency_checks = 0 +;opcache.force_restart_timeout = 180 +;opcache.error_log = +;opcache.log_verbosity_level = 1 +;opcache.preferred_memory_model = +;opcache.protect_memory = 0 +;opcache.restrict_api = +;opcache.mmap_base = +;opcache.file_cache = +;opcache.file_cache_only = 0 +;opcache.file_cache_consistency_checks = 1 +;opcache.file_cache_fallback = 1 +;opcache.huge_code_pages = 1 +;opcache.validate_permission = 0 +;opcache.validate_root = 0 + +[curl] +curl.cainfo = /etc/ssl/certs/ca-certificates.crt + +[openssl] +openssl.cafile = /etc/ssl/certs/ca-certificates.crt +openssl.capath = /etc/ssl/certs diff --git a/overlay/usr/local/bin/entrypoint.sh b/overlay/usr/local/bin/entrypoint.sh new file mode 100755 index 0000000..0439899 --- /dev/null +++ b/overlay/usr/local/bin/entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh +/usr/local/bin/gomplate -V -o /etc/php7/php.ini -f /etc/templates/php.ini.tmpl +/usr/local/bin/gomplate -V -o /var/www/app/config.php -f /etc/templates/config.php.tmpl + +chown -R nginx:nginx /var/www/app/data +chown -R nginx:nginx /var/www/app/plugins + +exec /bin/s6-svscan /etc/services.d diff --git a/overlay/usr/local/bin/healthcheck.sh b/overlay/usr/local/bin/healthcheck.sh new file mode 100755 index 0000000..67cbd61 --- /dev/null +++ b/overlay/usr/local/bin/healthcheck.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +set -eo pipefail +URL=http://localhost + +wget --quiet --tries=1 --spider ${URL} +[ $? -ne 0 ] && exit 1 + +CONTENT=$(wget --quiet -O - ${URL}) +case "$CONTENT" in + *Exception*) exit 1 ;; + *alert-*alert-*SELF_URL_PATH*) exit 1 ;; + *alert-*SELF_URL_PATH*alert-*) exit 1 ;; + *SELF_URL_PATH*alert-*alert-*) exit 1 ;; +esac + +exit 0