1
0
mirror of https://github.com/x86dev/docker-ttrss synced 2025-12-13 01:46:00 +00:00

Now based on Alpine Linux and s6 as supervisor, resulting in a much smaller Docker image. See README.md for details and other additions.

This commit is contained in:
x86dev
2017-02-21 23:50:08 +01:00
parent 16230d1e5f
commit d7247f6861
23 changed files with 199 additions and 131 deletions

View File

@@ -0,0 +1,2 @@
#!/usr/bin/with-contenv sh
cd /srv && ./setup-ttrss.sh

75
root/etc/nginx/nginx.conf Normal file
View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -0,0 +1,3 @@
#!/bin/sh
exit 0

View File

@@ -0,0 +1,2 @@
#!/bin/sh
exec nginx

View File

@@ -0,0 +1,2 @@
#!/bin/sh
exec php-fpm

View File

@@ -0,0 +1,7 @@
#!/bin/sh
while true; do
cd /var/www/ttrss
php -f /var/www/ttrss/update_daemon2.php
sleep 5m
done

View File

@@ -0,0 +1,6 @@
#!/bin/sh
while true; do
/srv/update-ttrss.sh
sleep 24h
done

62
root/srv/setup-ttrss.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/bin/sh
set -e
setup_nginx()
{
if [ -z "$TTRSS_HOST" ]; then
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" \
-keyout "/etc/ssl/private/ttrss.key" \
-out "/etc/ssl/certs/ttrss.crt"
fi
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*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
}
setup_ttrss()
{
TTRSS_PATH=/var/www/ttrss
mkdir -p ${TTRSS_PATH}
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
# Patch URL path.
sed -i -e 's@htt.*/@'"${SELF_URL_PATH-http://localhost/}"'@g' ${TTRSS_PATH}/config.php
# Enable additional system plugins: api_newsplus.
sed -i -e "s/.*define('PLUGINS'.*/define('PLUGINS', 'api_newsplus, auth_internal, note, updater');/g" ${TTRSS_PATH}/config.php
}
echo "Setup: Installing Tiny Tiny RSS ..."
setup_ttrss
setup_nginx
echo "Setup: Applying updates ..."
/srv/update-ttrss.sh --no-start
echo "Setup: Done"

9
root/srv/start-ttrss.sh Executable file
View File

