Git

Install Apache Subversion (SVN) Server on Rocky Linux 10 / Ubuntu 24.04

Still running Subversion in 2026? You’re not alone. Plenty of enterprises, regulated industries, and legacy codebases depend on SVN for centralized version control where Git’s distributed model is overkill or a compliance headache. Apache Subversion 1.14 (the current LTS branch) is stable, well-supported, and does the job it was built for.

Original content from computingforgeeks.com - post 29890

This guide covers a full SVN server setup with Apache mod_dav_svn on Rocky Linux 10 and Ubuntu 24.04, including repository creation, HTTP basic authentication, path-based authorization, SELinux configuration, firewall rules, and SSL/TLS with Let’s Encrypt. There is also a practical SVN command cheat sheet at the end for daily operations.

Last verified: March 2026 | Tested on Rocky Linux 10.1, Ubuntu 24.04 LTS

Prerequisites

  • A server running Rocky Linux 10, AlmaLinux 10, RHEL 10, or Ubuntu 24.04 LTS
  • Root or sudo access
  • Minimum 1 GB RAM, 1 vCPU (SVN is lightweight)
  • Ports 80/tcp and 443/tcp open for HTTP/HTTPS access
  • A domain or subdomain pointed to your server (for SSL)
  • Tested with: Subversion 1.14.5 (Rocky 10), Subversion 1.14.3 (Ubuntu 24.04)

Install Apache Subversion on Rocky Linux 10 / AlmaLinux 10

Subversion and the Apache DAV module are available directly from the AppStream repository. No extra repos needed.

Update the system first:

sudo dnf update -y

Install Subversion, the Apache HTTP server, and the mod_dav_svn module:

sudo dnf install -y subversion mod_dav_svn httpd httpd-tools

Confirm the installed versions:

svn --version --quiet
httpd -v | head -1

You should see Subversion 1.14.5 and Apache 2.4.63:

1.14.5
Server version: Apache/2.4.63 (Rocky Linux)

Install Apache Subversion on Ubuntu 24.04

On Ubuntu, the SVN Apache module is packaged separately as libapache2-mod-svn.

Update package lists and install:

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

Enable the required Apache modules:

sudo a2enmod dav dav_svn authz_svn

Verify the installation:

svn --version --quiet
apache2 -v | head -1

Expected output on Ubuntu 24.04:

1.14.3
Server version: Apache/2.4.58 (Ubuntu)

Create an SVN Repository

Create the parent directory for all SVN repositories and your first project repository. The SVNParentPath directive (configured later) lets Apache serve multiple repos from a single location.

sudo mkdir -p /var/www/svn /etc/svn
sudo svnadmin create /var/www/svn/myproject

Set ownership to the Apache user. On RHEL/Rocky this is apache, on Ubuntu it is www-data:

# Rocky / AlmaLinux / RHEL
sudo chown -R apache:apache /var/www/svn

# Ubuntu / Debian
sudo chown -R www-data:www-data /var/www/svn

Verify the repository was created successfully:

sudo svnadmin info /var/www/svn/myproject

The output confirms the repository format and filesystem type:

Path: /var/www/svn/myproject
UUID: a7546642-23ea-4d67-a3bd-4e3ad692926e
Revisions: 0
Repository Format: 5
Compatible With Version: 1.10.0
Repository Capability: mergeinfo
Filesystem Type: fsfs
Filesystem Format: 8
FSFS Sharded: yes
FSFS Shard Size: 1000
FSFS Shards Packed: 0/0
FSFS Logical Addressing: yes

Configure Apache with mod_dav_svn

The mod_dav_svn module serves SVN repositories over HTTP(S) through Apache. Create the configuration file for your OS.

Rocky / AlmaLinux / RHEL

Create the Apache SVN configuration file:

sudo vi /etc/httpd/conf.d/subversion.conf

Add the following configuration:

<Location /svn>
   DAV svn
   SVNParentPath /var/www/svn
   AuthType Basic
   AuthName "SVN Repository"
   AuthUserFile /etc/svn/svn-auth
   AuthzSVNAccessFile /etc/svn/svn-authz
   Require valid-user
