How To Install Apache Subversion on Ubuntu 26.04 LTS

Install Apache Subversion on Ubuntu 26.04

Many teams still rely on Apache Subversion for centralized version control, especially in regulated enterprise environments where atomic commits and path-level access control matter more than Git’s distributed model. Setting up a fresh SVN server on modern Ubuntu can feel confusing because documentation mixes old package names, unclear permission models, and Apache HTTP Server assumptions that don’t apply to every use case. This guide walks you through how to install Apache Subversion on Ubuntu 26.04 LTS with real-world sysadmin experience, covering APT installation, repository creation, Apache WebDAV configuration, user authentication with htpasswd, firewall rules, and a verified first commit. By the end, you will have a fully working SVN server served over HTTP with secured access and tested functionality.

Prerequisites

Before you begin the installation, make sure your environment meets these requirements:

  • Operating system: Ubuntu 26.04 LTS server (bare metal, VM, or cloud VPS) [web:7665]
  • User account: A non-root user with sudo privileges
  • Minimum hardware: 1 vCPU, 1 GB RAM, 10 GB disk for a small team repository [web:7657]
  • Network access: SSH access to your server and outbound internet access for APT
  • Open ports: TCP 80 (HTTP) or 443 (HTTPS) for Apache WebDAV access
  • Basic knowledge: Comfortable with the Linux terminal and editing text files
  • Hostname or IP: Static IP address or a hostname pointed at your server’s public IP

You need sudo privileges because installing packages, creating system users, configuring Apache, and managing services all require elevated permissions. Running these commands as root directly is a security anti-pattern that exposes your system to unnecessary risk.

What Is Apache Subversion (SVN)?

Apache Subversion (SVN) is a centralized version control system managed by the Apache Software Foundation. Unlike Git, which gives every developer a full copy of the repository history, SVN maintains a single authoritative server where all commits are stored. Developers check out working copies, make changes locally, and commit back to the central server.

Key concepts you need to understand before starting:

  • Repository: The central database that stores all file versions and revision history
  • Working copy: A local directory containing checked-out files that you edit before committing
  • Revision: A numbered snapshot of the entire repository after each commit
  • Trunk/branches/tags: Standard directory structure for main development, feature branches, and releases
  • svnadmin: Command-line tool for creating and administering repositories
  • svnserve: Lightweight standalone SVN server daemon (not used in this HTTP-based guide)
  • libapache2-mod-svn: Apache module that enables WebDAV-based SVN access [web:7665]

Ubuntu 26.04 LTS ships Subversion version 1.14.x from the Universe component. The “Apache” in the package name refers to the Apache Software Foundation, not the Apache HTTP Server itself. You can run SVN locally with svnserve without ever touching Apache, but this guide uses Apache with WebDAV because it provides better authentication, logging, and HTTPS support out of the box [web:7651][web:7665].

Step 1: Update Your System Package Index

sudo apt update && sudo apt upgrade -y

What this command does:

  • sudo apt update refreshes the local package metadata cache from Ubuntu’s repositories
  • sudo apt upgrade -y installs all available security updates and bug fixes automatically

Why you must do this:

Running apt update ensures APT has the latest package versions available. Without this step, APT might install an outdated or mismatched Subversion version that has known security vulnerabilities. Running apt upgrade before adding new software follows basic security hygiene by closing known exploits before your system becomes more complex [web:7656][web:7665].

Expected output:

Get:1 http://us.archive.ubuntu.com/ubuntu noble InRelease [256 kB]
...
Fetched 123 MB in 45s (2,734 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
12 packages can be upgraded. Run 'apt list --upgradable' to see them.

Reading package lists... Done
Building dependency tree... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be upgraded:
  libssl3 ubuntu-pro-client ...
12 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Important note: Subversion lives in Ubuntu’s Universe component. If apt install subversion returns “Unable to locate package,” enable Universe first:

sudo add-apt-repository universe
sudo apt update

Step 2: Install Apache Subversion and Required Packages

sudo apt install -y subversion apache2 libapache2-mod-svn apache2-utils

What each package does:

  • subversion: Installs the core SVN client binaries (svn, svnadmin, svnlook, svnserve, svnversion) and libraries [web:7665]
  • apache2: Installs the Apache HTTP Server, which acts as the network layer for WebDAV-based SVN access [web:7656]
  • libapache2-mod-svn: Installs the Apache module that translates WebDAV HTTP requests into SVN repository operations. Without this module, Apache has no understanding of SVN’s internal database format [web:7664]
  • apache2-utils: Installs utility tools including htpasswd, which creates and manages Basic Auth user credentials for SVN access [web:7656]

Why install all packages together:

APT resolves shared dependencies in a single transaction. Installing packages separately risks version mismatches between apache2, libapache2-mod-svn, and the core Subversion client, which can cause runtime errors when the modules try to communicate.

Expected output:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  apache2-bin apache2-data apache2-utils libapr1 libaprutil1 ...
The following NEW packages will be installed:
  apache2 apache2-utils libapache2-mod-svn subversion
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
...
Setting up subversion (1.14.5-1ubuntu1) ...
Setting up libapache2-mod-svn (1.14.5-1ubuntu1) ...
Setting up apache2 (2.4.58-1ubuntu8) ...
Processing triggers for apache2 (2.4.58-1ubuntu8) ...

Step 3: Verify the Installation

command -v svn svnadmin svnlook svnserve svnversion
svn --version --quiet
apache2 -v

What these commands do:

  • command -v ... checks whether each SVN binary exists in your system PATH and returns its full path
  • svn --version --quiet outputs only the Subversion version number without extra metadata
  • apache2 -v displays the Apache HTTP Server version

Why verify before proceeding:

Confirming binary availability and version strings catches failed installations before you waste time creating directories, writing configuration files, or setting permissions that will later fail. This is a quick health check that prevents frustration later in the tutorial.

Expected output on Ubuntu 26.04:

/usr/bin/svn
/usr/bin/svnadmin
/usr/bin/svnlook
/usr/bin/svnserve
/usr/bin/svnversion
1.14.5 (r1918546)
Server version: Apache/2.4.58 (Ubuntu)

If svn is not found, check that Universe is enabled and re-run sudo apt update && sudo apt install -y subversion.

Step 4: Create a Dedicated System User and Repository Directory

sudo addgroup --system svn
sudo adduser --system --ingroup svn --home /srv/svn --shell /usr/sbin/nologin svn
sudo mkdir -p /srv/svn

What each command does:

  • addgroup --system svn: Creates a system group named svn with a UID below 1000
  • adduser --system --ingroup svn ... svn: Creates a system user named svn, assigns it to the svn group, sets its home directory to /srv/svn, and prevents interactive login
  • mkdir -p /srv/svn: Creates the parent directory for all SVN repositories

Why create a dedicated system user:

Running SVN-managed directories under the default www-data user alone creates a single point of failure. If Apache is compromised, the attacker gains direct access to all repository data. A dedicated svn system account isolates repository data from the web process and follows the principle of least privilege [web:7657].

Why use /usr/sbin/nologin:

This shell prevents the svn account from logging in interactively via SSH or console. The account exists only for file ownership and group permissions, not for human login.

Why use /srv/svn:

The /srv/ directory is the Filesystem Hierarchy Standard (FHS) location for service-specific data. Keeping repositories here separates them from the web root (/var/www/) and avoids accidental exposure through web directory browsing. It also clearly signals to other administrators that this directory contains active service data [web:7657].

Why use --system:

System accounts get UIDs below 1000, which signals to admin tooling and monitoring systems that these are service accounts, not regular human user accounts. This distinction helps with security auditing and automated access control.

Step 5: Create the SVN Repository with svnadmin

sudo svnadmin create /srv/svn/project
sudo chown -R svn:svn /srv/svn
sudo chmod -R 770 /srv/svn
sudo usermod -aG svn www-data
sudo systemctl restart apache2

What each command does:

  • svnadmin create /srv/svn/project: Initializes a new FSFS-format repository at the specified path. The command creates db/, hooks/, locks/, and format files inside the directory [web:7657][web:7660]
  • chown -R svn:svn /srv/svn: Recursively changes ownership of all repository files to the svn user and group
  • chmod -R 770 /srv/svn: Sets read, write, and execute permissions for owner and group only
  • usermod -aG svn www-data: Adds the Apache user www-data to the svn group without removing existing group memberships
  • systemctl restart apache2: Reloads Apache to pick up any service-level changes

Why svnadmin create is necessary:

This command initializes a new Berkeley DB or FSFS-format repository. It does NOT create a Git-style bare clone. The resulting directory structure is specific to SVN’s internal database format and cannot be used without this initialization step.

Why chown -R svn:svn:

Repository files must be owned by the service account so that Apache (running as www-data) can read and write them through the shared group. If the repository is owned by root, Apache will fail with “Permission denied” errors during commit operations [web:7665].

Why chmod 770 and not 777:

Mode 777 gives world-writable permissions, which is a critical security vulnerability. Anyone on the system could modify or delete repository data. Mode 770 restricts access to the owner (svn) and group members only (including www-data), following the principle of least privilege [web:7658].

Why add www-data to the svn group:

Apache processes run as the www-data user. Group membership grants Apache write access to the repository without changing file ownership or using insecure permissions like 777 [web:7657].

Expected output:

[sudo] password for youruser:
usermod: no changes

The “no changes” message is normal if www-data is already in the group.

Step 6: Configure Apache WebDAV for SVN Access

Create a new Apache configuration file:

sudo nano /etc/apache2/conf-available/svn.conf

Paste this configuration into the file:

<Location /svn>
    DAV svn
    SVNParentPath /srv/svn
    AuthType Basic
    AuthName "SVN Repository"
    AuthUserFile /etc/svn-auth-file
    Require valid-user
</Location>

Save the file and exit the editor (Ctrl+O, Enter, Ctrl+X in nano).

Then enable the configuration and required modules:

sudo a2enconf svn
sudo a2enmod dav_svn
sudo systemctl reload apache2

What each Apache directive does:

  • <Location /svn>: Defines the URL path where SVN will be accessible. Users will access repositories at http://YOUR_IP/svn/repo-name
  • DAV svn: Activates the mod_dav_svn handler, telling Apache to process WebDAV requests at this path as SVN operations [web:7657]
  • SVNParentPath /srv/svn: Specifies the parent directory containing all SVN repositories. This allows multiple repositories under one directory (e.g., /srv/svn/project, /srv/svn/legacy)
  • AuthType Basic: Enables HTTP Basic Authentication for this location
  • AuthName "SVN Repository": Sets the authentication realm name shown in the login prompt
  • AuthUserFile /etc/svn-auth-file: Points to the file containing username and password credentials
  • Require valid-user: Denies access to all users who are not in the password file

Why use SVNParentPath instead of SVNPath:

SVNParentPath allows multiple repositories under one directory, making it easier to scale. SVNPath points to a single repository only. Use SVNParentPath unless you have a specific reason to serve exactly one repository [web:7659].

Why create a dedicated conf file instead of editing dav_svn.conf directly:

Using conf-available and a2enconf follows Debian/Ubuntu’s modular Apache configuration pattern. Editing module config files directly mixes concerns and makes upgrades risky. Modular configuration also makes it easier to disable SVN access by running a2disconf svn without touching core module files [web:7664].

Why store the auth file at /etc/svn-auth-file:

Storing the password file outside the web root (in /etc/) prevents accidental exposure if directory browsing is misconfigured. A file under /var/www/ could be downloadable through a web browser if Apache is misconfigured.

Step 7: Create SVN Users with htpasswd

Create the first user (this creates the password file):

sudo htpasswd -c /etc/svn-auth-file admin

Add additional users (omit -c to avoid overwriting):

sudo htpasswd /etc/svn-auth-file developer1
sudo htpasswd /etc/svn-auth-file developer2

What htpasswd does:

The htpasswd command creates and manages a flat file containing usernames and cryptographically hashed passwords for HTTP Basic Authentication.

Why the -c flag is dangerous on second use:

Using -c again silently overwrites the entire password file, deleting all existing users. This is one of the most common admin mistakes when adding new SVN users. Always omit -c after creating the initial file [web:7659].

Why use htpasswd instead of system users:

htpasswd manages a separate credential store scoped only to SVN. This decouples SVN access from system login. Revoking SVN access by removing a user from the password file does not affect OS accounts, and vice versa [web:7659].

Expected output:

New password: 
Retype new password: 
Adding password for user admin

Verify the file was created:

ls -l /etc/svn-auth-file

Expected output:

-rw-r--r-- 1 root root 123 May 29 18:45 /etc/svn-auth-file

Step 8: Configure UFW Firewall

sudo ufw allow 'Apache'
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status

What each command does:

  • ufw allow 'Apache': Opens ports 80 (HTTP) and 443 (HTTPS) using Ubuntu’s named Apache profile
  • ufw allow 22/tcp: Explicitly allows SSH traffic on port 22
  • ufw enable: Activates the firewall with current rules
  • ufw status: Displays the active firewall rules

Why enable the firewall:

Default Ubuntu 26.04 cloud images may have UFW inactive. Without it, all ports are reachable from the internet, exposing your server to automated scanning and brute-force attacks [web:7657].

Why allow port 22 BEFORE enabling UFW:

If you enable UFW without first allowing SSH, you will lock yourself out of the server during the same session. Always allow port 22 before running ufw enable [web:7657].

Why use the named Apache profile:

The named profile opens both port 80 and 443 automatically, reducing manual effort if you add HTTPS later with Let’s Encrypt. Custom port rules require you to remember exact port numbers.

Expected output:

Rules added (name: Apache)
Rules added
Firewall is active and enabled on system startup
Status: active

To                         Action      From
--                         ------      ----
Apache                     ALLOW       Anywhere
22/tcp                     ALLOW       Anywhere
Apache (v6)                ALLOW       Anywhere (v6)
22/tcp (v6)                ALLOW       Anywhere (v6)

Step 9: Verify Access in a Web Browser

Open your browser and navigate to:

http://<SERVER_IP>/svn/project/

Replace <SERVER_IP> with your server’s actual public IP address.

Why test in a browser first:

A browser test confirms the entire stack is working (Apache, mod_dav_svn, authentication, permissions) before introducing SVN client behavior as a variable. If the browser works but the client fails, you know the problem is on the client side, not the server [web:7657].

Expected result:

You should see a Basic Auth prompt asking for username and password. After entering admin and the password you set, you should see a Subversion index page showing repository revision and path information.

Troubleshooting browser errors:

  • 403 Forbidden: Re-check www-data group membership and chmod 770 on /srv/svn
  • 500 Internal Server Error: Inspect Apache error log at /var/log/apache2/error.log
  • Connection refused: Verify Apache is running with sudo systemctl status apache2

Step 10: Make Your First SVN Commit

On your local development machine (not the server), run:

svn checkout http://<SERVER_IP>/svn/project --username admin
cd project
echo "Initial file" > README.txt
svn add README.txt
svn commit -m "Initial commit"

What each command does:

  • svn checkout: Creates a working copy connected to the repository URL on your local machine
  • cd project: Changes into the checked-out working copy directory
  • echo "Initial file" > README.txt: Creates a test file with sample content
  • svn add README.txt: Stages the file for inclusion in the next commit
  • svn commit -m "Initial commit": Pushes the staged changes to the repository with a commit message

Why svn checkout before svn add:

SVN requires a working copy connected to a repository URL before tracking file changes. Unlike Git, you cannot initialize a repository locally and push later. The checkout operation establishes the connection between your local files and the central server [web:7665].

Why use the -m flag for commit messages:

Commit messages are stored permanently in the repository log. Empty or meaningless messages degrade long-term maintainability. The -m flag lets you write a proper message without opening an editor.

Expected output:

A    README.txt
Committed revision 1.

Verify the commit was recorded:

svn log

Expected output:

------------------------------------------------------------------------
r1 | admin | 2026-05-29 18:50:12 +0700 (Thu, 29 May 2026) | 1 line

Initial commit
------------------------------------------------------------------------

Troubleshooting Common Errors

Error 1: Unable to locate package subversion

Cause: Ubuntu’s Universe component is not enabled. Subversion is not in the main repository.

Solution:

sudo add-apt-repository universe
sudo apt update
sudo apt install -y subversion

This registers Universe with APT and refreshes the package cache [web:7665].

Error 2: 403 Forbidden When Accessing /svn/project/

Cause: The Apache user www-data lacks group access to /srv/svn.

Solution:

sudo usermod -aG svn www-data
sudo systemctl restart apache2
sudo chmod -R 770 /srv/svn

Verify www-data is in the svn group:

groups www-data

Expected output includes svn in the list [web:7657].

Error 3: Permission denied on Repository Path

Cause: Repository was created with sudo and owned by root instead of svn.

Solution:

sudo chown -R svn:svn /srv/svn
sudo chmod -R 770 /srv/svn

Always create repositories as the svn user or fix ownership immediately after creation [web:7665].

Error 4: 500 Internal Server Error in Browser

Cause: mod_dav_svn is not loaded or Apache configuration has a syntax error.

Solution:

Check Apache configuration syntax:

sudo apache2ctl configtest

Expected output: Syntax OK

Check Apache error log:

sudo tail -f /var/log/apache2/error.log

Ensure mod_dav_svn is enabled:

sudo a2enmod dav_svn
sudo systemctl reload apache2

Inspect the log for specific error messages after reloading [web:7664].

Error 5: All Users Wiped from htpasswd File

Cause: Accidentally used -c flag when adding a new user, which overwrote the entire file.

Solution:

There is no recovery. You must recreate all users without the -c flag:

sudo htpasswd -c /etc/svn-auth-file newadmin
sudo htpasswd /etc/svn-auth-file developer1

Always omit -c for additional users [web:7659].

Post-Installation Best Practices

Enable HTTPS with Let’s Encrypt

Basic Auth over plain HTTP transmits passwords in base64 encoding, which is readable on any network sniff. Use Certbot to add a Let’s Encrypt SSL certificate:

sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d yourdomain.com

This automatically configures HTTPS and redirects HTTP to HTTPS [web:7657].

Schedule Daily Backups with svnadmin hotcopy

SVN stores every revision permanently, so repositories grow over time. Use svnadmin hotcopy to create live, consistent backups without taking the server offline:

sudo svnadmin hotcopy /srv/svn/project /bak/project-$(date +%F)

Add this to cron for daily backups:

0 2 * * * svnadmin hotcopy /srv/svn/project /bak/project-$(date +\%F)

This is safe for cron jobs because it does not lock the repository [web:7657].

Add Path-Based Authorization

For team environments, use mod_authz_svn to segment access by path. Create an /etc/svn-authz file:

[groups]
dev-team = admin, developer1
ops-team = admin, developer2

[/project]
@dev-team = rw
@ops-team = r

[/legacy]
@ops-team = rw
* =

This prevents developer1 from accessing /legacy while allowing admin everywhere.

Monitor Disk Usage

SVN repositories grow with every commit. On a constrained VPS, running out of disk space causes write failures silently. Check disk usage regularly:

df -h /srv/svn
du -sh /srv/svn/*

[su_box title=”VPS Manage Service Offer” style=”bubbles” box_color=”#000000″ radius=”10″]If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal![/su_box]

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts