ThisCalculator

Everyday

How to Store Gitea Repositories on a Separate Volume

Updated · Standard formula, shown below

How to Store Gitea Repositories on a Separate Volume

This guide explains how to configure Gitea so that all repository data (bare Git repos, wiki data, and attachments) is stored on a separate disk or volume rather than the system root. This is useful for keeping backups isolated, expanding storage independently, or improving performance on a dedicated drive. You will need root or sudo access to your Gitea server and a mounted volume ready to use.

What You’ll Need

  • A server with Gitea already installed (via binary, Docker, or package manager).
  • A separate volume (e.g., an extra disk, partition, or network mount) that is already formatted and mounted to a directory like /mnt/gitea-data.
  • Root or sudo access to edit Gitea’s configuration file and move files.
  • Basic familiarity with the command line.

Step-by-Step

  1. Stop Gitea to ensure no data is written during the move. Use your service manager: sudo systemctl stop gitea (if using systemd) or sudo service gitea stop. For Docker, run docker-compose stop or docker stop gitea-container.
  2. Locate the current repository root. Open Gitea’s configuration file (usually /etc/gitea/app.ini or /var/lib/gitea/custom/conf/app.ini) and find the [repository] section. Look for ROOT; the default is often /var/lib/gitea/data/repositories or /home/git/repositories. Note this path.
  3. Create a mount point if you haven’t already: sudo mkdir -p /mnt/gitea-data. Ensure the volume is mounted there and has proper ownership. For example, if your Gitea user is git, run sudo chown git:git /mnt/gitea-data.
  4. Copy the existing repositories to the new volume. Use rsync to preserve permissions and ownership: sudo rsync -av /var/lib/gitea/data/repositories/ /mnt/gitea-data/repositories/. Include the trailing slash to copy the contents into the target directory.
  5. Verify the copy by checking file counts and sizes: sudo du -sh /mnt/gitea-data/repositories and compare with the original. Also check that the git user owns the files: ls -l /mnt/gitea-data/repositories.
  6. Move the old directory aside (do not delete yet) to test the new configuration: sudo mv /var/lib/gitea/data/repositories /var/lib/gitea/data/repositories.bak.
  7. Create a symlink from the original location to the new volume. This is the simplest method and avoids changing Gitea’s config: sudo ln -s /mnt/gitea-data/repositories /var/lib/gitea/data/repositories. Ensure the symlink owner is git (or the Gitea user): sudo chown -h git:git /var/lib/gitea/data/repositories.
  8. Start Gitea again: sudo systemctl start gitea. Watch the logs for errors: journalctl -u gitea -f (systemd) or docker logs gitea-container.
  9. Test thoroughly: clone a repository, create a new one, push a commit, and check that the wiki and attachments work. If everything works, you can remove the backup: sudo rm -rf /var/lib/gitea/data/repositories.bak. If something fails, you can revert by removing the symlink and renaming the backup back.

Common Mistakes

  • Forgetting to stop Gitea before copying. This can lead to inconsistent data or lost changes.
  • Copying with the wrong ownership. If the files are owned by root, Gitea (running as git) will fail to read or write them.
  • Using cp instead of rsync. cp may not preserve all permissions or handle symlinks correctly.
  • Not updating the symlink owner. The symlink itself must be owned by the Gitea user, otherwise it may be inaccessible.
  • Deleting the old directory too soon. Always keep a backup until you’ve verified the new setup works.

Tips

  • If you prefer not to use a symlink, you can edit app.ini and change ROOT under [repository] to /mnt/gitea-data/repositories. Then restart Gitea. This is cleaner but requires an extra step.
  • Consider also moving the LFS data (if you use Git LFS) and the attachments folder. These are typically under the same data directory. You can set LFS.PATH and ATTACHMENT.PATH in app.ini to point to the new volume.
  • If your volume is formatted with a filesystem that doesn’t support Unix permissions (like some network mounts), you may need to mount it with options that preserve ownership (e.g., uid=git,gid=git for NFS).
  • Set up a cron job to back up the new volume regularly, since it now holds all your repositories.

Troubleshooting

  • Gitea won’t start after the change. Check the logs. The most common cause is a permission error. Run sudo -u git ls -la /mnt/gitea-data/repositories to see if the git user can access the directory. If not, fix ownership with chown -R git:git /mnt/gitea-data.
  • Repositories appear empty or missing. This usually means the symlink is broken or pointing to an empty directory. Check the symlink target with readlink and verify the copy actually contains the *.git folders.
  • Push/pull operations fail with permission denied. The Gitea user needs write access to the volume. Ensure the mount is not read-only (check with mount | grep gitea-data) and that the directory ownership is correct.
  • Gitea starts but shows 500 errors. Look for errors in the Gitea log (usually in /var/log/gitea or via journalctl). A common issue is that the symlink is not being followed because of AppArmor or SELinux. You may need to adjust the security policy to allow Gitea to read from the new path.
  • All repositories are gone after a reboot. This suggests the volume is not mounted automatically. Add an entry to /etc/fstab to mount the volume at boot.

Frequently Asked Questions

Can I use a Docker volume instead of a host directory?

Yes. If Gitea runs in Docker, you can mount a named volume or a host directory to the container’s data path (e.g., -v /mnt/gitea-data:/data). The same principles apply: stop the container, copy data, and restart.

Do I need to move the entire /var/lib/gitea directory?

No, only the repositories folder is required for Git data. However, if you also want to move attachments, LFS objects, or the database (if using SQLite), you can move those separately and update their paths in app.ini.

Will this affect my existing clones?

No. The URL and SSH endpoints remain the same. Clones will continue to work as long as the Gitea service can access the repository files.

How do I know the move was successful?

After the move, create a new repository, clone it, and push a commit. Also check the Gitea admin panel under “Repository� to see that all existing repos are listed. If you see errors, revert the symlink and restore the backup.

Can I move repositories while Gitea is running?

It is not recommended. Doing so can cause data corruption because Gitea may be writing to files during the copy. Always stop the service first.

What if I don’t have a separate volume yet?

You can create a loopback file or use a cloud block storage volume. The process is the same once the volume is mounted to a directory.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.