
Version control isn’t just a Git conversation anymore — plenty of production environments, especially in enterprise, government, and legacy CI/CD pipelines, still lean heavily on Subversion (SVN). If you’ve been handed a Fedora 44 box and told “get SVN running by end of day,” you already know the frustration of stitching together outdated blog posts written for Fedora 20 or CentOS 6 that reference package names and paths that no longer exist.
Fedora 44 ships with dnf5 as the default package manager, tighter SELinux defaults, and a slightly reorganized Apache HTTP Server configuration layout compared to what most tutorials still assume. That mismatch between old documentation and current reality is exactly where sysadmins waste hours — permission denied errors that make no sense, SELinux silently blocking mod_dav_svn, or firewalld rules that were never opened in the first place.
This guide walks through installing Apache Subversion on Fedora 44 the way it should actually be done in 2026: with Apache HTTP Server integration via mod_dav_svn, proper repository permissions, authentication that doesn’t fall apart under concurrent access, and the security considerations that matter once this repository is exposed beyond your local network. Whether you’re standing up a lightweight internal repo for a small dev team or migrating a legacy SVN server that traffic spikes have started to choke, the fundamentals here scale in both directions.
We’ll also cover the parts most guides skip entirely — what happens when svnadmin create throws a permission error, why your commits vanish after a server reboot, and how to tune Apache’s worker processes when your repository suddenly gets hammered by a CI pipeline running dozens of concurrent checkouts. By the end, you’ll have a working, secured, and reasonably tuned SVN server running natively on Fedora 44.
What Is Apache Subversion and Why It Still Matters
Apache Subversion is a centralized version control system, meaning there’s a single authoritative repository that every client talks to — unlike Git’s distributed model. That centralization has tradeoffs, but for organizations with strict access control requirements, binary asset versioning (CAD files, large media, compiled artifacts), or teams that never fully migrated off legacy toolchains, SVN’s simplicity is a feature, not a limitation.
The project remains actively maintained, with 1.14 as the current long-term support branch. Fedora’s own package repositories track this closely, and as of Fedora 44, subversion-tools sits at version 1.14.5. That’s a mature, stable codebase — not something abandoned or deprecated, despite Git’s dominance in mindshare.
Pre-Installation Checklist
Before touching dnf, confirm a few things. Skipping this step is how you end up debugging SELinux denials at 11 PM instead of catching them upfront.
- Confirm you’re actually on Fedora 44 with
cat /etc/fedora-releaseorhostnamectl - Decide whether you need Apache HTTP integration (for http:// or https:// access) or a standalone svnserve daemon (for svn:// access on port 3690)
- Have root or sudo access ready — repository ownership and Apache config changes both require it
- Know your firewall zone; Fedora Workstation and Server default to different firewalld zones, which changes which commands you’ll run later
Most production setups use Apache integration rather than svnserve, mainly because it piggybacks on Apache’s existing SSL termination, logging, and authentication mechanisms. That’s the path this guide focuses on, though the standalone svnserve method gets a brief mention for completeness.
Step 1: Update the System
Never skip this. Fedora’s rapid release cadence means packages drift quickly, and installing SVN on a stale system is asking for dependency conflicts down the line.
sudo dnf update -y
sudo dnf install -y dnf-plugins-core
Reboot if the kernel got updated — a half-updated kernel state has caused more mysterious service failures than most sysadmins care to admit.
Step 2: Install Subversion and Apache HTTP Server
Fedora 44’s repositories carry both the core subversion package and the Apache DAV module needed to serve it over HTTP.
sudo dnf install -y subversion mod_dav_svn httpd
A quick note on what each package does:
- subversion — the core SVN binaries: svn, svnadmin, svnlook, svnserve
- mod_dav_svn — the Apache module that lets httpd speak WebDAV/SVN protocol
- httpd — Apache HTTP Server itself, Fedora’s default web server package
Verify the installed version once it completes:
svn --version
You should see something referencing 1.14.x, consistent with what Fedora currently packages. If you need supplementary tooling — diff visualizers, backup scripts, migration utilities — grab subversion-tools as well:
sudo dnf install -y subversion-tools
Step 3: Create the Repository Directory Structure
This is where a lot of tutorials get sloppy, and sloppy directory structure is exactly what turns into a permissions nightmare six months later when someone else inherits the server. Set up a dedicated parent directory rather than dumping repositories randomly under /var/www or /home.
sudo mkdir -p /var/svn/repos
sudo mkdir -p /var/svn/access
Now create your first repository:
sudo svnadmin create /var/svn/repos/projectname
svnadmin create builds the internal FSFS backend structure — db/, hooks/, conf/, locks/ — that SVN uses to track revisions. FSFS has been the default backend for years now; the older BDB (Berkeley DB) backend is essentially legacy at this point and shouldn’t be your default choice on a fresh install.
Setting Correct Ownership
Apache runs as the apache user on Fedora, not www-data like Debian-based systems — this trips up a lot of admins who cut their teeth on Ubuntu.
sudo chown -R apache:apache /var/svn/repos
sudo chmod -R 750 /var/svn/repos
Getting ownership wrong here is the single most common cause of “permission denied” errors when committing through Apache later. If httpd can’t write to the repository’s db/ directory, every commit attempt fails with a cryptic 500 error in the Apache logs rather than anything obviously permission-related.
Step 4: Configure Apache for Subversion
Fedora’s Apache config lives under /etc/httpd/, with module-specific configuration typically dropped into /etc/httpd/conf.d/. Create a dedicated config file rather than editing the main httpd.conf — it keeps things modular and easier to audit later.
sudo nano /etc/httpd/conf.d/subversion.conf
Populate it with:
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
<Location /svn>
DAV svn
SVNParentPath /var/svn/repos
SVNListParentPath on
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /var/svn/access/svn-auth-users
Require valid-user
</Location>
SVNParentPath is the key directive here — it tells Apache to treat everything under /var/svn/repos as a collection of repositories, rather than pointing to a single repo with SVNPath. This matters if you plan on hosting more than one project, which, realistically, you will eventually.
Step 5: Create Authentication Credentials
Basic Auth over HTTPS is still perfectly adequate for SVN in most internal environments — don’t overengineer this with LDAP or Kerberos unless your organization already has that infrastructure in place.
sudo htpasswd -cb /var/svn/access/svn-auth-users devuser 'StrongPassword123!'
Drop the -c flag for subsequent users — using it again wipes the existing file:
sudo htpasswd -b /var/svn/access/svn-auth-users seconduser 'AnotherPassword456!'
Lock the permissions down:
sudo chown root:apache /var/svn/access/svn-auth-users
sudo chmod 640 /var/svn/access/svn-auth-users
Step 6: Configure SELinux Contexts
This step is where most Fedora-specific installations go sideways, and it’s the part almost every generic Linux SVN tutorial completely ignores. Fedora ships SELinux enforcing by default, and unlike Ubuntu or Debian, you can’t just chown your way past access restrictions.
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/svn/repos(/.*)?"
sudo restorecon -Rv /var/svn/repos
If semanage isn’t available, install the policy management utilities first:
sudo dnf install -y policycoreutils-python-utils
Skipping this is why so many admins report SVN “working perfectly” over svnserve but throwing 403 Forbidden errors the moment Apache gets involved — SELinux is silently denying httpd_t domain processes from writing to a directory it doesn’t recognize as web content.
Step 7: Open the Firewall
Fedora’s firewalld defaults vary depending on whether you’re on Workstation or Server edition, so check your active zone first.
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
If you’re running the standalone svnserve daemon instead of Apache integration, open port 3690 explicitly:
sudo firewall-cmd --permanent --add-port=3690/tcp
sudo firewall-cmd --reload
Step 8: Start and Enable Apache
sudo systemctl enable --now httpd
sudo systemctl status httpd
Test the configuration syntax before relying on systemctl restart blindly — a bad config that fails silently mid-shift is worse than one that fails loudly during testing:
sudo apachectl configtest
Then browse to http://your-server-ip/svn/projectname — you should be prompted for the credentials created earlier, and once authenticated, see the (empty) repository listing.
Step 9: Test With a Client Checkout
From a workstation with the subversion client installed:
svn checkout http://your-server-ip/svn/projectname --username devuser
Add a test file, commit it, and confirm the revision history increments correctly:
svn add testfile.txt
svn commit -m "Initial commit test"
svn log
If that round-trips cleanly, the core setup is solid.
Access Control With AuthzSVNAccessFile
Basic authentication only handles who can log in — it says nothing about what they can do once they’re in. For anything beyond a single-developer setup, add path-based authorization.
AuthzSVNAccessFile /var/svn/access/svn-access-control
Then define granular rules:
[projectname:/]
devuser = rw
seconduser = r
[projectname:/branches/experimental]
devuser = rw
This lets you grant read-only access to junior devs or external contractors on sensitive branches while keeping write access restricted — something that’s saved more than one repository from an accidental force-push equivalent disaster.
Performance Tuning Considerations
SVN itself isn’t resource-hungry under normal load, but repositories that grow into gigabytes with thousands of revisions start exposing bottlenecks that only show up under real traffic.
Disk I/O: FSFS repositories are read-heavy on svn log, svn diff, and blame operations across large history. Putting the repository on SSD-backed storage rather than spinning disks makes a noticeable difference once revision counts climb into the thousands.
Apache worker configuration: Under mpm_event (Fedora’s default MPM), tune MaxRequestWorkers upward if you’re expecting concurrent CI checkouts:
<IfModule mpm_event_module>
StartServers 4
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestWorkers 200
</IfModule>
Repository caching: Enable SVNCacheFullTexts and SVNCacheTextDeltas in mod_dav_svn config for repositories with large binary files — this reduces redundant decompression work on repeated checkouts.
SVNCacheFullTexts on
SVNCacheTextDeltas on
Compression: If clients are on slower network links, enabling SVNCompressionLevel (set between 1-5) balances CPU overhead against bandwidth savings — don’t max it to 9 unless bandwidth is genuinely your bottleneck, because that shifts the cost straight onto CPU.
Security Hardening Beyond the Basics
Basic Auth over plain HTTP is not acceptable for anything internet-facing — full stop. Layer TLS on top immediately.
sudo dnf install -y mod_ssl
sudo systemctl restart httpd
Then force redirection from HTTP to HTTPS in your virtual host config, and update AuthUserFile references to sit behind the SSL-enabled VirtualHost block. Beyond TLS:
- Rotate htpasswd credentials periodically, especially after contractor offboarding
- Set SVNPathAuthz short_circuit when using large AuthzSVNAccessFile rule sets to speed up authorization checks without a full path walk
- Disable directory listing (SVNListParentPath off) once you’ve moved past the initial testing phase — no reason to advertise every repository name to anyone hitting the base URL
- Run svnadmin verify periodically on production repositories to catch silent corruption before it compounds
Real-World Scenario: Handling a Traffic Spike From CI
Picture this: a CI pipeline gets misconfigured and starts triggering full checkouts on every commit hook trigger instead of incremental updates. Suddenly Apache’s worker pool saturates, legitimate developer commits start timing out, and load average on the box climbs steadily.
The fix isn’t just “add more RAM.” First, check httpd process count and active connections:
ss -tn state established '( dport = :80 or dport = :443 )' | wc -l
If that number is spiking, temporarily throttle the offending CI IP at the firewall level while investigating:
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="CI_IP/32" reject' --timeout=600
Then fix the root cause — switch the CI job to svn update instead of repeated fresh checkouts, which is both the actual bug and the actual lesson here.
Troubleshooting Common Errors
Error: “svnadmin: E000013: Could not create repository”
Usually a permissions issue on the parent directory. Confirm the target directory exists and is writable by the user running the command, and check SELinux context with ls -Z.
Error: 403 Forbidden when browsing repository via Apache
Almost always SELinux, not Apache config. Run:
sudo ausearch -m avc -ts recent
Look for denials referencing httpd_t and the repository path — this confirms SELinux is the culprit and tells you exactly which context is missing.
Error: “svn: E170013: Unable to connect to a repository”
Check that httpd is actually running, and that the firewall rule for HTTP/HTTPS was applied and reloaded, not just added.
Commits silently fail with 500 Internal Server Error
Check /var/log/httpd/error_log first, always. Nine times out of ten it’s ownership on the repository’s db/ directory reverting after a manual chown outside of a proper SELinux-aware workflow.
Repository “locked” errors after an unclean shutdown
sudo svnadmin recover /var/svn/repos/projectname
This clears stale locks left behind by an interrupted commit — common after unexpected power loss or an OOM-killed process mid-transaction.