Apache Subversion Svn
Videos
Overview: Apache Subversion (SVN) on Azure: overview (watch on YouTube)
Launch and log in: Apache Subversion (SVN) on Azure: launch and log in (watch on YouTube)
Deep Dive: Apache Subversion (SVN) on Azure: deep dive (watch on YouTube)
Overview
Apache Subversion (SVN) is the enterprise centralized version-control system from the Apache Software Foundation. It keeps a single authoritative repository with a complete, ordered history of every change. Teams check out a working copy, commit revisions, branch and tag, and roll back to any earlier state.
History and access control live on the server rather than in every clone. This makes Subversion a natural fit for large binary assets, fine-grained path-based permissions, and organizations that want one governed source of truth.
This image serves one repository over HTTPS through Apache httpd and mod_dav_svn at /svn/repo. A self-signed TLS certificate and HTTP Basic Auth secure access, and a dedicated repository user (SecureAnyCloud) gets a strong password that is generated uniquely on first boot. There is no anonymous read or write, so every operation requires authentication.
What you get:
- Apache Subversion 1.14 (Apache-2.0) served over HTTPS by Apache httpd 2.4 and
mod_dav_svn - One FSFS repository at
/srv/svn/repo, created empty and ready to commit - A per-VM repository user, SecureAnyCloud, whose password is generated on first boot, with no shared default credential
- A per-VM self-signed TLS certificate generated on first boot. Swap it for a CA-signed certificate for production.
- Mandatory authentication on every path (
Require valid-user), with no anonymous access - An unauthenticated
/healthzendpoint for load-balancer and probe checks - 24/7 SecureAnyCloud support
Prerequisites
- An active Azure subscription.
- An SSH key pair.
- A VNet and subnet in the target region.
- Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size.
- NSG inbound rules that allow
22/tcpfrom your management network for SSH, and443/tcpfrom the clients that will access the repository over HTTPS. - Port
80/tcpis optional. It serves a landing page and redirects repository requests to HTTPS.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, and search the Marketplace for Apache Subversion by SecureAnyCloud. Select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTPS (443).
Then choose Review + create and Create.
Step 2 - Deploy from the Azure CLI
Alternatively, create the VM with the Azure CLI:
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:apachesubversionsvn-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name svn \
--image sac1647283583153:apachesubversionsvn-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku StandardOpen inbound 443/tcp, and 22/tcp for SSH, on the VM's network security group.
Step 3 - Connect to your VM
Connect over SSH with your key:
ssh azureuser@<vm-public-ip>Step 4 - Confirm Subversion is installed and serving
Apache serves the repository over HTTPS. It listens on :80 (landing page and redirect) and :443 (repository).
Check the service, the Subversion version, the listeners and the repository:
systemctl is-active apache2 svn --version --quiet ss -tln | grep -E ':80 |:443 '
sudo ls -ld /srv/svn/repoStep 5 - Retrieve your per-VM repository credentials
The repository user is SecureAnyCloud. Its password is generated uniquely on this VM's first boot and written to a root-only file. Read the file over SSH:
sudo cat /root/svn-credentials.txtThe file contains SVN_URL, SVN_USERNAME (SecureAnyCloud) and SVN_PASSWORD. These credentials are unique to this VM. Nothing is baked into the image.
Issue the certificate for your public address
First boot puts the address Azure reports into the TLS certificate and the credentials file. With a Standard SKU public IP, which is the Azure default and the --public-ip-sku Standard in Step 2, the current image records the VM's private address (10.0.0.x).
In that case SVN_URL points at an address you cannot reach. Subversion clients at the public IP report a certificate hostname mismatch on top of the self-signed warning (curl --cacert fails with error 60). Check the address:
sudo grep '^SVN_URL=' /root/svn-credentials.txtIf it shows a 10. address, issue a new certificate for the public IP on the VM. Azure's instance metadata service reports the public IP to the VM itself, and nothing leaves the VM:
PUBLIC_IP=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/loadbalancer?api-version=2020-10-01' | grep -o '"frontendIpAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
PRIV=$(hostname -I | awk '{print $1}'); echo "public $PUBLIC_IP, private $PRIV"
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/ssl/sac/sac.key -out /etc/ssl/sac/sac.crt \
-subj "/C=GB/O=sac/CN=$PUBLIC_IP" \
-addext "subjectAltName=IP:127.0.0.1,IP:$PRIV,IP:$PUBLIC_IP"
sudo chmod 0600 /etc/ssl/sac/sac.key
sudo sed -i "s/\b$PRIV\b/$PUBLIC_IP/g" /root/svn-credentials.txt
sudo systemctl reload apache2The certificate carries IP entries only. The svn client matches an IP address in the URL against the certificate's common name, and it ignores IP entries whenever a DNS entry is present.
For a DNS name, set PUBLIC_IP to the name and write DNS:$PUBLIC_IP in place of IP:$PUBLIC_IP. Your credentials do not change.
The certificate is still self-signed. Accept it once, or trust it on each workstation with the ssl-authority-files setting in the Subversion servers file, until you install a CA-signed one (Step 10).
Step 6 - Confirm access requires authentication (secure by default)
Subversion is served behind mandatory HTTP Basic Auth. An anonymous request and a wrong password are both rejected with 401. Only the per-VM password authenticates. The commands below read the real password from the credentials file:
SVN_PASS=$(sudo grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-)
curl -ks -o /dev/null -w 'anonymous request : HTTP %{http_code}\n' https://127.0.0.1/svn/repo/
curl -ks -o /dev/null -w 'wrong password : HTTP %{http_code}\n' -u sac:wrong-password https://127.0.0.1/svn/repo/
curl -ks -o /dev/null -w 'per-VM credentials : HTTP %{http_code}\n' -u "sac:$SVN_PASS" https://127.0.0.1/svn/repo/The output is 401, 401, then 200. This proves that anonymous and wrong-password access are refused and only the per-VM credentials succeed.
Step 7 - Check out the repository and commit a change
The repository is empty and ready to use. From an SSH session on the VM, check it out, add a file and commit. Everything runs over HTTPS with your per-VM credentials.
The first-boot certificate is self-signed, so the commands below trust it explicitly with --trust-server-cert-failures:
SVN_PASS=$(sudo grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-) T="--non-interactive --trust-server-cert-failures=unknown-ca,cn-mismatch,expired,not-yet-valid,other --no-auth-cache"
WORK=$(mktemp -d) svn checkout $T --username sac --password "$SVN_PASS" https://127.0.0.1/svn/repo "$WORK/repo" NOTE="release-notes-$(date -u +%Y%m%d-%H%M%S).txt" echo "First commit from sac" > "$WORK/repo/$NOTE" svn add $T "$WORK/repo/$NOTE" svn commit $T --username sac --password "$SVN_PASS" -m "Add $NOTE" "$WORK/repo" svn log $T --username sac --password "$SVN_PASS" "$WORK/repo" rm -rf "$WORK"From a workstation, run svn checkout https://<vm-ip>/svn/repo --username SecureAnyCloud instead. Enter the password when prompted, and accept the self-signed certificate the first time.
Step 8 - How the credentials are protected
There is no default password. The SecureAnyCloud user's password is generated per VM on first boot and stored bcrypt-hashed in Apache's AuthUserFile. The plaintext is written only to a root-owned 0600 file and never ships inside the image:
sudo stat -c 'file: %n perms: %a owner: %U:%G' /root/svn-credentials.txt
sudo stat -c 'file: %n perms: %a owner: %U:%G' /etc/apache2/svn.htpasswd
sudo sed -E 's/(sac:\$2[aby]\$[0-9]{2}\$.{6}).*/\1********************/' /etc/apache2/svn.htpasswdThe credentials file is 0600 root:root, the .htpasswd stores a bcrypt hash (not the plaintext), and only root and the Apache worker can read it.
Step 9 - Add repository users
Each repository user is an entry in Apache's AuthUserFile. Add another user and enter their password when prompted. They can then check out and commit exactly like sac:
sudo htpasswd -B /etc/apache2/svn.htpasswd alice
sudo systemctl reload apache2For read-only or per-path permissions, configure mod_authz_svn with an access file (AuthzSVNAccessFile) in the <Location /svn/repo> block of /etc/apache2/sites-available/000-sac-ssl.conf.
Step 10 - Use a CA-signed certificate for production
The first-boot certificate is self-signed, so clients must trust it explicitly. For production, point a DNS name at the VM and install a CA-signed certificate, for example with Certbot. This removes the certificate warning for every client:
sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d svn.example.comAfter Certbot installs the certificate, svn checkout https://svn.example.com/svn/repo works without the --trust-server-cert-failures flag.
Step 11 - Back up the repository
Take a portable dump of the whole repository history at any time. Store the dump off the VM, for example in Azure Blob Storage, as your backup:
sudo svnadmin dump /srv/svn/repo > /tmp/svn-repo-backup.dump ls -lh /tmp/svn-repo-backup.dumpRestore into a fresh repository with svnadmin load. See the Subversion book for repository administration and hook scripts.
Support
Every SecureAnyCloud image comes with 24/7 support. Email sales@secureanycloud.com or visit secureanycloud.com for documentation and assistance.
Deploy on Azure
Launch Apache Subversion (SVN) on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Apache Subversion (SVN) is the Apache Software Foundation's enterprise centralized version-control system. It keeps a single authoritative repository that stores every version of your files and directories, with atomic commits, branching and tagging, and a complete, queryable history.
This image runs Apache Subversion 1.14 behind HTTPS, with authentication required and a unique password generated on every instance.
What you get:
- The repository is served over HTTPS on port 443 by the Apache HTTP Server with the
mod_dav_svnWebDAV module andmod_authz_svn. - A fresh empty FSFS repository is provisioned at
/srv/svn/repoon a dedicated EBS data volume mounted at/srv/svn. The volume is separate from the operating system disk and independently resizable. - The repository is owned by the Apache service account, so commits are written safely.
- Access is authenticated by default. All repository operations require the repository credentials over HTTP Basic Auth, backed by a bcrypt password file. There is no anonymous read or write.
- An unauthenticated static health endpoint answers at
/healthzfor load-balancer and uptime checks. - Plain HTTP on port 80 serves a landing page and redirects repository clients to HTTPS.
Subversion has no built-in shared password, so this image generates one per instance. A one-shot first-boot service creates a unique repository password of 24 characters and generates a per-instance self-signed TLS certificate. It writes the bcrypt-hashed password into the Apache authentication file and records the plaintext in /root/svn-credentials.txt with mode 0600.
The first-boot service proves the authentication gate and a full commit round-trip before it reports ready. No shared or default credentials or certificates ship in the image.
Prerequisites
Before you deploy this image, you need the following:
- An Amazon Web Services account where you can launch EC2 instances.
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products.
- An EC2 key pair in the target Region for SSH access to the instance.
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network, and ports 80 and 443 from the clients that will use the repository.
- An SSH client on your workstation, and the Subversion command-line client (
svn) where you intend to work with the repository.
Launching from the AWS Marketplace
- Open the product page in AWS Marketplace and choose Continue to Subscribe.
- Accept the terms, then choose Continue to Configuration.
- Select the software version and the Region you want to deploy into, then choose Continue to Launch.
- Choose Launch through EC2 for full control of networking and storage.
- Pick an instance type.
m5.largeis the recommended minimum. Scale up as your repository size and commit concurrency grow. - Select your VPC, subnet and key pair.
- Attach a security group that allows inbound TCP 22 from your management network, and TCP 80 and 443 from the clients that will check out and commit.
- Launch, and wait for the instance to reach the 2/2 checks passed state.
Launching with the AWS CLI
Substitute your own AMI id, key pair, security group and subnet:
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <your-key-pair> \
--security-group-ids <your-sg-id> \
--subnet-id <your-subnet-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=subversion}]'Connecting to your instance
Connect over SSH on port 22 as the default login user for the operating system variant you launched. For Ubuntu 24.04 LTS, the SSH login user is ubuntu:
ssh -i /path/to/your-key.pem ubuntu@<public-ip>First boot takes a few moments to generate the repository password and the TLS certificate. If the credentials file does not yet show the generated password, wait a few seconds and read it again.
Retrieving the repository credentials
The per-instance repository password is written to a root-only file on first boot:
sudo cat /root/svn-credentials.txtThe file contains the repository URL, the username SecureAnyCloud and the generated password:
# Apache Subversion (SVN) - generated on first boot by svn-firstboot.service
# These credentials are unique to this instance. Store them somewhere safe. SVN_URL=https://<this-instance-public-ip>/svn/repo SVN_USERNAME=sac SVN_PASSWORD=<generated-on-first-boot>Load the password into a shell variable rather than printing it. This keeps it out of your shell history and terminal scrollback. The commands in the rest of this guide use $PW:
PW=$(grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-) if [ -n "$PW" ]; then echo "repository password loaded (${#PW} characters)"; else echo "not yet generated"; firepository password loaded (24 characters)Confirm the file is readable only by root:
stat -c '%a %U:%G' /root/svn-credentials.txt600 root:rootVerifying the repository is running
Confirm the Apache service is active and serving the repository, and that Subversion is installed:
systemctl is-active apache2.service svn --version --quietactive 1.14.3Both listeners are up: HTTPS on 443 for the repository and HTTP on 80 for the landing page and redirect:
ss -tln | grep -E ':80 |:443 'LISTEN 0 511 *:443 *:* LISTEN 0 511 *:80 *:*The unauthenticated health endpoint answers 200 for load-balancer and uptime checks:
curl -ks -o /dev/null -w 'healthz HTTP %{http_code}\n' https://127.0.0.1/healthzhealthz HTTP 200The repository store lives on its own data disk, mounted at /srv/svn:
df -h /srv/svn | tail -1/dev/nvme1n1 40G 208K 38G 1% /srv/svnThe authentication gate
The repository requires authentication for every operation. An unauthenticated request, or one with the wrong password, is rejected with 401:
curl -ks -o /dev/null -w 'unauthenticated: HTTP %{http_code}\n' https://127.0.0.1/svn/repo/
curl -ks -o /dev/null -w 'wrong password: HTTP %{http_code}\n' -u sac:definitely-wrong-pw https://127.0.0.1/svn/repo/unauthenticated: HTTP 401 wrong password: HTTP 401The correct per-instance password authenticates, and svn info returns the repository metadata:
PW=$(grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-) T='--non-interactive --trust-server-cert-failures=unknown-ca,cn-mismatch,expired,not-yet-valid,other --no-auth-cache' svn info $T --username sac --password "$PW" https://127.0.0.1/svn/repo | grep -E 'Repository Root|Repository UUID|Revision'Repository Root: https://127.0.0.1/svn/repo Repository UUID: 5bdb054c-fc2a-448e-9c5b-2bc0bf0f18b1 Revision: 0Checking out and committing
Prove that the repository round-trips a real commit. This checks out a working copy, adds a file, commits it and reads it back from the log. It uses $PW, so the password is never echoed:
PW=$(grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-) T='--non-interactive --trust-server-cert-failures=unknown-ca,cn-mismatch,expired,not-yet-valid,other --no-auth-cache'
WD=$(mktemp -d) svn co $T --username sac --password "$PW" https://127.0.0.1/svn/repo "$WD/wc" | tail -1 printf 'hello from svn %s\n' "$(date -u +%s)" > "$WD/wc/hello-$(date -u +%s).txt" svn add $T "$WD/wc"/hello-*.txt | head -1 svn ci $T --username sac --password "$PW" -m 'guide commit round-trip' "$WD/wc" | tail -1 svn log $T --username sac --password "$PW" https://127.0.0.1/svn/repo | head -3 rm -rf "$WD"Checked out revision 0. A /tmp/tmp.XXXX/wc/hello-1753178951.txt Committed revision 1. ------------------------------------------------------------------------ r1 | sac | 2026-07-22 10:09:11 +0000 (Wed, 22 Jul 2026) | 1 lineEvery access above was authenticated. There is no anonymous path to the repository.
Using the repository from your workstation
From any machine that can reach the instance on port 443, check out the repository with the standard Subversion client. Replace <public-ip> with your instance's public IP or DNS name. Use the username SecureAnyCloud and the password from the credentials file:
svn checkout https://<public-ip>/svn/repo my-working-copy --username sacOn first connection, the client prompts you to accept the per-instance self-signed certificate. From then on, you work with the repository exactly as with any Subversion server:
cd my-working-copy echo "release notes" > NOTES.txt svn add NOTES.txt svn commit -m "add release notes" svn update svn logThe same URL serves both checkout and commit. Point your CI jobs and existing Subversion tooling at it.
Replacing the self-signed certificate
The image ships with a per-instance self-signed certificate, so the repository is encrypted from the very first boot. For production, replace it with a certificate from your own certificate authority or a public CA. Clients then validate it without a trust exception.
The HTTPS virtual host at /etc/apache2/sites-available/000-sac-ssl.conf references the certificate and key:
SSLCertificateFile /etc/ssl/sac/sac.crt SSLCertificateKeyFile /etc/ssl/sac/sac.keyInstall your certificate and private key over those two files, or point the directives at new paths. Keep the key readable only by root, then reload Apache:
sudo install -m 0644 your-fullchain.crt /etc/ssl/sac/sac.crt
sudo install -m 0600 your-private.key /etc/ssl/sac/sac.key
sudo apachectl configtest
sudo systemctl reload apache2If you use a public DNS name for the repository, issue the certificate for that name and give it to your clients as the repository host.
Backup and maintenance
The repository is a standard FSFS Subversion repository under /srv/svn/repo. Take a consistent, portable dump of the full history with svnadmin dump, which is safe to run against a live repository:
sudo svnadmin dump /srv/svn/repo | gzip > svn-repo-$(date -u +%Y%m%d).svndump.gzRestore into a fresh repository with svnadmin load.
The repository lives on its own EBS volume mounted at /srv/svn. You can also snapshot that volume from the EC2 console or CLI for block-level backups. You can grow it independently of the operating system disk as your history expands.
Keep the operating system patched with the distribution's normal update mechanism, and monitor the service with:
systemctl status apache2.service --no-pager | head -3● apache2.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled) Active: active (running)Support
SecureAnyCloud publishes and supports this image. Technical support is available 24/7 by email and chat at sales@secureanycloud.com.
We can help with deployment, repository layout and access control, replacing the TLS certificate, integrating clients and CI, storage sizing, and backup or upgrade planning.
Apache, Apache Subversion and the Apache feather logo are trademarks of the Apache Software Foundation. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch Apache Subversion (SVN) on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com