aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docker/.env25
-rw-r--r--Docker/.gitignore1
-rw-r--r--Docker/README.md598
-rw-r--r--Docker/docker-compose.yml35
-rw-r--r--Docker/freshrss/docker-compose-db.yml21
-rw-r--r--Docker/freshrss/docker-compose-development.yml7
-rw-r--r--Docker/freshrss/docker-compose-local.yml7
-rw-r--r--Docker/freshrss/docker-compose-proxy.yml57
-rw-r--r--Docker/freshrss/docker-compose.yml22
-rw-r--r--Docker/freshrss/example.env38
-rw-r--r--Docker/freshrss/traefik/tls.yml15
11 files changed, 533 insertions, 293 deletions
diff --git a/Docker/.env b/Docker/.env
deleted file mode 100644
index 2b7a46618..000000000
--- a/Docker/.env
+++ /dev/null
@@ -1,25 +0,0 @@
-# Environment file for docker-compose
-# In this file you need to define the different settings
-
-
-# ====================================
-# Database
-# ====================================
-
-
-# Database to use for freshrss
-POSTGRES_DB=freshrss
-
-# User in the freshrss database
-POSTGRES_USER=freshrss
-
-# Password for the defined user
-POSTGRES_PASSWORD=freshrss
-
-
-# ====================================
-# FreshRSS
-# ====================================
-
-# Exposed port for the docker-container
-EXPOSED_PORT=8080 \ No newline at end of file
diff --git a/Docker/.gitignore b/Docker/.gitignore
index 7a7d633f1..f490a6cfa 100644
--- a/Docker/.gitignore
+++ b/Docker/.gitignore
@@ -1 +1,2 @@
env.txt
+.env
diff --git a/Docker/README.md b/Docker/README.md
index 9f12e65d5..6ff62d250 100644
--- a/Docker/README.md
+++ b/Docker/README.md
@@ -1,135 +1,98 @@
![Docker Cloud Automated build](https://img.shields.io/docker/cloud/automated/freshrss/freshrss.svg)
-![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/freshrss/freshrss.svg)
-![MicroBadger Size](https://img.shields.io/microbadger/image-size/freshrss/freshrss.svg)
![Docker Pulls](https://img.shields.io/docker/pulls/freshrss/freshrss.svg)
# Deploy FreshRSS with Docker
-* See also <https://hub.docker.com/r/freshrss/freshrss/>
-
+Our official images are available on [Docker Hub](https://hub.docker.com/r/freshrss/freshrss/).
## Install Docker
-```sh
-curl -fsSL https://get.docker.com/ -o get-docker.sh
-sh get-docker.sh
-```
+See <https://docs.docker.com/get-docker/>
-
-## Create an isolated network
+Example for Linux Debian / Ubuntu:
```sh
-docker network create freshrss-network
+# Install default Docker Compose and automatically the corresponding version of Docker
+apt install docker-compose
```
-## Recommended: use [Træfik](https://traefik.io/) reverse proxy
+## Quick run
-It is a good idea to use a reverse proxy on your host server, providing HTTPS.
-Here is the recommended configuration using automatic [Let’s Encrypt](https://letsencrypt.org/) HTTPS certificates and with a redirection from HTTP to HTTPS. See further below for alternatives.
+Example running FreshRSS (or scroll down to the [Docker Compose](#docker-compose) section instead):
```sh
-docker volume create traefik-letsencrypt
-docker volume create traefik-tmp
-
-# Just change your e-mail address in the command below:
docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v traefik-letsencrypt:/etc/traefik/acme \
- -v traefik-tmp:/tmp \
- -v /var/run/docker.sock:/var/run/docker.sock:ro \
- --net freshrss-network \
- -p 80:80 \
- -p 443:443 \
- --name traefik traefik:1.7 --docker \
- --loglevel=info \
- --entryPoints='Name:http Address::80 Compress:true Redirect.EntryPoint:https' \
- --entryPoints='Name:https Address::443 Compress:true TLS TLS.MinVersion:VersionTLS12 TLS.SniStrict:true TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA' \
- --defaultentrypoints=http,https --keeptrailingslash=true \
- --acme=true --acme.entrypoint=https --acme.onhostrule=true --acme.tlsChallenge \
- --acme.storage=/etc/traefik/acme/acme.json --acme.email=you@example.net
+ -p 8080:80 \
+ -e TZ=Europe/Paris \
+ -e 'CRON_MIN=1,31' \
+ -v freshrss_data:/var/www/FreshRSS/data \
+ --name freshrss \
+ freshrss/freshrss
```
-See [more information about Docker and Let’s Encrypt in Træfik](https://docs.traefik.io/user-guide/docker-and-lets-encrypt/).
+* Exposing on port 8080
+* With a [server timezone](http://php.net/timezones) (default is `UTC`)
+* With an automatic cron job to refresh feeds
+* Saving FreshRSS data in a Docker volume `freshrss_data`
+* Using the default image, which is the latest stable release
+### Complete installation
-## Run FreshRSS
+Browse to your server <https://freshrss.example.net/> to complete the installation via the FreshRSS Web interface,
+or use the command line described below.
-Example using the built-in refresh cron job (see further below for alternatives).
-You must first chose a domain (DNS) or sub-domain, e.g. `freshrss.example.net`.
+## Command line
-> **N.B.:** Default images are for x64 (Intel, AMD) platforms. For ARM (e.g. Raspberry Pi), use the `*-arm` tags. For other platforms, see the section *Build Docker image* further below.
+See the [CLI documentation](../cli/README.md) for all the commands, which can be applied like:
```sh
-docker volume create freshrss-data
-docker volume create freshrss-extensions
-
-# Remember to replace freshrss.example.net by your server address in the command below:
-docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v freshrss-data:/var/www/FreshRSS/data \
- -v freshrss-extensions:/var/www/FreshRSS/extensions \
- -e 'CRON_MIN=4,34' \
- -e TZ=Europe/Paris \
- --net freshrss-network \
- --label traefik.port=80 \
- --label traefik.frontend.rule='Host:freshrss.example.net' \
- --label traefik.frontend.headers.forceSTSHeader=true \
- --label traefik.frontend.headers.STSSeconds=31536000 \
- --name freshrss freshrss/freshrss
+docker exec --user www-data freshrss cli/list-users.php
```
-* Replace `TZ=Europe/Paris` by your [server timezone](http://php.net/timezones), or remove the line to use `UTC`.
-* If you cannot have FreshRSS at the root of a dedicated domain, update the command above according to the following model:
- `--label traefik.frontend.rule='Host:freshrss.example.net;PathPrefixStrip:/FreshRSS/' \`
-* You may remove the `--label traefik.*` lines if you do not use Træfik.
-* Add `-p 8080:80 \` if you want to expose FreshRSS locally, e.g. on port `8080`.
-* Replace `freshrss/freshrss` by a more specific tag (see below) such as `freshrss/freshrss:edge` for the development version, or `freshrss/freshrss:arm` for a Raspberry Pi version.
-
-This already works with a built-in **SQLite** database (easiest), but more powerful databases are supported:
-
-### [MySQL](https://hub.docker.com/_/mysql/) or [MariaDB](https://hub.docker.com/_/mariadb)
+Example of installation via command line:
```sh
-# If you already have a MySQL or MariaDB instance running, just attach it to the FreshRSS network:
-docker network connect freshrss-network mysql
+docker exec --user www-data freshrss cli/do-install.php --default_user freshrss
-# Otherwise, start a new MySQL instance, remembering to change the passwords:
-docker volume create mysql-data
-docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v mysql-data:/var/lib/mysql \
- -e MYSQL_ROOT_PASSWORD=rootpass \
- -e MYSQL_DATABASE=freshrss \
- -e MYSQL_USER=freshrss \
- -e MYSQL_PASSWORD=pass \
- --net freshrss-network \
- --name mysql mysql
+docker exec --user www-data freshrss cli/create-user.php --user freshrss --password freshrss
```
-### [PostgreSQL](https://hub.docker.com/_/postgres/)
+> ℹ️ You have to replace `--user www-data` by `--user apache` when using our images based on Linux Alpine.
-```sh
-# If you already have a PostgreSQL instance running, just attach it to the FreshRSS network:
-docker network connect freshrss-network postgres
+## Our Docker image variants
-# Otherwise, start a new PostgreSQL instance, remembering to change the passwords:
-docker volume create pgsql-data
-docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v pgsql-data:/var/lib/postgresql/data \
- -e POSTGRES_DB=freshrss \
- -e POSTGRES_USER=freshrss \
- -e POSTGRES_PASSWORD=pass \
- --net freshrss-network \
- --name postgres postgres
-```
+The [tags](https://hub.docker.com/r/freshrss/freshrss/tags) correspond to FreshRSS branches and versions:
-### Complete installation
+* `:latest` (default) is the [latest stable release](https://github.com/FreshRSS/FreshRSS/releases/latest)
+* `:edge` is the rolling release, same than our [git `edge` branch](https://github.com/FreshRSS/FreshRSS/tree/edge)
+* `:x.y.z` are [specific FreshRSS releases](https://github.com/FreshRSS/FreshRSS/releases)
+* `:arm` or `:*-arm` are the ARM `arm32v7` versions (e.g., for Raspberry Pi).
+ * For other platforms, see the [custom build section](#build-custom-docker-image)
-Browse to your server <https://freshrss.example.net/> to complete the installation via the FreshRSS Web interface,
-or use the command line described below.
+### Linux: Debian vs. Alpine
+
+Our default image is based on [Debian](https://www.debian.org/). We offer an alternative based on [Alpine](https://alpinelinux.org/) (with the `:alpine` or `*-alpine` tag suffix).
+In [our tests](https://github.com/FreshRSS/FreshRSS/pull/2205) (2019), Alpine was slower,
+while Alpine is smaller on disk (and much faster to build),
+and with newer packages in general (Apache, PHP).
+
+> ℹ️ For some rare systems, one variant might work but not the other, for instance due to kernel incompatibilities.
+
+## Environment variables
+* `TZ`: (default is `UTC`) A [server timezone](http://php.net/timezones) (default is `UTC`)
+* `CRON_MIN`: (default is disabled) Define minutes for the built-in cron job to automatically refresh feeds (see below for more advanced options)
+* `FRESHRSS_ENV`: (default is `production`) Enables additional development information if set to `development` (increases the level of logging and ensures that errors are displayed) (see below for more development options)
+* `COPY_LOG_TO_SYSLOG`: (default is `On`) Copy all the logs to syslog
+* `COPY_SYSLOG_TO_STDERR`: (default is `On`) Copy syslog to Standard Error so that it is visible in docker logs
+* `LISTEN`: (default is `0.0.0.0:80`) Modifies the internal Apache listening port, e.g. `0.0.0.0:8080` (for advanced users; useful for [Docker host networking](https://docs.docker.com/network/host/))
+* `FRESHRSS_INSTALL`: automatically pass arguments to command line `cli/do-install.php` (for advanced users; see example in Docker Compose section). Only executed at the very first run (so far), so if you make any change, you need to delete your `freshrss` service, `freshrss_data` volume, before running again.
+* `FRESHRSS_USER`: automatically pass arguments to command line `cli/create-user.php` (for advanced users; see example in Docker Compose section). Only executed at the very first run (so far), so if you make any change, you need to delete your `freshrss` service, `freshrss_data` volume, before running again.
## How to update
```sh
-# Rebuild an image (see build section above) or get a new online version:
+# Rebuild an image (see build section below) or get a new online version:
docker pull freshrss/freshrss
# And then
docker stop freshrss
@@ -140,163 +103,112 @@ docker run ... --name freshrss freshrss/freshrss
docker rm freshrss_old
```
+## Build custom Docker image
-## [Docker tags](https://hub.docker.com/r/freshrss/freshrss/tags)
-
-The tags correspond to FreshRSS branches and versions:
-
-* `:latest` (default) is the latest stable release
-* `:edge` is the rolling release
-* `:x.y.z` are specific FreshRSS releases
-* `:arm` or `:*-arm` are the ARM versions (e.g. for Raspberry Pi)
-
-### Linux: Debian vs. Alpine
-
-Our default image is based on [Debian](https://www.debian.org/). We offer an alternative based on [Alpine](https://alpinelinux.org/) (with the `*-alpine` tag suffix).
-In [our tests](https://github.com/FreshRSS/FreshRSS/pull/2205), Alpine is slower,
-while Alpine is [smaller on disk](https://hub.docker.com/r/freshrss/freshrss/tags) (and much faster to build).
-
-
-## Optional: Build Docker image of FreshRSS
-
-Building your own Docker image is optional because online images can be fetched automatically.
-Note that prebuilt images are less recent and only available for x64 (Intel, AMD) platforms.
+Building your own Docker image is especially relevant for platforms not available on our Docker Hub,
+which is currently limited to `x64` (Intel, AMD) and `arm32v7`.
```sh
# First time only
git clone https://github.com/FreshRSS/FreshRSS.git
cd FreshRSS/
-git pull
-docker build --pull --tag freshrss/freshrss -f Docker/Dockerfile .
-```
-
-
-## Command line
-
-```sh
-docker exec --user www-data -it freshrss php ./cli/list-users.php
+git pull --ff-only --prune
+docker build --pull --tag freshrss/freshrss:custom -f Docker/Dockerfile .
```
-See the [CLI documentation](../cli/) for all the other commands.
-You might have to replace `--user www-data` by `--user apache` when using our images based on Linux Alpine.
-
+## Development mode
-## Debugging
+To contribute to FreshRSS development, you can use one of the Docker images to run and serve the PHP code,
+while reading the source code from your local (git) directory, like the following example:
```sh
-# See FreshRSS data if you use Docker volume
-docker volume inspect freshrss-data
-sudo ls /var/lib/docker/volumes/freshrss-data/_data/
-
-# See Web server logs
-docker logs -f freshrss
-
-# Enter inside FreshRSS docker container
-docker exec -it freshrss sh
-## See FreshRSS root inside the container
-ls /var/www/FreshRSS/
+cd ./FreshRSS/
+docker run --rm \
+ -p 8080:80 \
+ -e FRESHRSS_ENV=development \
+ -e TZ=Europe/Paris \
+ -e 'CRON_MIN=1,31' \
+ -v $(pwd):/var/www/FreshRSS \
+ -v freshrss_data:/var/www/FreshRSS/data \
+ --name freshrss \
+ freshrss/freshrss:edge
```
+This will start a server on port 8080, based on your local PHP code, which will show the logs directly in your terminal.
+Press <kbd>Control</kbd>+<kbd>C</kbd> to exit.
-## Cron job to automatically refresh feeds
+### Special development images
-We recommend a refresh rate of about twice per hour (see *WebSub* / *PubSubHubbub* for real-time updates).
-There are no less than 3 options. Pick a single one.
+> ℹ️ See the [custom build section](#build-custom-docker-image) for an introduction
-### Option 1) Cron inside the FreshRSS Docker image
-
-Easiest, built-in solution, also used already in the examples above
-(but your Docker instance will have a second process in the background, without monitoring).
-Just pass the environment variable `CRON_MIN` to your `docker run` command,
-containing a valid cron minute definition such as `'13,43'` (recommended) or `'*/20'`.
-Not passing the `CRON_MIN` environment variable – or setting it to empty string – will disable the cron daemon.
+Two special Dockerfile are provided to reproduce the oldest and newest supported platforms (based on Alpine Linux).
+They need to be compiled manually:
```sh
-docker run ... \
- -e 'CRON_MIN=13,43' \
- --name freshrss freshrss/freshrss
+cd ./FreshRSS/
+docker build --pull --tag freshrss/freshrss:oldest -f Docker/Dockerfile-Oldest .
+docker build --pull --tag freshrss/freshrss:newest -f Docker/Dockerfile-Newest .
```
-### Option 2) Cron on the host machine
+## Supported databases
-Traditional solution.
-Set a cron job up on your host machine, calling the `actualize_script.php` inside the FreshRSS Docker instance.
-Remember not pass the `CRON_MIN` environment variable to your Docker run, to avoid running the built-in cron daemon of option 1.
+FreshRSS has a built-in [**SQLite** database](https://sqlite.org/) (easiest and good performance), but more powerful databases are also supported:
-Example on Debian / Ubuntu: Create `/etc/cron.d/FreshRSS` with:
+### Create an isolated network
-```text
-7,37 * * * * root docker exec --user www-data freshrss php ./app/actualize_script.php > /tmp/FreshRSS.log 2>&1
+```sh
+docker network create freshrss-network
+# Run FreshRSS with a `--net freshrss-network` parameter or use the following command:
+docker network connect freshrss-network freshrss
```
-### Option 3) Cron as another instance of the same FreshRSS Docker image
-
-For advanced users. Offers good logging and monitoring with auto-restart on failure.
-Watch out to use the same run parameters than in your main FreshRSS instance, for database, networking, and file system.
-See cron option 1 for customising the cron schedule.
-
-#### For the Debian image (default)
+### [PostgreSQL](https://hub.docker.com/_/postgres/)
```sh
+# If you already have a PostgreSQL instance running, just attach it to the FreshRSS network:
+docker network connect freshrss-network postgres
+
+# Otherwise, start a new PostgreSQL instance, remembering to change the passwords:
docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v freshrss-data:/var/www/FreshRSS/data \
- -v freshrss-extensions:/var/www/FreshRSS/extensions \
- -e 'CRON_MIN=17,47' \
+ -v pgsql_data:/var/lib/postgresql/data \
+ -e POSTGRES_DB=freshrss \
+ -e POSTGRES_USER=freshrss \
+ -e POSTGRES_PASSWORD=freshrss \
--net freshrss-network \
- --name freshrss_cron freshrss/freshrss \
- cron -f
+ --name freshrss-db postgres
```
-#### For the Debian image (default) using a custom cron.d fragment
+In the FreshRSS setup, you will then specify the name of the container (`freshrss-db`) as the host for the database.
-This method gives you the most flexibility most flexiblity to
-execute various freshrss cli commands.
+### [MySQL](https://hub.docker.com/_/mysql/) or [MariaDB](https://hub.docker.com/_/mariadb)
```sh
-docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v freshrss-data:/var/www/FreshRSS/data \
- -v freshrss-extensions:/var/www/FreshRSS/extensions \
- -v ./freshrss_crontab:/etc/cron.d/freshrss \
- --net freshrss-network \
- --name freshrss_cron freshrss/freshrss \
- cron -f
-```
-
-#### For the Alpine image
+# If you already have a MySQL or MariaDB instance running, just attach it to the FreshRSS network:
+docker network connect freshrss-network mysql
-```sh
+# Otherwise, start a new MySQL instance, remembering to change the passwords:
docker run -d --restart unless-stopped --log-opt max-size=10m \
- -v freshrss-data:/var/www/FreshRSS/data \
- -v freshrss-extensions:/var/www/FreshRSS/extensions \
- -e 'CRON_MIN=27,57' \
+ -v mysql_data:/var/lib/mysql \
+ -e MYSQL_ROOT_PASSWORD=rootpass \
+ -e MYSQL_DATABASE=freshrss \
+ -e MYSQL_USER=freshrss \
+ -e MYSQL_PASSWORD=freshrss \
--net freshrss-network \
- --name freshrss_cron freshrss/freshrss:alpine \
- crond -f -d 6
+ --name freshrss-db mysql \
+ --default-authentication-plugin=mysql_native_password
```
-## Development mode
+> ℹ️ The parameter `--default-authentication-plugin` is not needed if using PHP 8+ (which is the case for our Alpine images but not yet for our Debian images).
-To contribute to FreshRSS development, you can use one of the Docker images to run and serve the PHP code,
-while reading the source code from your local (git) directory, like the following example:
-
-```sh
-cd /path-to-local/FreshRSS/
-docker run --rm -p 8080:80 -e TZ=Europe/Paris -e FRESHRSS_ENV=development \
- -v $(pwd):/var/www/FreshRSS \
- freshrss/freshrss:edge
-```
-
-This will start a server on port 8080, based on your local PHP code, which will show the logs directly in your terminal.
-Press <kbd>Control</kbd>+<kbd>c</kbd> to exit.
-
-The `FRESHRSS_ENV=development` environment variable increases the level of logging and ensures that errors are displayed.
+In the FreshRSS setup, you will then specify the name of the container (`freshrss-db`) as the host for the database.
## More deployment options
### Custom Apache configuration (advanced users)
-Changes in Apache `.htaccess` files are applied when restarting the container.
+The FreshRSS Docker image uses the [Web server Apache](https://httpd.apache.org/) internally.
+Changes in [Apache `.htaccess` files](https://httpd.apache.org/docs/trunk/howto/htaccess.html) are applied when restarting the container.
In particular, if you want FreshRSS to use HTTP-based login (instead of the easier Web form login), you can mount your own `./FreshRSS/p/i/.htaccess`:
```sh
@@ -316,35 +228,198 @@ AuthType Basic
Require valid-user
```
-### Example with [docker-compose](https://docs.docker.com/compose/)
+### Modify the configuration of a running FreshRSS instance
-A [docker-compose.yml](docker-compose.yml) file is given as an example, using PostgreSQL. In order to use it, you have to adapt:
+Some FreshRSS configuration parameters are stored in [`./FreshRSS/data/config.php`](../config.default.php)
+(e.g. `base_url`, `'environment' => 'development'`, database parameters, cURL options, etc.)
+and the following procedure can be used to modify them:
-* In the `postgresql` service:
- * `container_name` directive. Whatever you set this to will be the value you put in the "Host" field during the "Database Configuration" step of installation;
- * the `volumes` section. Be careful to keep the path `/var/lib/postgresql/data` for the container. If the path is wrong, you will not get any error but your db will be gone at the next run;
- * the `POSTGRES_PASSWORD` in the `.env` file;
- * the `POSTGRES_DB` in the `.env` file;
- * the `POSTGRES_USER` in the `.env` file;
-* In the `freshrss` service:
- * the `volumes` section;
- * options under the `labels` section are specific to [Træfik](https://traefik.io/), a reverse proxy. If you are not using it, feel free to delete this section. If you are using it, adapt accordingly to your config, especially the `traefik.frontend.rule` option.
- * the `environment` section to adapt the strategy to update feeds.
- * the `EXPOSED_PORT` variable in the `.env` file;
+```sh
+# Verify the name of your FreshRSS volume, typically `freshrss_data`
+docker volume ls
+# Verify the path of your FreshRSS volume, typically `/var/lib/docker/volumes/freshrss_data/`
+docker volume inspect freshrss_data
+# Then edit your configuration file
+sudo nano /var/lib/docker/volumes/freshrss_data/_data/config.php
+```
-If you don’t want to use the `.env` file you can also directly edit the `docker-compose.yml` file. It’s highly recommended to change the password. If you don’t change it, it will use the default option.
+## Docker Compose
+
+First, put variables such as passwords in your `.env` file (see [`example.env`](./freshrss/example.env)):
+
+```ini
+ADMIN_EMAIL=admin@example.net
+ADMIN_PASSWORD=freshrss
+ADMIN_API_PASSWORD=freshrss
+# Published port if running locally
+PUBLISHED_PORT=8080
+# Database credentials (not relevant if using default SQLite database)
+DB_HOST=freshrss-db
+DB_BASE=freshrss
+DB_PASSWORD=freshrss
+DB_USER=freshrss
+```
-You can then launch the stack (FreshRSS + PostgreSQL) with:
+See [`docker-compose.yml`](./freshrss/docker-compose.yml)
```sh
-docker-compose up -d
+cd ./FreshRSS/Docker/freshrss/
+# Update
+docker-compose pull
+# Run
+docker-compose -f docker-compose.yml -f docker-compose-local.yml up -d --remove-orphans
+# Logs
+docker-compose logs -f --timestamps
+# Stop
+docker-compose down --remove-orphans
+```
+
+Detailed (partial) example of Docker Compose for FreshRSS:
+
+```yaml
+version: "2.4"
+
+volumes:
+ data:
+ extensions:
+
+services:
+ freshrss:
+ image: freshrss/freshrss:edge
+ container_name: freshrss
+ restart: unless-stopped
+ logging:
+ options:
+ max-size: 10m
+ volumes:
+ - data:/var/www/FreshRSS/data
+ - extensions:/var/www/FreshRSS/extensions
+ ports:
+ # If you want to open a port 8080 on the local machine:
+ - "8080:80"
+ environment:
+ TZ: Europe/Paris
+ CRON_MIN: '2,32'
+ FRESHRSS_ENV: development
+ # Optional advanced parameter controlling the internal Apache listening port
+ LISTEN: 0.0.0.0:80
+ # Optional auto-install parameters (the Web interface install is recommended instead):
+ # ⚠️ Parameters below are only used at the very first run (so far).
+ # So if changes are made (or in .env file), first delete the service and volumes.
+ # ℹ️ All the --db-* parameters can be omitted if using built-in SQLite database.
+ FRESHRSS_INSTALL: |-
+ --api_enabled
+ --base_url ${BASE_URL}
+ --db-base ${DB_BASE}
+ --db-host ${DB_HOST}
+ --db-password ${DB_PASSWORD}
+ --db-type pgsql
+ --db-user ${DB_USER}
+ --default_user admin
+ --language en
+ FRESHRSS_USER: |-
+ --api_password ${ADMIN_API_PASSWORD}
+ --email ${ADMIN_EMAIL}
+ --language en
+ --password ${ADMIN_PASSWORD}
+ --user admin
```
-### Alternative reverse proxy using [nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
+### Docker Compose with PostgreSQL
+
+Example including a [PostgreSQL](https://www.postgresql.org/) database.
+
+See [`docker-compose-db.yml`](./freshrss/docker-compose-db.yml)
+
+```sh
+cd ./FreshRSS/Docker/freshrss/
+# Update
+docker-compose -f docker-compose.yml -f docker-compose-db.yml pull
+# Run
+docker-compose -f docker-compose.yml -f docker-compose-db.yml -f docker-compose-local.yml up -d --remove-orphans
+# Logs
+docker-compose -f docker-compose.yml -f docker-compose-db.yml logs -f --timestamps
+```
+
+### Docker Compose for development
+
+Use the local (git) FreshRSS source code instead of the one inside the Docker container,
+to avoid having to rebuild/restart at each change in the source code.
+
+See [`docker-compose-development.yml`](./freshrss/docker-compose-development.yml)
+
+```sh
+cd ./FreshRSS/Docker/freshrss/
+# Update
+git pull --ff-only --prune
+docker-compose pull
+# Run
+docker-compose -f docker-compose-development.yml -f docker-compose.yml -f docker-compose-local.yml up --remove-orphans
+# Stop with [Control]+[C] and purge
+docker-compose down --remove-orphans --volumes
+```
+
+> ℹ️ You can combine it with `-f docker-compose-db.yml` to spin a PostgreSQL database.
+
+## Run in production
+
+For production, it is a good idea to use a reverse proxy on your host server, providing HTTPS.
+A dedicated solution such as [Træfik](https://traefik.io/traefik/) is recommended
+(or see [alternative options below](#alternative-reverse-proxy-configurations)).
+
+You must first chose a domain (DNS) or sub-domain, e.g. `freshrss.example.net`, and set it in your `.env` file:
+
+```ini
+SERVER_DNS=freshrss.example.net
+```
+
+### Use [Træfik](https://traefik.io/traefik/) reverse proxy
+
+Here is the recommended configuration using automatic [Let’s Encrypt](https://letsencrypt.org/) HTTPS certificates and with a redirection from HTTP to HTTPS.
+
+See [`docker-compose-proxy.yml`](./freshrss/docker-compose-proxy.yml)
+
+```sh
+cd ./FreshRSS/Docker/freshrss/
+# Update
+docker-compose -f docker-compose.yml -f docker-compose-proxy.yml pull
+# Run
+docker-compose -f docker-compose.yml -f docker-compose-proxy.yml up -d --remove-orphans
+# Logs
+docker-compose -f docker-compose.yml -f docker-compose-proxy.yml logs -f --timestamps
+# Stop
+docker-compose -f docker-compose.yml -f docker-compose-proxy.yml down --remove-orphans
+```
+
+> ℹ️ You can combine it with `-f docker-compose-db.yml` to spin a PostgreSQL database.
+
+See [more information about Docker and Let’s Encrypt in Træfik](https://doc.traefik.io/traefik/https/acme/).
+
+## Alternative reverse proxy configurations
+
+### Alternative reverse proxy using Apache
+
+Here is an example of a configuration file for running FreshRSS behind an [Apache 2.4 reverse proxy](https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html) (as a subdirectory).
+You need a working SSL configuration and the Apache modules `proxy`, `proxy_http` and `headers` installed (depends on your distribution) and enabled (`a2enmod proxy proxy_http headers`).
+
+```apache
+ProxyPreserveHost On
+
+<Location /freshrss/>
+ ProxyPass http://127.0.0.1:8080/
+ ProxyPassReverse http://127.0.0.1:8080/
+ RequestHeader set X-Forwarded-Prefix "/freshrss"
+ RequestHeader set X-Forwarded-Proto "https"
+ Require all granted
+ Options none
+</Location>
+```
+
+### Alternative reverse proxy using nginx
#### Hosted in a subdirectory
-Here is an example of configuration to run FreshRSS behind an Nginx reverse proxy (as subdirectory).
+Here is an example of configuration to run FreshRSS behind an [nginx reverse proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) (as subdirectory).
```nginx
upstream freshrss {
@@ -437,20 +512,77 @@ server {
}
```
-### Alternative reverse proxy using [Apache 2.4](https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html)
+## Cron job to automatically refresh feeds
-Here is an example of a configuration file for running FreshRSS behind an Apache reverse proxy (as a subdirectory).
-You need a working SSL configuration and the Apache modules `proxy`, `proxy_http` and `headers` installed (depends on your distribution) and enabled (```a2enmod proxy proxy_http headers```).
+We recommend a refresh rate of about twice per hour (see *WebSub* / *PubSubHubbub* for real-time updates).
+There are no less than 3 options. Pick a single one.
-```apache
-ProxyPreserveHost On
+### Option 1) Cron inside the FreshRSS Docker image
-<Location /freshrss/>
- ProxyPass http://127.0.0.1:8080/
- ProxyPassReverse http://127.0.0.1:8080/
- RequestHeader set X-Forwarded-Prefix "/freshrss"
- RequestHeader set X-Forwarded-Proto "https"
- Require all granted
- Options none
-</Location>
+Easiest, built-in solution, also used already in the examples above
+(but your Docker instance will have a second process in the background, without monitoring).
+Just pass the environment variable `CRON_MIN` to your `docker run` command,
+containing a valid cron minute definition such as `'13,43'` (recommended) or `'*/20'`.
+Not passing the `CRON_MIN` environment variable – or setting it to empty string – will disable the cron daemon.
+
+```sh
+docker run ... \
+ -e 'CRON_MIN=13,43' \
+ --name freshrss freshrss/freshrss
+```
+
+### Option 2) Cron on the host machine
+
+Traditional solution.
+Set a cron job up on your host machine, calling the `actualize_script.php` inside the FreshRSS Docker instance.
+Remember not pass the `CRON_MIN` environment variable to your Docker run, to avoid running the built-in cron daemon of option 1.
+
+Example on Debian / Ubuntu: Create `/etc/cron.d/FreshRSS` with:
+
+```text
+7,37 * * * * root docker exec --user www-data freshrss php ./app/actualize_script.php > /tmp/FreshRSS.log 2>&1
+```
+
+### Option 3) Cron as another instance of the same FreshRSS Docker image
+
+For advanced users. Offers good logging and monitoring with auto-restart on failure.
+Watch out to use the same run parameters than in your main FreshRSS instance, for database, networking, and file system.
+See cron option 1 for customising the cron schedule.
+
+#### For the Debian image (default)
+
+```sh
+docker run -d --restart unless-stopped --log-opt max-size=10m \
+ -v freshrss_data:/var/www/FreshRSS/data \
+ -v freshrss_extensions:/var/www/FreshRSS/extensions \
+ -e 'CRON_MIN=17,47' \
+ --net freshrss-network \
+ --name freshrss_cron freshrss/freshrss \
+ cron -f
+```
+
+#### For the Debian image (default) using a custom cron.d fragment
+
+This method gives most flexibility to execute various FreshRSS CLI commands.
+
+```sh
+docker run -d --restart unless-stopped --log-opt max-size=10m \
+ -v freshrss_data:/var/www/FreshRSS/data \
+ -v freshrss_extensions:/var/www/FreshRSS/extensions \
+ -v ./freshrss_crontab:/etc/cron.d/freshrss \
+ --net freshrss-network \
+ --name freshrss_cron freshrss/freshrss \
+ cron -f
+```
+
+#### For the Alpine image
+
+```sh
+docker run -d --restart unless-stopped --log-opt max-size=10m \
+ -v freshrss_data:/var/www/FreshRSS/data \
+ -v freshrss_extensions:/var/www/FreshRSS/extensions \
+ -e 'CRON_MIN=27,57' \
+ --net freshrss-network \
+ --name freshrss_cron freshrss/freshrss:alpine \
+ crond -f -d 6
```
diff --git a/Docker/docker-compose.yml b/Docker/docker-compose.yml
deleted file mode 100644
index 1f93a80cf..000000000
--- a/Docker/docker-compose.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-version: "3"
-
-services:
- freshrss-db:
- image: postgres:12-alpine
- container_name: freshrss-db
- hostname: freshrss-db
- restart: unless-stopped
- volumes:
- - db:/var/lib/postgresql/data
- environment:
- POSTGRES_USER: ${POSTGRES_USER:-freshrss}
- POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-freshrss}
- POSTGRES_DB: ${POSTGRES_DB:-freshrss}
-
- freshrss-app:
- image: freshrss/freshrss:latest
- container_name: freshrss-app
- hostname: freshrss-app
- restart: unless-stopped
- ports:
- - "${EXPOSED_PORT:-8080}:80"
- depends_on:
- - freshrss-db
- volumes:
- - data:/var/www/FreshRSS/data
- - extensions:/var/www/FreshRSS/extensions
- environment:
- CRON_MIN: '*/20'
- TZ: Europe/Paris
-
-volumes:
- db:
- data:
- extensions:
diff --git a/Docker/freshrss/docker-compose-db.yml b/Docker/freshrss/docker-compose-db.yml
new file mode 100644
index 000000000..b845947b6
--- /dev/null
+++ b/Docker/freshrss/docker-compose-db.yml
@@ -0,0 +1,21 @@
+version: "2.4"
+
+volumes:
+ db:
+
+services:
+
+ freshrss-db:
+ image: postgres:14
+ container_name: freshrss-db
+ hostname: freshrss-db
+ restart: unless-stopped
+ logging:
+ options:
+ max-size: 10m
+ volumes:
+ - db:/var/lib/postgresql/data
+ environment:
+ POSTGRES_DB: ${DB_BASE:-freshrss}
+ POSTGRES_USER: ${DB_USER:-freshrss}
+ POSTGRES_PASSWORD: ${DB_PASSWORD:-freshrss}
diff --git a/Docker/freshrss/docker-compose-development.yml b/Docker/freshrss/docker-compose-development.yml
new file mode 100644
index 000000000..db0bbc099
--- /dev/null
+++ b/Docker/freshrss/docker-compose-development.yml
@@ -0,0 +1,7 @@
+version: "2.4"
+
+services:
+
+ freshrss:
+ volumes:
+ - ../..:/var/www/FreshRSS
diff --git a/Docker/freshrss/docker-compose-local.yml b/Docker/freshrss/docker-compose-local.yml
new file mode 100644
index 000000000..989c3c617
--- /dev/null
+++ b/Docker/freshrss/docker-compose-local.yml
@@ -0,0 +1,7 @@
+version: "2.4"
+
+services:
+
+ freshrss:
+ ports:
+ - "${PUBLISHED_PORT:-8080}:${LISTEN:-80}"
diff --git a/Docker/freshrss/docker-compose-proxy.yml b/Docker/freshrss/docker-compose-proxy.yml
new file mode 100644
index 000000000..980e45e67
--- /dev/null
+++ b/Docker/freshrss/docker-compose-proxy.yml
@@ -0,0 +1,57 @@
+version: "2.4"
+
+volumes:
+ traefik-letsencrypt:
+ traefik-tmp:
+
+services:
+
+ traefik:
+ image: traefik:2.6
+ container_name: traefik
+ restart: unless-stopped
+ logging:
+ options:
+ max-size: 10m
+ ports:
+ - 80:80
+ - 443:443
+ networks:
+ - network
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - traefik-tmp:/tmp
+ - traefik-letsencrypt:/etc/traefik/acme
+ - ./traefik/tls.yaml:/etc/traefik/tls.yaml:ro
+ command:
+ - --global.sendAnonymousUsage
+ - --accesslog=true
+ - --api=false
+ - --providers.docker=true
+ - --providers.docker.exposedByDefault=false
+ - --log.level=INFO
+ - --entryPoints.http.address=:80
+ - --entryPoints.https.address=:443
+ - --entryPoints.http.http.redirections.entryPoint.to=https
+ - --entryPoints.http.http.redirections.entryPoint.scheme=https
+ - --certificatesResolvers.letsEncrypt.acme.storage=/etc/traefik/acme/acme.json
+ - --certificatesResolvers.letsEncrypt.acme.email=${ADMIN_EMAIL}
+ - --certificatesResolvers.letsEncrypt.acme.tlsChallenge=true
+ - --providers.file.filename=/etc/traefik/tls.yaml
+ labels:
+ - traefik.enable=false
+
+ freshrss:
+ labels:
+ - traefik.enable=true
+ - traefik.http.middlewares.freshrssM1.compress=true
+ - traefik.http.middlewares.freshrssM2.headers.browserXssFilter=true
+ - traefik.http.middlewares.freshrssM2.headers.forceSTSHeader=true
+ - traefik.http.middlewares.freshrssM2.headers.frameDeny=true
+ - traefik.http.middlewares.freshrssM2.headers.referrerPolicy=no-referrer-when-downgrade
+ - traefik.http.middlewares.freshrssM2.headers.stsSeconds=31536000
+ - traefik.http.routers.freshrss.entryPoints=https
+ - traefik.http.routers.freshrss.middlewares=freshrssM1,freshrssM2
+ - traefik.http.routers.freshrss.rule=Host(`${SERVER_DNS}`)
+ - traefik.http.routers.freshrss.tls.certResolver=letsEncrypt
+ - traefik.http.routers.freshrss.tls=true
diff --git a/Docker/freshrss/docker-compose.yml b/Docker/freshrss/docker-compose.yml
new file mode 100644
index 000000000..075e8d503
--- /dev/null
+++ b/Docker/freshrss/docker-compose.yml
@@ -0,0 +1,22 @@
+version: "2.4"
+
+volumes:
+ data:
+ extensions:
+
+services:
+
+ freshrss:
+ image: freshrss/freshrss
+ container_name: freshrss
+ hostname: freshrss
+ restart: unless-stopped
+ logging:
+ options:
+ max-size: 10m
+ volumes:
+ - data:/var/www/FreshRSS/data
+ - extensions:/var/www/FreshRSS/extensions
+ environment:
+ TZ: Europe/Paris
+ CRON_MIN: '3,33'
diff --git a/Docker/freshrss/example.env b/Docker/freshrss/example.env
new file mode 100644
index 000000000..d40cd775c
--- /dev/null
+++ b/Docker/freshrss/example.env
@@ -0,0 +1,38 @@
+# Example of environment file for docker-compose
+# Copy this file into your own `.env` file
+
+# ================================
+# FreshRSS
+# ================================
+
+ADMIN_EMAIL=admin@example.net
+
+# Published port for development or local use (optional)
+PUBLISHED_PORT=8080
+
+# =========================================
+# For automatic FreshRSS install (optional)
+# =========================================
+
+ADMIN_PASSWORD=freshrss
+ADMIN_API_PASSWORD=freshrss
+
+# Address at which the FreshRSS instance will be reachable:
+BASE_URL=https://freshrss.example.net
+
+# Database server (not relevant if using default SQLite)
+# Use the name of the Docker container if running on the same machine
+DB_HOST=freshrss-db
+
+# ===========================================================
+# Database credentials (not relevant if using default SQLite)
+# ===========================================================
+
+# Database to use
+DB_BASE=freshrss
+
+# User in the freshrss database
+DB_USER=freshrss
+
+# Password for the defined user
+DB_PASSWORD=freshrss
diff --git a/Docker/freshrss/traefik/tls.yml b/Docker/freshrss/traefik/tls.yml
new file mode 100644
index 000000000..8a01f9e6d
--- /dev/null
+++ b/Docker/freshrss/traefik/tls.yml
@@ -0,0 +1,15 @@
+tls:
+ options:
+ default:
+ minVersion: VersionTLS12
+ sniStrict: true
+ cipherSuites:
+ - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
+ - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
+ - TLS_AES_128_GCM_SHA256
+ - TLS_AES_256_GCM_SHA384
+ - TLS_CHACHA20_POLY1305_SHA256