</Location>

Ubuntu / Debian

On Ubuntu, the DAV SVN module ships with a default config file. Replace its contents:

sudo vi /etc/apache2/mods-available/dav_svn.conf

Add the same Location block:

<Location /svn>
   DAV svn
   SVNParentPath /var/www/svn
   AuthType Basic
   AuthName "SVN Repository"
   AuthUserFile /etc/svn/svn-auth
   AuthzSVNAccessFile /etc/svn/svn-authz
   Require valid-user
</Location>

The key directives here: SVNParentPath serves every repository under /var/www/svn automatically, AuthUserFile points to the htpasswd credentials, and AuthzSVNAccessFile enables per-path access control.

Create SVN Users with htpasswd

SVN over Apache uses HTTP Basic authentication. Create the password file and add your first user with the -c flag (creates the file):

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

You will be prompted to enter and confirm a password. To add more users, omit the -c flag so the existing file is not overwritten:

sudo htpasswd /etc/svn/svn-auth developer
sudo htpasswd /etc/svn/svn-auth designer

Lock down the password file permissions so only Apache can read it:

# Rocky / AlmaLinux / RHEL
sudo chown root:apache /etc/svn/svn-auth
sudo chmod 640 /etc/svn/svn-auth

# Ubuntu / Debian
sudo chown root:www-data /etc/svn/svn-auth
sudo chmod 640 /etc/svn/svn-auth

Set Up Path-Based Authorization

The AuthzSVNAccessFile directive referenced in the Apache config points to a file that controls who can read or write specific paths within each repository. This is one of SVN’s advantages over basic filesystem permissions.

Create the authorization file:

sudo vi /etc/svn/svn-authz

Add group definitions and per-path rules:

[groups]
admins = admin
developers = developer, designer

[myproject:/]
@admins = rw
@developers = rw

[myproject:/releases]
@admins = rw
@developers = r

[myproject:/config]
@admins = rw
* =

In this example, admins have full read-write access everywhere. Developers can read and write to most paths but only read from /releases. The /config path is restricted to admins only, with * = denying everyone else. You can add more repositories by creating additional [reponame:/path] sections.

Configure SELinux for SVN (Rocky / AlmaLinux / RHEL)

Rocky Linux 10 runs SELinux in enforcing mode by default. Apache needs the correct security contexts to read and write SVN repository files. Without these, you will get “403 Forbidden” errors when accessing the repository.

Set the SELinux file context so Apache can write to the SVN directory:

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/svn(/.*)?"
sudo restorecon -Rv /var/www/svn

The restorecon command applies the new context to all existing files. You should see output confirming each file was relabeled:

Relabeled /var/www/svn from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:httpd_sys_rw_content_t:s0
Relabeled /var/www/svn/myproject from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:httpd_sys_rw_content_t:s0
Relabeled /var/www/svn/myproject/db from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:httpd_sys_rw_content_t:s0
...

Enable the httpd_unified boolean so Apache can access all its content directories uniformly:

sudo setsebool -P httpd_unified 1

Verify there are no SELinux denials after the configuration:

sudo ausearch -m avc -ts recent

A clean output (<no matches>) means SELinux is happy with the configuration. If you see AVC denials later after accessing the repository, check what is being denied with ausearch and adjust the context or booleans accordingly.

Configure the Firewall

Open HTTP and HTTPS ports so clients can reach the SVN server.

Firewalld (Rocky / AlmaLinux / RHEL)

If firewalld is configured on your server, open the required ports:

sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

Confirm the services are listed:

sudo firewall-cmd --list-services

UFW (Ubuntu / Debian)

On Ubuntu, allow Apache through UFW:

sudo ufw allow "Apache Full"
sudo ufw enable
sudo ufw status

Start Apache and Verify SVN Access

Enable and start the Apache service:

# Rocky / AlmaLinux / RHEL
sudo systemctl enable --now httpd
sudo systemctl status httpd

