add freshrss playbook

This commit is contained in:
Denis-Cosmin Nutiu 2025-02-17 21:43:05 +02:00
parent 22409efefc
commit 941d924e7b
15 changed files with 382 additions and 0 deletions

164
fresh-rss/.gitignore vendored Normal file
View file

@ -0,0 +1,164 @@
# Created by https://www.gitignore.io/api/macos,python,ansible
# Edit at https://www.gitignore.io/?templates=macos,python,ansible
### Ansible ###
*.retry
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that dont work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Downloaded files
root@*
# End of https://www.gitignore.io/api/macos,python,ansible

8
fresh-rss/.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

17
fresh-rss/.idea/fresh-rss.iml generated Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.13 (fresh-rss)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/templates" />
</list>
</option>
</component>
</module>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
fresh-rss/.idea/misc.xml generated Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.13 (fresh-rss)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (fresh-rss)" project-jdk-type="Python SDK" />
</project>

8
fresh-rss/.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/fresh-rss.iml" filepath="$PROJECT_DIR$/.idea/fresh-rss.iml" />
</modules>
</component>
</project>

6
fresh-rss/.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

9
fresh-rss/Makefile Normal file
View file

@ -0,0 +1,9 @@
install:
sudo dnf install ansible
ansible-galaxy collection install community.general
ansible-galaxy collection install containers.podman
ansible-galaxy collection install ansible.posix
list-hosts:
ansible-inventory -i inventory.ini --list
run:
ansible-playbook -i inventory.ini playbook.yaml --ask-become-pass

5
fresh-rss/inventory.ini Normal file
View file

@ -0,0 +1,5 @@
[nuculabs]
my-linux.box ansible_user=ansible
[local]
localhost

100
fresh-rss/playbook.yaml Normal file
View file

@ -0,0 +1,100 @@
- name: Install FreshRSS
hosts: nuculabs
become: true
become_method: sudo
vars_files:
- variables.yaml
tasks:
# Create necessary directories.
- name: "Create directories"
block:
- name: Create base directory
ansible.builtin.file:
path: "{{ fresh_rss.base_directory }}"
state: directory
mode: "0755"
ignore_errors: true
- name: Create data directory
ansible.builtin.file:
path: "{{ fresh_rss.base_directory }}/{{ fresh_rss.data_directory }}"
state: directory
mode: "0755"
ignore_errors: true
- name: Create extensions directory
ansible.builtin.file:
path: "{{ fresh_rss.base_directory }}/{{ fresh_rss.extensions_directory }}"
state: directory
mode: "0755"
ignore_errors: true
- name: Setup SELinux
block:
- name: Ensure Udica is installed
ansible.builtin.package:
name: udica
state: present
- name: Ensure container-selinux is installed
ansible.builtin.package:
name: container-selinux
state: present
- name: Copy freshrss cil
ansible.builtin.copy:
src: ./templates/selinux/freshrss.cil
dest: /tmp/freshrss.cil
mode: "0644"
- name: Load freshrss CIL policy
ansible.builtin.command:
argv:
- semodule
- -i
- /tmp/freshrss.cil
- /usr/share/udica/templates/base_container.cil
- /usr/share/udica/templates/net_container.cil
when: setup_selinux
- name: Setup Container
block:
- name: Ensure Podman is installed
ansible.builtin.package:
name: podman
state: present
- name: Pull image
containers.podman.podman_image:
name: "{{ fresh_rss.container_image }}"
state: present
- name: "Copy container"
ansible.builtin.template:
src: ./templates/container/freshrss.container.j2
dest: /etc/containers/systemd/freshrss.container
mode: "0644"
- name: Reload systemd
ansible.builtin.command:
cmd: systemctl daemon-reload
- name: Stop service
ansible.builtin.systemd_service:
name: freshrss.service
state: stopped
enabled: true
- name: Enable service
ansible.builtin.systemd_service:
name: freshrss.service
state: started
enabled: true
- name: Setup firewall
block:
- name: Create firewalld service
ansible.builtin.template:
src: ./templates/firewall/freshrss.xml.j2
dest: /etc/firewalld/services/freshrss.xml
mode: "0644"
- name: Reload firewalld
ansible.builtin.command:
argv:
- firewall-cmd
- --reload
- name: Enable firewalld service
ansible.posix.firewalld:
service: freshrss
state: enabled
permanent: true
immediate: true
offline: true
when: setup_firewall

9
fresh-rss/readme.md Normal file
View file

@ -0,0 +1,9 @@
# Self Hosted FreshRSS server
This playbook allows you to self-host a FreshRSS sever with podman containers and systemd Quadlets.
It was tested on Fedora 41.
References:
- https://github.com/FreshRSS/FreshRSS/tree/edge
- https://github.com/FreshRSS/FreshRSS/tree/edge/Docker

View file

@ -0,0 +1,20 @@
[Unit]
Description=freshrss
[Container]
Image={{ fresh_rss.container_image }}
AutoUpdate=registry
PublishPort={{ fresh_rss.port }}:80/tcp
Volume={{ fresh_rss.base_directory }}/{{ fresh_rss.data_directory }}:/var/www/FreshRSS/data:Z
Volume={{ fresh_rss.base_directory }}/{{ fresh_rss.extensions_directory }}:/var/www/FreshRSS/extensions:Z
Environment=CRON_MIN={{ fresh_rss.cron_min }}
SecurityLabelType=freshrss.process
[Service]
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>FreshRSS Service</short>
<description>A free, self-hostable news aggregator.</description>
<port protocol="tcp" port="{{ fresh_rss.port }}" />
</service>

View file

@ -0,0 +1,8 @@
(block freshrss
(blockinherit container)
(blockinherit restricted_net_container)
(allow process default_t (dir (setattr add_name write create)))
(allow process default_t (file (create)))
(allow process http_port_t (tcp_socket (name_bind)))
)

9
fresh-rss/variables.yaml Normal file
View file

@ -0,0 +1,9 @@
setup_selinux: true
setup_firewall: true # exposes the firewall ports
fresh_rss:
port: 8080
cron_min: "*,45"
container_image: "docker.io/freshrss/freshrss:1.25.0"
base_directory: "/fresh_rss"
data_directory: "data"
extensions_directory: "extensions"