@@ -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

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env php
<?php
include '/srv/ttrss-utils.php';
if (!env('TTRSS_PATH', ''))
$confpath = '/var/www/ttrss/';
$conffile = $confpath . 'config.php';
$ename = 'DB';
$eport = 5432;
echo 'Configuring database for: ' . $conffile . PHP_EOL;
// check DB_NAME, which will be set automatically for a linked "db" container
if (!env($ename . '_PORT', '')) {
error('The env ' . $ename .'_PORT does not exist. Make sure to run with "--link mypostgresinstance:' . $ename . '"');
}
$config = array();
$config['DB_TYPE'] = 'pgsql';
$config['DB_HOST'] = env($ename . '_PORT_' . $eport . '_TCP_ADDR');
$config['DB_PORT'] = env($ename . '_PORT_' . $eport . '_TCP_PORT');
// database credentials for this instance
// database name (DB_NAME) can be supplied or detaults to "ttrss"
// database user (DB_USER) can be supplied or defaults to database name
// database pass (DB_PASS) can be supplied or defaults to database user
$config['DB_NAME'] = env($ename . '_NAME', 'ttrss');
$config['DB_USER'] = env($ename . '_USER', $config['DB_NAME']);
$config['DB_PASS'] = env($ename . '_PASS', $config['DB_USER']);
if (!dbcheck($config)) {
echo 'Database login failed, trying to create ...' . PHP_EOL;
// superuser account to create new database and corresponding user account
// username (SU_USER) can be supplied or defaults to "docker"
// password (SU_PASS) can be supplied or defaults to username
$super = $config;
$super['DB_NAME'] = null;
$super['DB_USER'] = env($ename . '_ENV_USER', 'docker');
$super['DB_PASS'] = env($ename . '_ENV_PASS', $super['DB_USER']);
$pdo = dbconnect($super);
$pdo->exec('CREATE ROLE ' . ($config['DB_USER']) . ' WITH LOGIN PASSWORD ' . $pdo->quote($config['DB_PASS']));
$pdo->exec('CREATE DATABASE ' . ($config['DB_NAME']) . ' WITH OWNER ' . ($config['DB_USER']));
unset($pdo);
if (dbcheck($config)) {
echo 'Database login created and confirmed' . PHP_EOL;
} else {
error('Database login failed, trying to create login failed as well');
}
}
$pdo = dbconnect($config);
try {
$pdo->query('SELECT 1 FROM ttrss_feeds');
echo 'Connection to database successful' . PHP_EOL;
// reached this point => table found, assume db is complete
}
catch (PDOException $e) {
echo 'Database table not found, applying schema... ' . PHP_EOL;
$schema = file_get_contents($confpath . 'schema/ttrss_schema_' . $config['DB_TYPE'] . '.sql');
$schema = preg_replace('/--(.*?);/', '', $schema);
$schema = preg_replace('/[\r\n]/', ' ', $schema);
$schema = trim($schema, ' ;');
foreach (explode(';', $schema) as $stm) {
$pdo->exec($stm);
}
unset($pdo);
}
$contents = file_get_contents($conffile);
foreach ($config as $name => $value) {
$contents = preg_replace('/(define\s*\(\'' . $name . '\',\s*)(.*)(\);)/', '$1"' . $value . '"$3', $contents);
}
file_put_contents($conffile, $contents);

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env php
<?php
include '/srv/ttrss-utils.php';
$ename = 'DB';
$eport = 5432;
$confpath = '/var/www/ttrss/config.php';
// check DB_NAME, which will be set automatically for a linked "db" container
if (!env($ename . '_PORT', '')) {
error('The env ' . $ename .'_PORT does not exist. Make sure to run with "--link mypostgresinstance:' . $ename . '"');
}
$config = array();
$config['DB_TYPE'] = 'pgsql';
$config['DB_HOST'] = env($ename . '_PORT_' . $eport . '_TCP_ADDR');
$config['DB_PORT'] = env($ename . '_PORT_' . $eport . '_TCP_PORT');
// database credentials for this instance
// database name (DB_NAME) can be supplied or detaults to "ttrss"
// database user (DB_USER) can be supplied or defaults to database name
// database pass (DB_PASS) can be supplied or defaults to database user
$config['DB_NAME'] = env($ename . '_NAME', 'ttrss');
$config['DB_USER'] = env($ename . '_USER', $config['DB_NAME']);
$config['DB_PASS'] = env($ename . '_PASS', $config['DB_USER']);
$pdo = dbconnect($config);
try {
$pdo->query('SELECT 1 FROM plugin_mobilize_feeds');
// reached this point => table found, assume db is complete
}
catch (PDOException $e) {
echo 'Database table for mobilize plugin not found, applying schema... ' . PHP_EOL;
$schema = file_get_contents('/srv/ttrss-plugin-mobilize.pgsql');
$schema = preg_replace('/--(.*?);/', '', $schema);
$schema = preg_replace('/[\r\n]/', ' ', $schema);
$schema = trim($schema, ' ;');
foreach (explode(';', $schema) as $stm) {
$pdo->exec($stm);
}
unset($pdo);
}
$contents = file_get_contents($confpath);
foreach ($config as $name => $value) {
$contents = preg_replace('/(define\s*\(\'' . $name . '\',\s*)(.*)(\);)/', '$1"' . $value . '"$3', $contents);
}
file_put_contents($confpath, $contents);

View File

@@ -0,0 +1,9 @@
CREATE TABLE "plugin_mobilize_feeds" ( "id" int NOT NULL, "owner_uid" int NOT NULL, "mobilizer_id" int NOT NULL, PRIMARY KEY ("id","owner_uid") );
CREATE TABLE "plugin_mobilize_mobilizers" ( "id" int NOT NULL, "description" varchar(255) NOT NULL, "url" varchar(1000) NOT NULL, PRIMARY KEY ("id") ) ;
INSERT INTO "plugin_mobilize_mobilizers" ( "id", "description", "url") VALUES
(0, 'Readability', 'http://www.readability.com/m?url=%s'),
(1, 'Instapaper', 'http://www.instapaper.com/m?u=%s'),
(2, 'Google Mobilizer', 'http://www.google.com/gwt/x?u=%s'),
(3, 'Original Stripped', 'http://strip=%s'),
(4, 'Original', '%s');