# Ubuntu / Debian
sudo systemctl enable --now apache2
sudo systemctl restart apache2
sudo systemctl status apache2

Test SVN access from the command line on the server itself:

curl -u admin http://localhost/svn/myproject/

After entering the password, you should see the repository HTML listing:

<html><head><title>myproject - Revision 0: /</title></head>
<body>
 <h2>myproject - Revision 0: /</h2>
 <ul>
 </ul>
</body></html>

From a remote machine, open http://your-server-ip/svn/myproject in a web browser. You will be prompted for credentials before seeing the repository browser.

Secure SVN with SSL/TLS (Let’s Encrypt)

Running SVN over plain HTTP sends credentials in base64 encoding, which is trivially decoded. For any production use, you must enable HTTPS. Here we use Let’s Encrypt for a free SSL certificate.

Install Certbot

# Rocky / AlmaLinux / RHEL
sudo dnf install -y certbot python3-certbot-apache mod_ssl

# Ubuntu / Debian
sudo apt install -y certbot python3-certbot-apache

Obtain and Install the Certificate

Replace svn.example.com with your actual domain. Certbot will automatically configure Apache for SSL:

sudo certbot --apache -d svn.example.com --non-interactive --agree-tos -m [email protected]

Certbot creates the SSL virtual host configuration and sets up automatic HTTP to HTTPS redirection. Verify the certificate renewal works:

sudo certbot renew --dry-run

After SSL is configured, access your repository at https://svn.example.com/svn/myproject. All SVN client connections should also use the HTTPS URL going forward.

SVN Client Operations

With the server running, here are the essential client-side operations. Install the SVN client on your workstation if you have not already (dnf install subversion or apt install subversion).

Checkout a Repository

svn checkout https://svn.example.com/svn/myproject --username admin

This creates a local working copy. You will be prompted for the password on first access, and SVN caches the credentials for subsequent operations:

Checked out revision 0.

Add Files and Commit

cd myproject
echo "Project README" > README.txt
mkdir src
echo '#!/bin/bash' > src/build.sh

svn add README.txt src
svn commit -m "Initial project structure"

SVN confirms each added file and the resulting revision number:

Adding         README.txt
Adding         src
Adding         src/build.sh
Transmitting file data ..done
Committing transaction...
Committed revision 1.

View Repository Info and Log

svn info

Shows the working copy metadata:

Path: .
Working Copy Root Path: /home/user/myproject
URL: https://svn.example.com/svn/myproject
Relative URL: ^/
Repository Root: https://svn.example.com/svn/myproject
Repository UUID: a7546642-23ea-4d67-a3bd-4e3ad692926e
Revision: 1
Node Kind: directory
Last Changed Author: admin
Last Changed Rev: 1
Last Changed Date: 2026-03-24 11:14:18 +0000 (Tue, 24 Mar 2026)

View the commit history:

svn log

The log shows all revisions with author, date, and commit message:

------------------------------------------------------------------------
r1 | admin | 2026-03-24 11:14:18 +0000 (Tue, 24 Mar 2026) | 1 line

Initial project structure
------------------------------------------------------------------------

Create Additional Repositories

Because we used SVNParentPath, adding a new repository is just two commands. No Apache restart needed:

sudo svnadmin create /var/www/svn/another-project

Set the correct ownership for your OS:

# Rocky / AlmaLinux / RHEL
sudo chown -R apache:apache /var/www/svn/another-project

# Ubuntu / Debian
sudo chown -R www-data:www-data /var/www/svn/another-project

On RHEL-based systems, also apply the SELinux context:

sudo restorecon -Rv /var/www/svn/another-project

Add authorization rules in /etc/svn/svn-authz for the new repository, then access it at https://svn.example.com/svn/another-project.

SVN Command Cheat Sheet

This reference table covers the commands you will use most often when working with Subversion repositories.

