diff options
| -rw-r--r-- | Docker/.env | 25 | ||||
| -rw-r--r-- | Docker/.gitignore | 1 | ||||
| -rw-r--r-- | Docker/README.md | 598 | ||||
| -rw-r--r-- | Docker/docker-compose.yml | 35 | ||||
| -rw-r--r-- | Docker/freshrss/docker-compose-db.yml | 21 | ||||
| -rw-r--r-- | Docker/freshrss/docker-compose-development.yml | 7 | ||||
| -rw-r--r-- | Docker/freshrss/docker-compose-local.yml | 7 | ||||
| -rw-r--r-- | Docker/freshrss/docker-compose-proxy.yml | 57 | ||||
| -rw-r--r-- | Docker/freshrss/docker-compose.yml | 22 | ||||
| -rw-r--r-- | Docker/freshrss/example.env | 38 | ||||
| -rw-r--r-- | Docker/freshrss/traefik/tls.yml | 15 |
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 @@  - -  # 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 |