45
root/srv/ttrss-utils.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
function env($name, $default = null)
{
$v = getenv($name) ?: $default;
if ($v === null) {
error('The env ' . $name . ' does not exist');
}
return $v;
}
function error($text)
{
echo 'Error: ' . $text . PHP_EOL;
exit(1);
}
function dbconnect($config)
{
$map = array('host' => 'HOST', 'port' => 'PORT', 'dbname' => 'NAME', 'user' => 'USER', 'password' => 'PASS');
$dsn = $config['DB_TYPE'] . ':';
foreach ($map as $d => $h) {
if (isset($config['DB_' . $h])) {
$dsn .= $d . '=' . $config['DB_' . $h] . ';';
}
}
$pdo = new \PDO($dsn);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
}
function dbcheck($config)
{
try {
dbconnect($config);
return true;
}
catch (PDOException $e) {
return false;
}
}
?>

92
root/srv/update-ttrss.sh Executable file
View File

@@ -0,0 +1,92 @@
#!/bin/sh
set -e
TTRSS_PATH=/var/www/ttrss
update_ttrss()
{
echo "Updating: Tiny Tiny RSS"
( cd ${TTRSS_PATH} && git pull origin HEAD )
if [ -n "$DB_PORT" ]; then
echo "Updating: Database"
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 HEAD )
# Patch ttrss-mobilize plugin for getting it to work.
sed -i -e "s/<?$/<?php/g" ${TTRSS_PATH}/plugins/mobilize/m.php
}
# For use with News+ on Android. Buy the Pro version -- I love it!
update_plugin_newsplus()
{
echo "Updating: News+ plugin"
( cd ${TTRSS_PATH}/plugins/api_newsplus && git pull origin HEAD )
# Link plugin to TTRSS.
ln -f -s ${TTRSS_PATH}/plugins/api_newsplus/api_newsplus/init.php ${TTRSS_PATH}/plugins/api_newsplus/init.php
}
update_plugin_feediron()
{
echo "Updating: FeedIron"
( cd ${TTRSS_PATH}/plugins/feediron && git pull origin HEAD )
}
update_theme_feedly()
{
echo "Updating: Feedly theme"
( cd ${TTRSS_PATH}/themes/feedly-git && git pull origin HEAD )
# Link theme to TTRSS.
ln -f -s ${TTRSS_PATH}/themes/feedly-git/feedly ${TTRSS_PATH}/themes/feedly
ln -f -s ${TTRSS_PATH}/themes/feedly-git/feedly.css ${TTRSS_PATH}/themes/feedly.css
}
update_common()
{
echo "Updating: Updating permissions"
for dir in /etc/nginx /etc/php5 /var/log /var/lib/nginx /tmp /etc/services.d; do
if $(find $dir ! -user $UID -o ! -group $GID | egrep '.' -q); then
echo "Updating: Updating permissions in $dir..."
chown -R $UID:$GID $dir
else
echo "Updating: Permissions in $dir are correct"
fi
done
chown -R www-data:www-data ${TTRSS_PATH}
echo "Updating: updating permissions done"
}
echo "Update: Updating rolling release ..."
echo "Update: Stopping all ..."
update_ttrss
update_plugin_mobilize
update_plugin_newsplus
update_plugin_feediron
update_theme_feedly
update_common
echo "Update: Done."
if [ "$1" != "--no-start" ]; then
echo "Update: Starting all ..."
fi
if [ "$1" = "--wait-exit" ]; then
UPDATE_WAIT_TIME=$2
if [ -z "$UPDATE_WAIT_TIME" ]; then
UPDATE_WAIT_TIME=24h # Default is to check every day (24 hours).
fi
echo "Update: Sleeping for $UPDATE_WAIT_TIME ..."
sleep ${UPDATE_WAIT_TIME}
fi