How to Secure a Self-Hosted Docmost Server
Learn how to secure your self-hosted Docmost server by configuring SSH key authentication, disabling root and password-based logins, enabling UFW, installing Fail2ban, and configuring automatic security updates.

Deploying Docmost is only the first step. Once your server is publicly accessible, it becomes a target for automated bots that continuously scan for exposed services, weak SSH configurations, and other common security vulnerabilities.
A production deployment requires more than Docker and HTTPS. Securing the underlying Linux server is essential to protect your application, reduce the attack surface, and help prevent unauthorized access.
In this article, you'll secure your Docmost server by configuring SSH key authentication, disabling root and password-based logins, enabling a firewall with UFW, installing Fail2ban, and configuring automatic security updates.
Note: This article assumes you have already deployed Docmost by following the deployment article and are logged in as the non-root user created during the installation.
Prerequisites
Before you begin, make sure you have the following:
A Running Docmost Deployment: Complete the deployment by following the previous guide before proceeding with this article.
A Non-Root User with Sudo Privileges: This article assumes you are logged in as the non-root user created during the deployment.
SSH Access to the Server: You'll need SSH access to apply the security configurations and verify the changes.
Step 1: Configure SSH Key Authentication
SSH key authentication is more secure than password-based authentication because it uses a cryptographic key pair to verify your identity. Instead of entering a password each time you connect, your local machine uses a private key that matches a public key stored on the server. This significantly reduces the risk of brute-force attacks against your SSH service.
- Generate a new SSH key on your local machine:
ssh-keygen -t ed25519 -C "docmost-server"
The command generates a public and private SSH key pair. By default, the keys are stored in the ~/.ssh directory.
- Display the public key:
cat ~/.ssh/id_ed25519.pub
Copy the entire output.
💡
Note: The following commands should be executed while logged in as the non-root user created during the deployment. Do not perform these steps as the root user. The SSH public key should be added to the non-root user's account because it will be used for all future server administration.
- On the server, create the SSH directory if it doesn't already exist:
mkdir -p ~/.ssh
- Create the
authorized_keysfile:
nano ~/.ssh/authorized_keys
Paste the public key you copied earlier, save the file, and exit the editor.
- Set the correct permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
- Verify the permissions:
ls -la ~/.ssh
You should see output similar to:
drwx------ 2 USERNAME USERNAME 4096 Jun 25 10:00 .ssh
-rw------- 1 USERNAME USERNAME 104 Jun 25 10:01 authorized_keys
- Open a new terminal on your local machine and verify that you can connect to the server using SSH:
ssh USERNAME@SERVER_IP
Replace:
USERNAMEwith the non-root username created during the deployment.SERVER_IPwith your server's public IP address.
If you're able to log in successfully, SSH key authentication has been configured correctly. Verify that you're logged in before proceeding to the next step.
Step 2: Disable Root Login
Many Linux servers allow the root user to log in over SSH. Since the root account has unrestricted access to the system, it is a common target for automated login attempts. Disabling root login forces administrators to authenticate using a non-root user with sudo privileges, reducing the risk of unauthorized access.
Important: Before proceeding, verify that you can successfully log in to the server using the non-root user and the SSH key configured in the previous step. Disabling root login without verifying SSH key authentication may prevent you from accessing the server.
- Open the SSH server configuration file:
sudo nano /etc/ssh/sshd_config
- Locate the following directive:
PermitRootLogin yes
Update it to:
PermitRootLogin no
Save the file and exit the editor.
- Validate the SSH configuration:
sudo sshd -t
If the command produces no output, the configuration is valid.
- Reload the SSH service to apply the changes:
sudo systemctl reload ssh
- Open a new terminal on your local machine and verify that you can no longer log in as the
rootuser:
ssh root@SERVER_IP
Replace:
SERVER_IPwith your server's public IP address.
- You should see a permission denied message similar to:
Permission denied, please try again.
This confirms that direct SSH access for the root user has been disabled successfully.
Step 3: Disable Password Authentication
Now that SSH key authentication is working correctly, you can disable password-based authentication. This prevents attackers from attempting to guess account passwords through brute-force attacks, allowing only users with an authorized SSH key to access the server.
Important: Before disabling password authentication, verify that you can successfully log in to the server using the SSH key configured in the previous step. If SSH key authentication is not working, you may lose access to the server.
Open the SSH server configuration file:
sudo nano /etc/ssh/sshd_config
Locate the following directive:
#PasswordAuthentication yes
Update it to:
PasswordAuthentication no
Also verify that the following directive is enabled:
PubkeyAuthentication yes
Save the file and exit the editor.
Validate the SSH configuration:
sudo sshd -t
If the command produces no output, the configuration is valid.
Reload the SSH service to apply the changes:
sudo systemctl reload ssh
Verify the active SSH configuration:
sudo sshd -T | grep passwordauthentication
You should see output similar to:
passwordauthentication no
Troubleshooting: If the command still returns
passwordauthentication yes, check for additional SSH configuration files under/etc/ssh/sshd_config.d/that may override the setting. Some Ubuntu cloud images managed by cloud-init include a file such as50-cloud-init.confwithPasswordAuthentication yes. Update the overriding file toPasswordAuthentication no, reload the SSH service, and verify the configuration again.
Open a new terminal and verify that you can still log in using your SSH key:
ssh USERNAME@SERVER_IP
Replace:
USERNAMEwith the non-root username created during the deployment.SERVER_IPwith your server's public IP address.
If you're able to log in successfully without entering the server account password, password-based authentication has been disabled successfully.
Step 4: Configure the UFW Firewall
By default, a server can expose services to the internet that do not need to be publicly accessible. A firewall helps reduce the attack surface by blocking all incoming traffic except the ports required for your application. For a typical Docmost deployment with Traefik, only SSH, HTTP, and HTTPS should be accessible.
Configure the default firewall policies:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow SSH connections:
sudo ufw allow OpenSSH
Allow HTTP and HTTPS traffic:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Enable the firewall:
sudo ufw enable
When prompted, enter:
y
to continue.
Verify the firewall configuration:
sudo ufw status verbose
You should see output similar to:
Status: active
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
The firewall is now configured to allow only SSH, HTTP, and HTTPS traffic while blocking all other incoming connections. This reduces the server's attack surface by preventing access to ports that are not required for your deployment.
Step 5: Install and Configure Fail2ban
Even after disabling root login and password-based authentication, your server will continue to receive automated SSH login attempts. Fail2ban helps protect against these attacks by monitoring authentication logs and automatically banning IP addresses that repeatedly fail to authenticate.
Update the package index:
sudo apt update
Install Fail2ban:
sudo apt install fail2ban -y
Verify that the service is running:
sudo systemctl status fail2ban
You should see output similar to:
Active: active (running)
View the list of active jails:
sudo fail2ban-client status
You should see output similar to:
Status
|- Number of jail: 1
`- Jail list: sshd
View the status of the SSH jail:
sudo fail2ban-client status sshd
You should see output similar to:
Status for the jail: sshd
|- Filter
| |- Currently failed: 33
| |- Total failed: 63
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 2
|- Total banned: 2
`- Banned IP list: 92.207.4.157 150.5.131.119
The output confirms that Fail2ban is actively monitoring SSH login attempts and automatically blocking IP addresses that repeatedly fail authentication. This provides an additional layer of protection against automated brute-force attacks targeting your server.
Step 6: Enable Automatic Security Updates
Keeping your server up to date is an important part of maintaining a secure deployment. Ubuntu provides the unattended-upgrades package, which automatically installs security updates in the background, helping protect your server against newly discovered vulnerabilities.
Install the unattended-upgrades package:
sudo apt install unattended-upgrades -y
Enable automatic security updates:
sudo dpkg-reconfigure --priority=low unattended-upgrades
When prompted, select:
Yes
and press Enter.
Verify that the service is running:
sudo systemctl status unattended-upgrades
You should see output similar to:
Active: active (running)
With automatic security updates enabled, Ubuntu will automatically install security patches, helping keep your server protected without requiring manual intervention.
Conclusion
In this article, you secured your Docmost server by configuring SSH key authentication, disabling root and password-based logins, enabling a firewall with UFW, installing Fail2ban, and enabling automatic security updates.
These security measures provide a strong foundation for running Docmost in a production environment and help protect your server against common threats such as unauthorized access and brute-force attacks.
As you continue self-hosting applications, regularly review your server configuration, apply security updates, and monitor your system to keep your deployment secure.



