diff --git a/Dockerfile b/Dockerfile index 1d6f7e3..945ebc6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,59 +1,33 @@ -FROM kdelfour/supervisor-docker +# Using https://github.com/smebberson/docker-alpine, which in turn +# uses https://github.com/just-containers/s6-overlay for a s6 Docker overlay +FROM smebberson/alpine-base # Initially was based on work of Christian Lück -MAINTAINER Andreas Löffler +LABEL description="A complete, self-hosted Tiny Tiny RSS (TTRSS) environment." \ + maintainer="Andreas Löffler " -RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ - nginx git ca-certificates php5-fpm php5-cli php5-curl php5-gd php5-json php5-mcrypt php5-pgsql +RUN set -xe && \ + apk update && apk upgrade && \ + apk add --no-cache --virtual=run-deps \ + nginx git ca-certificates \ + php5 php5-fpm php5-curl php5-dom php5-gd php5-json php5-mcrypt php5-pcntl php5-pdo php5-pdo_pgsql php5-pgsql php5-posix -# add ttrss as the only Nginx site -ADD ttrss-nginx.conf /etc/nginx/sites-available/ttrss -RUN ln -s /etc/nginx/sites-available/ttrss /etc/nginx/sites-enabled/ttrss -RUN rm /etc/nginx/sites-enabled/default +# Add user www-data for php-fpm +# 82 is the standard uid/gid for "www-data" in Alpine +RUN adduser -u 82 -D -S -G www-data www-data -# patch php5-fpm configuration so that it does not daemonize itself. This is -# needed so that runit can watch its state and restart it if it crashes etc. -RUN sed -i -e "s/;daemonize\s*=\s*yes/daemonize = no/g" /etc/php5/fpm/php-fpm.conf - -# patch the php-fpm's listening method to _always_ use a unix socket -# note: if not done correctly this will result in a "502 Bad Gateway" error -# (see /var/log/nginx/error.log for more information then) -RUN sed -i -e "s/listen\s*=.*/listen = \/var\/run\/php5-fpm.sock/g" /etc/php5/fpm/pool.d/www.conf - -# enable PHP5 modules -RUN php5enmod mcrypt +COPY root / # expose Nginx ports -EXPOSE 80 -EXPOSE 443 +EXPOSE 8080 +EXPOSE 4443 # expose default database credentials via ENV in order to ease overwriting ENV DB_NAME ttrss ENV DB_USER ttrss ENV DB_PASS ttrss -# always re-configure database with current ENV when RUNning container, then monitor all services -RUN mkdir -p /srv -ADD ttrss-utils.php /srv/ttrss-utils.php -ADD ttrss-configure-db.php /srv/ttrss-configure-db.php -ADD ttrss-configure-plugin-mobilize.php /srv/ttrss-configure-plugin-mobilize.php -ADD ttrss-plugin-mobilize.pgsql /srv/ttrss-plugin-mobilize.pgsql - -ADD setup-ttrss.sh /srv/setup-ttrss.sh -ADD update-ttrss.sh /srv/update-ttrss.sh -ADD start-ttrss.sh /srv/start-ttrss.sh - -RUN mkdir -p /etc/supervisor/conf.d -ADD service-nginx.conf /etc/supervisor/conf.d/nginx.conf -ADD service-php5-fpm.conf /etc/supervisor/conf.d/php5.conf -ADD service-ttrss-daemon.conf /etc/supervisor/conf.d/ttrss-daemon.conf -ADD service-ttrss-update.conf /etc/supervisor/conf.d/ttrss-update.conf - # only run the setup once -RUN /srv/setup-ttrss.sh +RUN set -xe && /srv/setup-ttrss.sh # clean up -RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# start supervisord -WORKDIR /srv -CMD ["/srv/start-ttrss.sh"] +RUN set -xe && apk del --progress --purge && rm -rf /var/cache/apk/* diff --git a/README.md b/README.md index 52dcb07..cf25be8 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,12 @@ This Dockerfile installs Tiny Tiny RSS (TT-RSS) with the following features: -- **New:** Rolling release support: Updates TT-RSS automatically every day -- **New:** Works nicely with jwilder's [nginx-proxy](https://github.com/jwilder/nginx-proxy), e.g. to use for Let's Encrypt SSL certificates +- **New:** Based on [Docker-Alpine](https://github.com/smebberson/docker-alpine) and [s6][nginx-proxy](http://skarnet.org/software/s6/) as the supervisor +- **New:** Small and lightweight image size (about 100 MB) +- Rolling release support: Updates TT-RSS automatically every day +- Works nicely with jwilder's [nginx-proxy](https://github.com/jwilder/nginx-proxy), e.g. to use for Let's Encrypt SSL certificates - Integrated [Feedly theme](https://github.com/levito/tt-rss-feedly-theme) +- **New:** Integrated [FeedIron plugin](https://github.com/m42e/ttrss_plugin-feediron) to get modify feeds - Integrated [Mobilize plugin](https://github.com/sepich/tt-rss-mobilize) for using Readability, Instapaper + Google Mobilizer - Integrated [News+ plugin](https://github.com/hrk/tt-rss-newsplus-plugin) for [News+](https://play.google.com/store/apps/details?id=com.noinnion.android.newsplus) on Android - Optional: Self-signed 2048-bit RSA TLS certificate for accessing TT-RSS via https @@ -35,7 +38,7 @@ Just start up a new database container: Next, run the actual TT-RSS instance by doing a: ```bash -# docker run -d --link $DB:db -p 80:80 --name ttrss x86dev/docker-ttrss +# docker run -d --link $DB:db -p 80:8080 --name ttrss x86dev/docker-ttrss ``` Running this command for the first time will download the image automatically. @@ -57,13 +60,17 @@ Password: password Obviously, you're recommended to change those ASAP. -## Enabling SSL/TLS support -For enabling SSL/TLS support with a self-signed certificate you have to add `-e TTRSS_SSL_ENABLED=1` +## Enabling SSL/TLS encryption support + +For enabling SSL/TLS support with a self-signed certificate you have to add `-e TTRSS_SSL_ENABLED=1 -p 443:4443` when running your TT-RSS container. Then you can access TT-RSS via: `https://`. +**Warning: Running services unencrypted on the Internet is not recommended!** + The container also has been successfully tested with Let's Encrypt certificates. + ## Reverse proxy support A nice thing to have is jwilder's [nginx-proxy](https://github.com/jwilder/nginx-proxy) as a separate @@ -73,7 +80,7 @@ That way you easily can integrate your TT-RSS instance with an existing domain b (e.g. https://ttrss.yourdomain.com). In combination with an official Let's Encrypt certificate you can get a nice A+ encryption/security rating over at [SSLLabs](https://www.ssllabs.com/ssltest/). -Never run your services unencrypted! +**Never run your services unencrypted!** ## Installation walkthrough @@ -86,6 +93,7 @@ database instance and configuration you're relying on. Also, this makes this container quite disposable, as it doesn't store any sensitive information at all. + ### Starting a database instance This container requires a PostgreSQL database instance. You're free to pick (or build) @@ -175,15 +183,16 @@ When running this docker container you don't need to worry anymore how and when update TT-RSS. Since TT-RSS has a so-called "rolling release" model since some time (which essentially means that there won't be any specific versions like 1.0, 1.1 etc), this container takes the burden any checks for updates of TT-RSS and the accompanied -plugins/themes every day via an own update script (see `update-ttrss.sh`). +plugins/themes every day via an own update script (see `root/srv/update-ttrss.sh`). By default the update script checks every 24 hours if there are updates for TT-RSS, the plugins or the theme(s) available. If you want to change the update interval you just need to edit the file -`service-ttrss-update.conf` and change the `--wait-exit 24h` to fit your needs, whereas +`root/etc/services.d/ttrss-updater/run` and change the `--wait-exit 24h` to fit your needs, whereas the suffix `h` stands for hours, `m` for minutes and `s` for seconds. + ### Want to contribute? You think you have something which absolutely must be part of this container, implemented diff --git a/root/etc/cont-init.d/99-ttrss b/root/etc/cont-init.d/99-ttrss new file mode 100644 index 0000000..352cca4 --- /dev/null +++ b/root/etc/cont-init.d/99-ttrss @@ -0,0 +1,2 @@ +#!/usr/bin/with-contenv sh +cd /srv && ./setup-ttrss.sh diff --git a/root/etc/nginx/nginx.conf b/root/etc/nginx/nginx.conf new file mode 100644 index 0000000..eb42325 --- /dev/null +++ b/root/etc/nginx/nginx.conf @@ -0,0 +1,75 @@ +user www-data; +worker_processes auto; +pid /tmp/nginx.pid; +daemon off; + +events { + worker_connections 1024; + use epoll; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log debug; + + sendfile on; + keepalive_timeout 15; + keepalive_disable msie6; + keepalive_requests 100; + tcp_nopush on; + tcp_nodelay on; + server_tokens off; + + fastcgi_temp_path /tmp/fastcgi 1 2; + client_body_temp_path /tmp/client_body 1 2; + proxy_temp_path /tmp/proxy 1 2; + uwsgi_temp_path /tmp/uwsgi 1 2; + scgi_temp_path /tmp/scgi 1 2; + + gzip off; + + server + { + listen 4443; + root /var/www/ttrss; + + ssl on; + ssl_certificate /etc/ssl/certs/ttrss.crt; + ssl_certificate_key /etc/ssl/private/ttrss.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; + + index index.php index.html; + client_max_body_size 100M; + + location / { + try_files $uri $uri/ =404; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.*\.php)(/.*)?$; + fastcgi_pass unix:/tmp/php-fpm.sock; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_intercept_errors off; + fastcgi_buffer_size 16k; + fastcgi_buffers 4 16k; + } + + location ~ /\.ht { + deny all; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/tmp/php-fpm.sock; + fastcgi_index index.php; + include fastcgi_params; + } + } +} diff --git a/root/etc/php5/php-fpm.conf b/root/etc/php5/php-fpm.conf new file mode 100644 index 0000000..2111c80 --- /dev/null +++ b/root/etc/php5/php-fpm.conf @@ -0,0 +1,19 @@ +[global] +daemonize = no + +[www] +user = www-data +listen.owner = www-data +listen.group = www-data +listen = /tmp/php-fpm.sock +pm = dynamic +pm.max_children = 15 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 6 +chdir = /var/www/ttrss/ +request_terminate_timeout = 0 +env[PATH] = /usr/local/bin:/usr/bin:/bin +php_admin_value[max_execution_time] = 10800 +php_admin_value[max_input_time] = 3600 +php_admin_value[expose_php] = Off diff --git a/root/etc/services.d/.s6-svscan/finish b/root/etc/services.d/.s6-svscan/finish new file mode 100644 index 0000000..92b94c4 --- /dev/null +++ b/root/etc/services.d/.s6-svscan/finish @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 0 \ No newline at end of file diff --git a/root/etc/services.d/nginx/run b/root/etc/services.d/nginx/run new file mode 100644 index 0000000..eaf8049 --- /dev/null +++ b/root/etc/services.d/nginx/run @@ -0,0 +1,2 @@ +#!/bin/sh +exec nginx diff --git a/root/etc/services.d/php/run b/root/etc/services.d/php/run new file mode 100644 index 0000000..2639c94 --- /dev/null +++ b/root/etc/services.d/php/run @@ -0,0 +1,2 @@ +#!/bin/sh +exec php-fpm diff --git a/root/etc/services.d/ttrss-daemon/run b/root/etc/services.d/ttrss-daemon/run new file mode 100644 index 0000000..ef437ea --- /dev/null +++ b/root/etc/services.d/ttrss-daemon/run @@ -0,0 +1,7 @@ +#!/bin/sh + +while true; do + cd /var/www/ttrss + php -f /var/www/ttrss/update_daemon2.php + sleep 5m +done diff --git a/root/etc/services.d/ttrss-updater/run b/root/etc/services.d/ttrss-updater/run new file mode 100644 index 0000000..dc385de --- /dev/null +++ b/root/etc/services.d/ttrss-updater/run @@ -0,0 +1,6 @@ +#!/bin/sh + +while true; do + /srv/update-ttrss.sh + sleep 24h +done diff --git a/setup-ttrss.sh b/root/srv/setup-ttrss.sh similarity index 58% rename from setup-ttrss.sh rename to root/srv/setup-ttrss.sh index 4c02443..ee5ac66 100755 --- a/setup-ttrss.sh +++ b/root/srv/setup-ttrss.sh @@ -8,8 +8,11 @@ setup_nginx() TTRSS_HOST=ttrss fi + NGINX_CONF=/etc/nginx/nginx.conf + if [ "$TTRSS_SSL_ENABLED" = "1" ]; then if [ ! -f "/etc/ssl/private/ttrss.key" ]; then + echo "Setup: Generating self-signed certificate ..." # Generate the TLS certificate for our Tiny Tiny RSS server instance. openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \ -subj "/C=US/ST=World/L=World/O=$TTRSS_HOST/CN=$TTRSS_HOST" \ @@ -19,14 +22,13 @@ setup_nginx() chmod 600 "/etc/ssl/private/ttrss.key" chmod 600 "/etc/ssl/certs/ttrss.crt" else + echo "Setup: !!! WARNING !!! Turning OFF SSL/TLS !!! WARNING !!!" + echo "Setup: This is not recommended for a production server. You have been warned." # Turn off SSL. - sed -i -e "s/listen\s*443\s*;/listen 80;/g" /etc/nginx/sites-available/ttrss - sed -i -e "s/ssl\s*on\s*;/ssl off;/g" /etc/nginx/sites-available/ttrss - sed -i -e "/\s*ssl_*/d" /etc/nginx/sites-available/ttrss + sed -i -e "s/listen\s*4443\s*;/listen 8080;/g" ${NGINX_CONF} + sed -i -e "s/ssl\s*on\s*;/ssl off;/g" ${NGINX_CONF} + sed -i -e "/\s*ssl_*/d" ${NGINX_CONF} fi - - # Configure Nginx so that is doesn't show its version number in the HTTP headers. - sed -i -e "s/.*server_tokens\s.*/server_tokens off;/g" /etc/nginx/nginx.conf } setup_ttrss() @@ -34,10 +36,11 @@ setup_ttrss() TTRSS_PATH=/var/www/ttrss mkdir -p ${TTRSS_PATH} - git clone https://tt-rss.org/gitlab/fox/tt-rss.git ${TTRSS_PATH} - git clone https://github.com/sepich/tt-rss-mobilize.git ${TTRSS_PATH}/plugins/mobilize - git clone https://github.com/hrk/tt-rss-newsplus-plugin.git ${TTRSS_PATH}/plugins/api_newsplus - git clone https://github.com/levito/tt-rss-feedly-theme.git ${TTRSS_PATH}/themes/feedly-git + git clone --depth=1 https://tt-rss.org/gitlab/fox/tt-rss.git ${TTRSS_PATH} + git clone --depth=1 https://github.com/sepich/tt-rss-mobilize.git ${TTRSS_PATH}/plugins/mobilize + git clone --depth=1 https://github.com/hrk/tt-rss-newsplus-plugin.git ${TTRSS_PATH}/plugins/api_newsplus + git clone --depth=1 https://github.com/m42e/ttrss_plugin-feediron.git ${TTRSS_PATH}/plugins/feediron + git clone --depth=1 https://github.com/levito/tt-rss-feedly-theme.git ${TTRSS_PATH}/themes/feedly-git # Add initial config. cp ${TTRSS_PATH}/config.php-dist ${TTRSS_PATH}/config.php diff --git a/root/srv/start-ttrss.sh b/root/srv/start-ttrss.sh new file mode 100755 index 0000000..ed87717 --- /dev/null +++ b/root/srv/start-ttrss.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +# Update configuration. This is necessary for entering the current IP + PORT of the database. +/srv/update-ttrss.sh --no-start + +# Call the image's init script which in turn calls the s6 supervisor then. +/init diff --git a/ttrss-configure-db.php b/root/srv/ttrss-configure-db.php similarity index 100% rename from ttrss-configure-db.php rename to root/srv/ttrss-configure-db.php diff --git a/ttrss-configure-plugin-mobilize.php b/root/srv/ttrss-configure-plugin-mobilize.php similarity index 100% rename from ttrss-configure-plugin-mobilize.php rename to root/srv/ttrss-configure-plugin-mobilize.php diff --git a/ttrss-plugin-mobilize.pgsql b/root/srv/ttrss-plugin-mobilize.pgsql similarity index 100% rename from ttrss-plugin-mobilize.pgsql rename to root/srv/ttrss-plugin-mobilize.pgsql diff --git a/ttrss-utils.php b/root/srv/ttrss-utils.php similarity index 100% rename from ttrss-utils.php rename to root/srv/ttrss-utils.php diff --git a/update-ttrss.sh b/root/srv/update-ttrss.sh similarity index 60% rename from update-ttrss.sh rename to root/srv/update-ttrss.sh index 94bbfb9..698e5e4 100755 --- a/update-ttrss.sh +++ b/root/srv/update-ttrss.sh @@ -3,26 +3,22 @@ set -e TTRSS_PATH=/var/www/ttrss -# Note: Make sure to keep the actual updater service ("ttrss-update") alive, -# otherwise this script will be killed and everyting goes nuts. -TTRSS_SUPERVISORD_SERVICES="ttrss-daemon nginx php5-fpm" - update_ttrss() { echo "Updating: Tiny Tiny RSS" - ( cd ${TTRSS_PATH} && git pull origin master ) + ( cd ${TTRSS_PATH} && git pull origin HEAD ) if [ -n "$DB_PORT" ]; then echo "Updating: Database" - php /srv/ttrss-configure-db.php - php /srv/ttrss-configure-plugin-mobilize.php + php -f /srv/ttrss-configure-db.php + php -f /srv/ttrss-configure-plugin-mobilize.php fi } update_plugin_mobilize() { echo "Updating: Mobilize plugin" - ( cd ${TTRSS_PATH}/plugins/mobilize && git pull origin master ) + ( cd ${TTRSS_PATH}/plugins/mobilize && git pull origin HEAD ) # Patch ttrss-mobilize plugin for getting it to work. sed -i -e "s/