CommandDescriptionExample
svn checkout URLCreate a local working copy from a remote repositorysvn checkout https://svn.example.com/svn/myproject
svn updatePull latest changes from the server into your working copysvn update
svn add FILESchedule a new file or directory for additionsvn add src/main.py
svn delete FILESchedule a file for deletion on next commitsvn delete old-config.ini
svn commit -m "msg"Send local changes to the serversvn commit -m "Add login module"
svn statusShow modified, added, or deleted files in working copysvn status
svn diffShow line-by-line differences in modified filessvn diff src/main.py
svn logShow commit historysvn log -l 10 (last 10 commits)
svn infoDisplay working copy or repository metadatasvn info https://svn.example.com/svn/myproject
svn revert FILEUndo local changes (restore to last committed version)svn revert src/main.py
svn copy SRC DSTCreate a branch or tag (server-side copy)svn copy ^/trunk ^/branches/feature-x -m "Branch"
svn merge SRCMerge changes from another branch into working copysvn merge ^/branches/feature-x
svn switch URLSwitch working copy to a different branch or tagsvn switch ^/branches/feature-x
svn export URLExport a clean copy without .svn metadatasvn export ^/trunk /tmp/release
svn blame FILEShow per-line author and revision informationsvn blame src/main.py
svn propsetSet a property on a file or directorysvn propset svn:ignore "*.log" .
svn cleanupClean up a broken working copy (remove locks)svn cleanup
svn list URLList directory contents in a repositorysvn list https://svn.example.com/svn/myproject
svnadmin create PATHCreate a new repository (server-side)svnadmin create /var/www/svn/newrepo
svnadmin dump REPOExport full repository for backup or migrationsvnadmin dump /var/www/svn/myproject > backup.dump
svnadmin load REPORestore a repository from a dump filesvnadmin load /var/www/svn/myproject < backup.dump
svnadmin hotcopyCreate a safe backup of a live repositorysvnadmin hotcopy /var/www/svn/myproject /backup/myproject

SVN Repository Backup and Restore

Regular backups are essential. SVN provides two approaches: dump files (portable, can be loaded into different SVN versions) and hotcopy (fast, byte-for-byte clone).

Dump and Load (Portable Backup)

svnadmin dump /var/www/svn/myproject > /backup/myproject-$(date +%Y%m%d).dump

To restore into a fresh repository:

sudo svnadmin create /var/www/svn/myproject-restored
sudo svnadmin load /var/www/svn/myproject-restored < /backup/myproject-20260324.dump

Hotcopy (Fast Clone)

For quick backups on the same server, hotcopy is faster because it copies the repository at the filesystem level:

sudo svnadmin hotcopy /var/www/svn/myproject /backup/myproject-hotcopy

Automate daily backups with a cron job. This example runs at 2 AM and keeps 7 days of dumps:

echo "0 2 * * * root svnadmin dump /var/www/svn/myproject | gzip > /backup/myproject-\$(date +\%Y\%m\%d).dump.gz && find /backup -name 'myproject-*.dump.gz' -mtime +7 -delete" | sudo tee /etc/cron.d/svn-backup

OS-Specific Differences

This comparison table summarizes the key differences between setting up SVN on RHEL-based and Debian-based systems. Keep this handy when following the steps above.

ItemRocky / AlmaLinux / RHEL 10Ubuntu 24.04 / Debian
SVN version in repos1.14.51.14.3
SVN packagesubversionsubversion
Apache DAV modulemod_dav_svnlibapache2-mod-svn
Apache config path/etc/httpd/conf.d/subversion.conf/etc/apache2/mods-available/dav_svn.conf
Apache userapachewww-data
Service namehttpdapache2
Enable modulesLoaded automatically via configa2enmod dav dav_svn authz_svn
Firewallfirewall-cmdufw
SELinux/AppArmorSELinux context + boolean requiredNo action needed (AppArmor has no default Apache profile)
Install certbotdnf install certbot python3-certbot-apache mod_sslapt install certbot python3-certbot-apache

Troubleshooting Common Issues

Error: “403 Forbidden” when accessing /svn/

This almost always means SELinux is blocking Apache from reading the repository files on RHEL-based systems. Verify the SELinux context is correct:

ls -lZ /var/www/svn/

Every file should show httpd_sys_rw_content_t. If it shows default_t or httpd_sys_content_t (read-only), run restorecon -Rv /var/www/svn and make sure you set the httpd_sys_rw_content_t context, not httpd_sys_content_t. Check the audit log with ausearch -m avc -ts recent for details.

Error: “500 Internal Server Error” on repository access

Check the Apache error log for specifics:

# Rocky / RHEL
sudo tail -20 /var/log/httpd/error_log

# Ubuntu
sudo tail -20 /var/log/apache2/error.log

Common causes: the repository path in SVNParentPath does not match the actual directory, or the Apache user does not own the repository files. Fix ownership with chown -R apache:apache /var/www/svn (or www-data:www-data on Ubuntu).

Error: “Could not open the requested SVN filesystem”

This means the repository directory exists but was not created with svnadmin create. A plain mkdir does not create a valid SVN repository. Remove the directory and recreate it properly with svnadmin create /var/www/svn/reponame.

Error: “Authorization failed” with correct password

If the password is correct but access is still denied, the issue is in the svn-authz file. Check that the username in the authz file matches exactly (case-sensitive) what is in the htpasswd file. Also verify the repository name in the authz section header matches the actual repository directory name under /var/www/svn/.

SVN commits fail with “txn-current-lock: Permission denied”

The Apache user cannot write to the repository. This happens when new files are created with wrong ownership after a manual operation. Fix it:

# Rocky / AlmaLinux / RHEL
sudo chown -R apache:apache /var/www/svn/myproject

# Ubuntu / Debian
sudo chown -R www-data:www-data /var/www/svn/myproject

On RHEL-based systems, also re-apply the SELinux context: sudo restorecon -Rv /var/www/svn/myproject.

Frequently Asked Questions

Is SVN still maintained in 2026?

Yes. Apache Subversion 1.14 is the current LTS branch. The latest release is 1.14.5 (December 2024), which included a security fix for CVE-2024-46901. The project receives bugfix and security updates, though no major feature releases are planned.

Should I use SVN or Git?

Git is the standard for most software projects today. SVN still makes sense for large binary assets (game studios, hardware design), strict centralized access control requirements (regulated industries), or legacy codebases where migration cost outweighs the benefit. If you are starting a new project with no constraints, use Git.

What port does SVN use?

When served through Apache (mod_dav_svn), SVN uses standard HTTP/HTTPS ports: 80/tcp and 443/tcp. The standalone svnserve daemon uses port 3690/tcp, but the Apache method is recommended for production because it provides SSL, authentication integration, and fine-grained path authorization.

How do I migrate from SVN to Git?

Use git svn clone to convert an SVN repository to Git while preserving full history. For large repositories, the svn2git tool provides better control over author mapping and branch conversion. Plan for a transition period where both systems are available.

Wrapping Up

You now have a fully functional Apache Subversion server with HTTP authentication, path-based authorization, and SSL encryption. The setup works identically across Rocky Linux 10, AlmaLinux 10, RHEL 10, and Ubuntu 24.04, with the only differences being package names, Apache user accounts, and SELinux requirements on RHEL-based systems.

For production environments, consider integrating LDAP authentication instead of htpasswd for centralized user management, setting up automated backups with the cron job shown above, and monitoring Apache access logs for unauthorized access attempts. If your team is evaluating alternatives, GitLab CE offers a modern web-based Git platform with built-in CI/CD.

Related Articles

Email Running Zimbra on Docker Container AlmaLinux Install Zabbix 8.0 on Rocky Linux 10 / AlmaLinux 10 AlmaLinux Setup Syncthing synchronization on Rocky / AlmaLinux 8 Rocky Linux Install Apache, MariaDB, PHP (LAMP) on Rocky Linux 9

1 thought on “Install Apache Subversion (SVN) Server on Rocky Linux 10 / Ubuntu 24.04”

  1. Hi Josphat,

    This is the second Linux tutorial I’ve used for you and your instructions is spot on. Thanks for this. Trying to get back into programming and building my resources to accomplish this.

    Reply

Leave a Comment

Press ESC to close