An easily deployed server based on Docker compose, complete with privacy tools, a media center, cloud storage, and much more.
Currently it is designed with Fedora Server in mind with SELinux set to enforcing. The Flotilla is protected by Suricata, an intrusion prevention system.
There are a handful of different configurations available. alpha
is the
overarching one which contains nearly all services. devops
is oriented for
production of solely code. Others may be created at a later time.
Simply run ./flotilla install [alpha | devops]
to install Flotilla. From now
on you may access Flotilla's commands from all contexts (flotilla status
, no
more ./
)
If you have NAS storage, you can symlink /opt/flotilla/data
to the mount point.
Credentials are stored in /opt/flotilla/secrets.env
, a template exists in the
root of this repository. Fill it out so that docker containers may read them.
Unfortunately many containers have yet to accept the standard Secrets feature recently added in Docker.
Docker will complain with this error on some versions of Fedora:
ERROR: for CONTAINER_NAME Cannot start service CONTAINER_NAME: open /dev/dma_heap: permission denied
As of writing Fedora 33 has an SELinux issue where /dev/dma_heap/
gets labeled
incorrectly. Follow these commands to fix it:
sudo setenforce 0
# Check it with:
# ls -aZ /dev/dma*
sudo chcon -t device_t /dev/dma_heap
sudo setenforce 1
Some special manual actions are currently are necessary to get a handful of services running.
The entire swarm is defended by Suricata, an Intrusion Prevention System (IPS) which runs on the host and intercepts malicious packets before they make contact with containers (or any other service on the host). Suricata automatically updates rules using a cron job which is performed daily.
Suricata requires some IPTables rules to intercept these packets, so be warned that while these rules are enabled, Suricata must also be online; otherwise, no data will pass, and any connections (e.g., SSH) will be terminated.
The IPS may be handled via the flotilla ips
subcommands.
If you have issues, check that /etc/sysconfig/suricata
is using the -q 0
option so that it can execute in inline (IPS) mode and intercept packets! It
must also be running in repeat mode (with masks), or else it will skip all
other filters (effectively making your firewall useless).
FirewallD is used to intelligently manage IPTables. It will not manage Docker services due to it's independent firewall, and it does not manage Suricata.
Firewall commands are accessible via flotilla fw
subcommands.
All that should be required other than tweaking the docker-compose
file is
adding /opt/flotilla/config/letsencrypt/nginx/.htpasswd
:
# The -C <level> is for bcrypt, you can make it stronger by increasing it up to 17.
htpasswd -B -C 10 -c .htpasswd <user> # Then fill in the password prompt.
# For additional users:
htpasswd -B .htpasswd <user> # Then fill in the password prompt.
qBittorrent's web panel is restricted to local-only access. It's default
username and password are admin
and adminadmin
respectively. It's
recommended you log in and change them (Tools > Options > Web UI) if you
don't bypass the login with whitelisted IP's.
In order for this to work using Sonarr et. al., under Tools > Options > Downloads
set Default Save Path to /data
. Set Monitored Folder to /torrents
.
It's recommened you enable Anonymous mode under Tools > Options > BitTorrent, and optionally bump up your queueing and enable not counting slow torrent.
Leave the fixed port (6881
) alone, it will break otherwise.
Enable Advanced Settings, then under Settings > Indexers add a Torznab entry with at least these settings:
Name: Jackett All
Enable RSS Sync: Yes
Enable Search: Yes
URL: http://jackett:9117
API Path: /torznab/all/api
API Key: <Get this from the Jackett web terminal>
This should track all available indexes in Jackett.
Then under Settings > Download Client, add an entry with at least these settings:
Name: Flotilla qBittorrent
Enable: Yes
Host: cleanroom
Port: 8800
Username: admin # Unless changed.
Password: adminadmin # Unless changed.
Use SSL: No
Connect your download client folder under Settings > Download Client > Remote Path Mappings by filling in these settings:
Host: cleanroom
Remote Path: /data/
Local Path: /data/
When you add a new {Series,Movie,Song}
, you'll want to set the path it gets
placed in to {/tv/,/movies/,/music/}
respectively.
If this is exposed to the internet, you'll likely want to add authentication as well, which is configurable under Settings > General > Security. You'll likely also want to turn some quality settings down since they start on unlimited.
Add Libraries for the following internal, shared volumes:
/data/tvshows
as TV Shows from Sonarr/data/movies
as Movies from Radarr/data/music
as Music from Lidarr/data/books
as Books from Calibre?/data/photos
as Photos from various uploads
If you see an endlessly spinning circle on the webpage, clear your browser cache for the page.
Optionally enable hardware accelerated transcoding under Dashboard > Playback > Transcoding, VAAPI-enabled devices should already be mounted into the Jellyfin container.
Login with the email and password you specified in the config files.
Click Add New Server and fill out:
[General]
Name: Flotilla Postgres
[Connection]
Host name/address: postgres
Password: <POSTGRES_PASSWORD from secrets.env>
Save Password: true
The user ID must be 1000
in order to share the key files from letsencrypt.
For security, each user is restricted to a table in pg_hba.conf
, you will have
to add new users under there.
Create a database for Nextcloud inside of Postgres:
CREATE USER nextcloud WITH PASSWORD 'password';
CREATE DATABASE nextcloud TEMPLATE template0 ENCODING 'UNICODE';
ALTER DATABASE nextcloud OWNER TO nextcloud;
GRANT ALL PRIVILEGES ON DATABASE nextcloud TO nextcloud;
password
should match the one provided for POSTGRES_PASS
in
secrets.env
.
Any extra domains must be added to config/nextcloud/config.php
in addition to
a few extra settings like so:
'trusted_proxies' =>
array (
0 => 'letsencrypt',
),
'trusted_domains' =>
array (
0 => 'cloud.maxocull.com',
1 => 'cloud.maxocull.net',
),
'overwriteprotocol' => "https",
'overwritehost' => "cloud.maxocull.com",
'overwrite.cli.url' => 'https://cloud.maxocull.com/',
Create a database for Gitlab inside of Postgres:
CREATE ROLE gitlab with LOGIN CREATEDB PASSWORD 'password';
CREATE DATABASE gitlabhq_production;
GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production to gitlab;
password
should match the one provided for DB_PASS
in
secrets.env
. This use should have permission to create databases, but he does
not have to be superuser. Afterward, create the pg_trgm
extension on the
database with the superuser (who should be postgres
).
Since the host will be using port 22, this container will share it by creating a
git
user on the host and SSH tunnelling into the Docker network's Gitlab
instance. This requires symlinking manually copying SSH keys from the
container volume bind mount into the local git
user's .ssh
folder. See
here
for more details. It must be manually copied because of SELinux permissions;
container security contexts may not mix with sshd
contexts of a different user.
The Gitlab Runner must be connected to the Gitlab instance. Paste the key from
the web UI into the REGISTRATION_TOKEN
environment variable.
Gitlab must also connect to a Docker registry to host Docker images. This shares the letsencrypt certificates to make API calls.
TODO: Automate this procedure. TODO: Automate update of SSH keys, possibly with inotify/crond/incrontab.
Any services you add which contact an API will require the hostname of the Docker container and their port listed. As an example, for qBittorrent you would enter:
URL: cleanroom:8800
Username: admin # Unless changed.
Password: adminadmin # Unless changed.
Some configuration options should be set.
- Config > Interface > Access Control: Set a WebServer login
- Config > Interface > Startup: Enable API
- Config > Interface > Appearance: Set to
flatly
- Config > Interface > OPDS Server: Enable, require credentials, leave credentials empty, enable metadata
- Config > Downloaders > Torrents: Enable qBittorrent,
cleanroom:8800
,admin
andadminadmin
(unless changed),/downloads
- Config > Providers > Torznab Providers: Name it
Jackett All
, enable,http://jackett:9117/torznab/all
, enter the API key from the Jackett webpage - Config > Providers > Direct Download Providers: You may have to change the mirror (
libgen.pw
,gen.lib.rus.ec
, ...), set one to usesearch.php
and the otherforeignfiction/index.php
, enable Z-Library as well withb-ok.cc
- Config > Processing > Calibre: Set the
calibredb
import program to/usr/bin/calibredb
Setup LazyLibrarian first to generate a databse. Otherwise, you must manually
generate a metadata.db file and upload it to /books
using Calibre desktop. It
is unfortunate that the main project does not support automatically generating
this file.
At the setup menu, enter these values:
Location of Calibre databse: /books
Enable uploading: true
Use Calibre's ebook converter: true
Path to convertertool: /usr/bin/ebook-convert
Location of Unrar binary: /usr/bin/unrar
The default login is admin
and admin123
. Change these.
Mayan needs a database, create one in our existing Postgres DB. First make a
user mayan
with the password you specified ($MAYAN_DATABASE_PASSWORD
), then
make a database named mayan
owned by the mayan
user.
If after first run it doesn't provide a web dialog with a password, the
initialization failed. Try again by running: docker-compose exec mayan /opt/mayan-edms/bin/mayan-edms.py initialsetup
.
Configure the email account:
Label: maxocull.com Gmail
Default: true
Enabled: true
Host: smtp.gmail.com
Port: 587
Use TLS: true
Use SSL: false
Username: maxocull.com
Password: <Gmail password, does not need an app password, should match $SMTP_PASSWORD>
From: max.ocull@gmail.com
You'll need to touch this file:
touch /opt/flotilla/config/kimai/local.yaml:
Create a database for Greenlight inside of Postgres:
CREATE USER greenlight WITH PASSWORD 'password';
CREATE DATABASE greenlight_production;
ALTER DATABASE greenlight_production OWNER TO greenlight;
GRANT ALL PRIVILEGES ON DATABASE greenlight_production TO greenlight;
password
should match the one provided for DB_PASSWORD
in
secrets.env
.
You'll need to generate secret keys for BBB and Greenlight and place them in secrets.env
.
Fedora does not load the wireguard module by default. To load it on boot,
create a file at /etc/modules-load.d/wireguard.conf
with contents:
wireguard
Then run sudo modprobe wireguard
to load it without rebooting.
TODO: Document config process.
- NordVPN router
- Switching to Deluge
- Set Jackett to use VPN rather than proxy
- Shadowsocks proxy server through the VPN (does this gain me anything?)
- Matomo/Piwik for analytics
- A TOR node, then hosting an onion site
- An IRC server