Filebrowser installation and introduction - Part 1

Table of Contents

General introduction 📚

Filebrowser is a simple software that provides a nice and clean web interface to remotely manage your files from a web browser.

It is written in Go with an embedded VueJS frontend ❤️ . Regarding the database, it uses bbolt which means that your database will be embedded in a single file. Easy to backup, easy to restore.

Filebrowser minimal design makes it easy to install, easy to configure, and easy to host on your own server. All of that without sacrificing the functionalities.

With filebrowser, you can:

  • upload
  • download
  • edit
  • share

your files very easily.

It also allows to create and manage multiple users and isolate them in their own storage space.

Screenshots

filebrowser demo filebrowser demo
filebrowser builtin user login page filebrowser builtin user login page
filebrowser embedded editor filebrowser embedded editor

How to deploy on your own Linux server without Docker 🧑‍🎓

As described in the official install documentation, you can use the docker image filebrowser/filebrowser to easily deploy a filebrowser container.

In this post, we’ll focus on:

  • how to setup filebrowser as a usual systemd service.
  • how to offload TLS functionality to an httpd reverse proxy.
  • how to secure filebrowser access with fail2ban.

Why do I prefer a basic system integration with systemd over a container deployment ?

My home server does not have support for docker or any container runtime.

Step 1: Install filebrowser

This is a simple step. Point your favorite web browser to the filebrowser release page and download the flavor you need.

Extract the binary and install it in /usr/bin/filebrowser

Example:

$ tar xvf linux-amd64-filebrowser.tar.gz
$ sudo mv filebrowser /usr/bin/filebrowser
$ sudo chown root:root /usr/bin/filebrowser
$ sudo chmod 0755 /usr/bin/filebrowser

Step 2: Deploy the configuration and system integration 🚀

We’re in 2022 📅. We don’t want to manually do something. Some tools like ansible are here to help and create an executable documentation of what we did and how. I kinda hate ansible … but for this kind of work it is perfect.

Here are the versions I’ll be using:

$ ansible --version
ansible [core 2.13.2]
  config file = /home/riton/.ansible.cfg
  configured module search path = ['/home/riton/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/riton/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/riton/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/riton/.local/bin/ansible
  python version = 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

As usual when we want to model something, we’ll apply a top to bottom logic. In other words, we’ll start to write the logic that describes the behavior we want, and then progressively go down to the implementation details.

All the pseudo ansible code bellow can be found in the repository: https://github.com/riton/ansible-filebrowser-role.

Ansible step 1: The playbook

 1---
 2- hosts: all
 3  gather_facts: true
 4  become: true
 5
 6  vars:
 7    # Where to store data uploaded to filebrowser
 8    storage_data_dir: '/path/to/filebrowser/root_dir'
 9    sysconfig_options: "SEE THAT LATER"
10
11  tasks:
12    # Do the real system configuration of the filebrowser
13    # service
14    - import_role:
15        name: 'filebrowser'
16
17    - name: 'Configure HTTPd reverse proxy for filebrowser'
18      import_role:
19        name: 'filebrowser'
20        tasks_from: 'reverse_proxy.yml'
21
22    - name: 'Configure fail2ban for filebrowser'
23      import_role:
24        name: 'filebrowser'
25        tasks_from: 'fail2ban.yml'

This is just a sample playbook and you should adapt it to your needs.

The playbook clearly distinguishes the three steps we’ll need to deploy our filebrowser instance:

  1. The filebrowser system integration and configuration (line 14-15)
  2. The reverse proxy configuration (line 19-20)
  3. The final fail2ban integration (line 24-25)

Ansible step 2: Write the base filebrowser role

This role will handle all the filebrowser configuration and system integration.

We’ll start with the creation of a dedicated system user for the service.

  • tasks/main.yaml
  • vars/main.yaml
 1    ---
 2    - name: Create system group
 3      group:
 4        name: '{{ groupname }}'
 5        system: true
 6
 7    - name: Create system user
 8      user:
 9        name: '{{ username }}'
10        comment: 'filebrowser system user'
11        shell: '/bin/false'
12        group: '{{ groupname }}'
13        system: true
14        home: '{{ data_dir }}'
15        createhome: true
16    

The directory /var/lib/filebrowser will be used:

  • as the home directory of the system user filebrowser.
  • to store the database of our filebrowser instance.

Now that we’ve created the system user, we’ll need to create specific directories this user have access to:

  • for the filebrowser log file in /var/log/filebrowser/filebrowser.log.
  • for the filebrowser database file. It should have been pre-created by ansible thanks to the createhome: true parameter.
  • tasks/main.yaml
  • vars/main.yaml
 1    - name: Create directories
 2      file:
 3        path: '{{ item }}'
 4        state: 'directory'
 5        owner: '{{ username }}'
 6        group: '{{ groupname }}'
 7        mode: '0700'
 8      loop:
 9        - '{{ data_dir }}'
10        - '{{ log_dir }}'
11
12    - name: Initialize log file
13      file:
14        path: '{{ log_dir }}/filebrowser.log'
15        state: 'touch'
16        owner: '{{ username }}'
17        group: '{{ groupname }}'
18        mode: '0640'
19    

We simply pre-create an empty /var/log/filebrowser/filebrowser.log file and gives the system user filebrowser full access to that file.


Next, we’ll create a simple sysconfig file that will be used by the systemd unit file to source environment variables.

The sysconfig files default directory is:

  • /etc/sysconfig for Red Hat like operating systems.
  • /etc/default for Debian like operating systems.

I’m using a sysconfig file instead of a configuration file because it’s simpler to create and manage. We only pass the various command-line flags without further modification.

  • tasks/main.yaml
  • vars/main.yaml
  • templates/sysconfig.j2
1    - name: Create sysconfig file
2      template:
3        src: 'sysconfig.j2'
4        dest: '{{ sysconfig_file }}'
5        owner: 'root'
6        group: 'root'
7        mode: '0640'
8    

We define a OPTIONS variable that we’ll later use in our systemd unit file.

Note: We’re here using the variable sysconfig_options that we’ve defined globally in our playbook. This makes it simpler to quickly find the options we’ve used to launch the filebrowser.


The final step is to create our systemd unit file.

This file will be created and managed by ansible, so the /etc/systemd/system directory is more suited than the /usr/lib/systemd/system or the /lib/systemd/system directories.

  • tasks/main.yaml
  • templates/systemd.j2
1    - name: Create systemd service file
2      template:
3        src: 'systemd.j2'
4        dest: '/etc/systemd/system/filebrowser.service'
5        owner: 'root'
6        group: 'root'
7        mode: '0644'
8    

This systemd service unit file can be described as such:

  • the /usr/bin/filebrowser program will be launched as the filebrowser system user and group.
  • the command line arguments passed to the /usr/bin/filebrowser program are contained in the $OPTIONS variable.
  • the file /etc/sysconfig/filebrowser is used to source environment variables and MUST exist. This is where the $OPTIONS variable is initialized.
  • the filebrowser process is isolated from the whole system, except the /var/lib/filebrowser, /var/log/filebrowser and the /path/to/filebrowser/root_dir (from the global playbook variables).
  • the filebrowser process will be started from the /path/to/filebrowser/root_dir directory. filebrowser will write its data to this directory.

💡 All this ansible code can be found at https://github.com/riton/ansible-filebrowser-role.

Conclusion

We’ve seen how to deploy filebrowser on our system and rely on systemd to start and manage the process.

👉 The ansible role does not currently manage the filebrowser service. It is left as an exercise to the reader 🧑‍🎓.

In the next post dedicated to filebrowser, we’ll see a minimalist reverse proxy configuration that can be used to face the Internet and handle all the TLS traffic.

To be continued