Skip to content

Commit ff57fbb

Browse files
committed
Initial commit
0 parents  commit ff57fbb

File tree

11 files changed

+1146
-0
lines changed

11 files changed

+1146
-0
lines changed

Dockerfile

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#Dockerfile.
2+
FROM ubuntu:jammy
3+
4+
ARG DEBIAN_FRONTEND="noninteractive"
5+
6+
ENV SCRIPT_ROOT=/opt/tt-rss
7+
8+
VOLUME /var/www/html
9+
VOLUME ${SCRIPT_ROOT}/config.d
10+
11+
# Install software
12+
RUN apt-get -qq update -y && apt-get -qq upgrade -y && apt-get -qq install git curl sudo -y
13+
RUN apt-get -qq install nginx-core -y
14+
RUN apt-get -qq install php php-fpm php-common php-apcu \
15+
php-gd php-pgsql php-pdo-mysql php-xml php-opcache \
16+
php-mbstring php-intl php-xml php-curl php-tokenizer \
17+
php-json php-zip -y
18+
RUN apt-get -qq install mysql-client rsync tzdata -y
19+
RUN apt-get -qq install supervisor -y
20+
RUN rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
21+
RUN sed -i -e 's/;\(clear_env\) = .*/\1 = no/i' \
22+
-e 's/^\(user\|group\) = .*/\1 = app/i' \
23+
-e 's/;\(php_admin_value\[error_log\]\) = .*/\1 = \/tmp\/error.log/' \
24+
-e 's/;\(php_admin_flag\[log_errors\]\) = .*/\1 = on/' \
25+
/etc/php/8.1/fpm/pool.d/www.conf
26+
RUN mkdir -p ${SCRIPT_ROOT}/config.d /etc/nginx/global /var/www/tt-rss
27+
28+
# Configure Image
29+
COPY app/config.docker.php ${SCRIPT_ROOT}
30+
COPY app/update-feeds.sh ${SCRIPT_ROOT}
31+
RUN chmod 755 ${SCRIPT_ROOT}/update-feeds.sh
32+
33+
COPY config/README.md ${SCRIPT_ROOT}/config.d
34+
COPY config/php.conf /etc/nginx/global
35+
COPY config/restrictions.conf /etc/nginx/global
36+
COPY config/nginx.conf /etc/nginx/sites-enabled/default
37+
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
38+
39+
# forward request and error logs to docker log collector
40+
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
41+
&& ln -sf /dev/stderr /var/log/nginx/error.log \
42+
&& ln -sf /dev/stderr /var/log/php8.1-fpm.log
43+
44+
# HTTP
45+
EXPOSE 80/tcp
46+
47+
# these are applied on every startup, if set
48+
ENV ADMIN_USER_PASS=""
49+
# see classes/UserHelper.php ACCESS_LEVEL_*
50+
# setting this to -2 would effectively disable built-in admin user
51+
# unless single user mode is enabled
52+
ENV ADMIN_USER_ACCESS_LEVEL=""
53+
54+
# these are applied unless user already exists
55+
ENV AUTO_CREATE_USER=""
56+
ENV AUTO_CREATE_USER_PASS=""
57+
ENV AUTO_CREATE_USER_ACCESS_LEVEL="0"
58+
59+
# don't try to update local plugins on startup (except for nginx_xaccel)
60+
ENV TTRSS_NO_STARTUP_PLUGIN_UPDATES=""
61+
62+
ENV TTRSS_DB_TYPE="mysql"
63+
ENV TTRSS_DB_HOST="mysql"
64+
ENV TTRSS_DB_PORT="3306"
65+
66+
ENV TTRSS_MYSQL_CHARSET="UTF8"
67+
ENV TTRSS_PHP_EXECUTABLE="/usr/bin/php"
68+
ENV TTRSS_PLUGINS="auth_internal, note, nginx_xaccel"
69+
70+
ENV TTRSS_FEED_UPDATE_CHECK=900
71+
72+
ENV OWNER_UID=1000
73+
ENV OWNER_GID=1000
74+
75+
ENV PHP_WORKER_MAX_CHILDREN=5
76+
ENV PHP_WORKER_MEMORY_LIMIT=256M
77+
78+
ENV SIMPLE_UPDATE_MODE=false
79+
ENV SINGLE_USER_MODE=false
80+
81+
COPY app/startup.sh /startup.sh
82+
RUN chmod 755 /startup.sh
83+
84+
CMD ["/startup.sh"]
85+
86+
LABEL maintainer="[email protected]"

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# alandoyle/tt-rss-mysql
2+
3+
![Tiny Tiny RSS](https://community.tt-rss.org/uploads/default/optimized/1X/18a2e96275d1fffb21cce225d30a87be4544db60_2_180x180.png)
4+
5+
A simple Tiny Tiny RSS image which only supports MySQL with integrated feed updates.
6+
7+
+ Support MySQL server.
8+
+ Built in Feed updating.
9+
+ Built-in TT-RSS updating.
10+
11+
----
12+
## IMPORTANT NOTES
13+
14+
This Docker image has several assumptions/prerequisites which need to be fulfilled, ignoring them *will* bring failure.
15+
16+
1. This Docker Image is for MySQL _ONLY_.
17+
1. This image is for domains or sub-domains with **/tt-rss/** in the URL. e.g. **http://reader.mydomain.tld**
18+
1. MySQL needs to be installed in a separate Docker container.
19+
1. MySQL needs to be configured and setup **BEFORE** this image is deployed (explained below).
20+
1. If a previous MySQL instance is used and and old TT-RSS instance was using PHP 7.x then a "Data Fix" will need to be applied to the database as this image used PHP 8.1 and generates JSON differently. Failure to "Data Fix" the database could result in duplicate posts appearing in TT-RSS (explained below)
21+
22+
## MySQL Setup
23+
24+
This image _requires_ a database and database user be set up **PRIOR** to bringing up the image.
25+
26+
A new database and user can be created using the _mysql_ command.
27+
28+
e.g. If you're running the MySQL container from the Docker Compose example below you will need to run the following commands to create the database and user.
29+
30+
```bash
31+
docker exec -it <MYSQL_CONTAINER> /bin/bash
32+
```
33+
Once inside the container run the following command to access MySQL.
34+
```bash
35+
mysql -u root -p
36+
```
37+
You will be prompted for the MYSQL_ROOT_PASSWORD (see Docker Compose example)
38+
Once in _mysql_ run the following SQL commands to set up the database and user (see Docker Compose example to match up the values).
39+
```sql
40+
CREATE DATABASE <TTRSS_DB_NAME>;
41+
CREATE USER '<TTRSS_DB_USER>' IDENTIFIED BY '<TTRSS_DB_PASS>';
42+
GRANT ALL ON <TTRSS_DB_NAME>.* TO '<TTRSS_DB_USER>';
43+
FLUSH PRIVILEGES;
44+
\q
45+
```
46+
47+
Now the `tt-rss-mysql` image can be started.
48+
49+
## PHP 7 -> PHP 8 "Data Fix"
50+
51+
**NOTE:** If this is a fresh install of Tiny Tiny RSS then ignore this section.
52+
53+
PHP 7 stores the unique GUID used by each article in the following format:
54+
```
55+
{"ver":2,"uid":"2","hash":"SHA1:2b10b494802dc70e9d9d7676cdef0cf0f9969b78"}
56+
```
57+
58+
PHP 8 stores the unique GUID used by each article in the following format:
59+
```
60+
{"ver":2,"uid":2,"hash":"SHA1:2b10b494802dc70e9d9d7676cdef0cf0f9969b78"}
61+
```
62+
63+
Notice that the "uid" value is quoted with PHP 7 but not PHP 8.
64+
65+
### The fix
66+
To fix a previous MySQL database populated by PHP 7 the following SQL commands need to be used via the _mysql_ commandline tool.
67+
```sql
68+
USE <TTRSS-DATABASE>;
69+
70+
UPDATE ttrss_entries
71+
SET guid = replace(replace(guid,'"uid":"', '"uid":'),'", "hash":', ',"hash":')
72+
WHERE guid LIKE '%"uid":"%"%';
73+
```
74+
----
75+
76+
## Docker
77+
78+
Available on [DockerHub](https://hub.docker.com/r/alandoyle/tt-rss-mysql)
79+
```bash
80+
docker pull alandoyle/tt-rss-mysql
81+
```
82+
83+
## Usage
84+
85+
```bash
86+
docker run --name=tt-rss-mysql \
87+
-d --init \
88+
-v <MY_CONF_PATH>:/opt/tt-rss/config.d\
89+
-v <MY_WEB_PATH>:/var/www/tt-rss\
90+
-p 8000:80/tcp \
91+
alandoyle/tt-rss-mysql:latest
92+
```
93+
94+
Docker compose example:
95+
96+
```yaml
97+
version: "3"
98+
99+
services:
100+
mysql:
101+
image: mysql:8.0
102+
container_name: mysql
103+
restart: unless-stopped
104+
environment:
105+
MYSQL_ROOT_PASSWORD: SecureSecretPassword
106+
volumes:
107+
- ./mysql/data:/var/lib/mysql
108+
tt-rss-mysql:
109+
image: alandoyle/tt-rss-mysql:latest
110+
container_name: tt-rss-mysql
111+
restart: unless-stopped
112+
init: true
113+
ports:
114+
- "8000:80/tcp"
115+
volumes:
116+
- ./tt-rss/web:/var/www/tt-rss
117+
- ./tt-rss/config:/opt/tt-rss/config.d
118+
environment:
119+
TTRSS_SELF_URL_PATH: https://reader.mydomain.tld
120+
TTRSS_DB_HOST: mysql
121+
TTRSS_DB_USER: ttrss_user
122+
TTRSS_DB_NAME: ttrss_database
123+
TTRSS_DB_PASS: ttrss_password
124+
TTRSS_DB_PORT: 3306
125+
TTRSS_FEED_UPDATE_CHECK: 600
126+
```
127+
128+
### Ports
129+
130+
| Port | Description |
131+
|----------|-----------------------|
132+
| `80/tcp` | HTTP |
133+
134+
### Volumes
135+
136+
| Path | Description |
137+
|---------|---------------------------------------|
138+
| `/var/www/tt-rss` | path for tt-rss web files |
139+
| `/opt/tt-rss/config.d` | path for tt-rss configuration files |

app/config.docker.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
$snippets = glob(getenv("SCRIPT_ROOT")."/config.d/*.php");
4+
5+
foreach ($snippets as $snippet) {
6+
require_once $snippet;
7+
}
8+

app/startup.sh

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/sh -e
2+
#
3+
# Based in part on the original TT-RSS Docker startup.sh
4+
#
5+
6+
while ! mysqladmin ping -h $TTRSS_DB_HOST -u $TTRSS_DB_USER -p$TTRSS_DB_PASS; do
7+
echo waiting until $TTRSS_DB_HOST is ready...
8+
sleep 3
9+
done
10+
11+
DST_DIR=/var/www/tt-rss
12+
SRC_REPO=https://git.tt-rss.org/fox/tt-rss.git
13+
14+
# Create the 'app' user
15+
if ! id app >/dev/null 2>&1; then
16+
addgroup --gid $OWNER_GID app
17+
useradd -d /var/www/tt-rss -g app -u $OWNER_UID app
18+
usermod -aG www-data,app app
19+
fi
20+
21+
if [ ! -d $DST_DIR/.git ]; then
22+
mkdir -p $DST_DIR
23+
chown $OWNER_UID:$OWNER_GID $DST_DIR
24+
25+
echo cloning tt-rss source from $SRC_REPO to $DST_DIR...
26+
sudo -u app git clone --depth 1 $SRC_REPO $DST_DIR || echo error: failed to clone master repository.
27+
else
28+
echo updating tt-rss source in $DST_DIR from $SRC_REPO...
29+
30+
chown -R $OWNER_UID:$OWNER_GID $DST_DIR
31+
cd $DST_DIR && \
32+
sudo -u app git config core.filemode false && \
33+
sudo -u app git config pull.rebase false && \
34+
sudo -u app git pull origin master || echo error: unable to update master repository.
35+
fi
36+
37+
update-ca-certificates || true
38+
39+
if [ ! -e $DST_DIR/index.php ]; then
40+
echo "error: tt-rss index.php missing (git clone failed?), unable to continue."
41+
exit 1
42+
fi
43+
44+
if [ ! -d $DST_DIR/plugins.local/nginx_xaccel ]; then
45+
echo cloning plugins.local/nginx_xaccel...
46+
sudo -u app git clone https://git.tt-rss.org/fox/ttrss-nginx-xaccel.git \
47+
$DST_DIR/plugins.local/nginx_xaccel || echo warning: failed to clone nginx_xaccel.
48+
else
49+
if [ -z "$TTRSS_NO_STARTUP_PLUGIN_UPDATES" ]; then
50+
echo updating all local plugins...
51+
52+
find $DST_DIR/plugins.local/ -maxdepth 1 -mindepth 1 -type d | while read PLUGIN; do
53+
if [ -d $PLUGIN/.git ]; then
54+
echo updating $PLUGIN...
55+
56+
cd $PLUGIN && \
57+
sudo -u app git config core.filemode false && \
58+
sudo -u app git config pull.rebase false && \
59+
sudo -u app git pull origin master || echo warning: attempt to update plugin $PLUGIN failed.
60+
fi
61+
done
62+
else
63+
echo updating plugins.local/nginx_xaccel...
64+
65+
cd $DST_DIR/plugins.local/nginx_xaccel && \
66+
sudo -u app git config core.filemode false && \
67+
sudo -u app git config pull.rebase false && \
68+
sudo -u app git pull origin master || echo warning: attempt to update plugin nginx_xaccel failed.
69+
fi
70+
fi
71+
72+
cp ${SCRIPT_ROOT}/config.docker.php $DST_DIR/config.php
73+
chmod 644 $DST_DIR/config.php
74+
75+
for d in cache lock feed-icons; do
76+
chmod 777 $DST_DIR/$d
77+
find $DST_DIR/$d -type f -exec chmod 666 {} \;
78+
done
79+
80+
# Configure PHP
81+
echo "Setting PHP memory_limit to ${PHP_WORKER_MEMORY_LIMIT}"
82+
sed -i.bak "s/^\(memory_limit\) = \(.*\)/\1 = ${PHP_WORKER_MEMORY_LIMIT}/" \
83+
/etc/php/8.1/fpm/php.ini
84+
85+
echo "Setting PHP pm.max_children to ${PHP_WORKER_MAX_CHILDREN}"
86+
sed -i.bak "s/^\(pm.max_children\) = \(.*\)/\1 = ${PHP_WORKER_MAX_CHILDREN}/" \
87+
/etc/php/8.1/fpm/pool.d/www.conf
88+
89+
# Update schema if necessary
90+
sudo -Eu app ${TTRSS_PHP_EXECUTABLE} $DST_DIR/update.php --update-schema=force-yes
91+
92+
if [ ! -z "$ADMIN_USER_PASS" ]; then
93+
sudo -Eu app ${TTRSS_PHP_EXECUTABLE} $DST_DIR/update.php --user-set-password "admin:$ADMIN_USER_PASS"
94+
else
95+
if sudo -Eu app ${TTRSS_PHP_EXECUTABLE} $DST_DIR/update.php --user-check-password "admin:password"; then
96+
RANDOM_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 16 ; echo '')
97+
98+
echo "*****************************************************************************"
99+
echo "* Setting initial built-in admin user password to '$RANDOM_PASS' *"
100+
echo "* If you want to set it manually, use ADMIN_USER_PASS environment variable. *"
101+
echo "*****************************************************************************"
102+
103+
sudo -Eu app ${TTRSS_PHP_EXECUTABLE} $DST_DIR/update.php --user-set-password "admin:$RANDOM_PASS"
104+
fi
105+
fi
106+
107+
if [ ! -z "$ADMIN_USER_ACCESS_LEVEL" ]; then
108+
sudo -Eu app ${TTRSS_PHP_EXECUTABLE} $DST_DIR/update.php --user-set-access-level "admin:$ADMIN_USER_ACCESS_LEVEL"
109+
fi
110+
111+
if [ ! -z "$AUTO_CREATE_USER" ]; then
112+
sudo -Eu app /bin/sh -c "php $DST_DIR/update.php --user-exists $AUTO_CREATE_USER ||
113+
${TTRSS_PHP_EXECUTABLE} $DST_DIR/update.php --force-yes --user-add \"$AUTO_CREATE_USER:$AUTO_CREATE_USER_PASS:$AUTO_CREATE_USER_ACCESS_LEVEL\""
114+
fi
115+
116+
rm -f /tmp/error.log && mkfifo /tmp/error.log && chown app:app /tmp/error.log
117+
118+
(tail -q -f /tmp/error.log >> /proc/1/fd/2) &
119+
120+
unset ADMIN_USER_PASS
121+
unset AUTO_CREATE_USER_PASS
122+
123+
# cleanup any old lockfiles
124+
rm -vf -- /var/www/tt-rss/lock/*.lock
125+
126+
touch $DST_DIR/.app_is_ready
127+
128+
# Run it all :)
129+
echo "Starting daemons for $TTRSS_SELF_URL_PATH"
130+
/usr/bin/supervisord -n -c /etc/supervisor/conf.d/supervisord.conf

app/update-feeds.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash -e
2+
#
3+
# TT-RSS Feed Update script
4+
#
5+
6+
TTRSS_FEED_UPDATE_CHECK=${TTRSS_FEED_UPDATE_CHECK:-900}
7+
sudo -Eu app ${TTRSS_PHP_EXECUTABLE} /var/www/tt-rss/update_daemon2.php --interval=${TTRSS_FEED_UPDATE_CHECK}
8+
exit 0

config/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Put anything else you need included into `config.php` to this directory as separate `.php` files.

0 commit comments

Comments
 (0)