How to Set Up Gitea on Windows Server 2012 R2

Gitea is a lightweight, self-hosted Git service written in Go that provides a GitHub-like web interface for managing repositories, issues, pull requests, and CI/CD pipelines. It is an excellent choice for organizations that need an on-premises Git server without the complexity and licensing cost of GitLab or the resource requirements of Gogs. On Windows Server 2012 R2, Gitea runs as a native Windows service with minimal resource overhead — a typical installation uses under 100 MB of RAM at idle — making it suitable even for smaller servers. This guide covers downloading and installing Gitea, configuring it as a Windows service, setting up the database backend, and performing initial repository setup.

Prerequisites

  • Windows Server 2012 R2 with administrator access
  • PowerShell 4.0
  • At least 512 MB RAM available for Gitea (more for active teams)
  • Git for Windows installed (for repository operations)
  • A database backend: SQLite (built in, suitable for small teams), MySQL, PostgreSQL, or MSSQL
  • An inbound firewall rule allowing TCP port 3000 (or your chosen HTTP port)

Step 1: Create a Dedicated Service Account

Gitea should run as a dedicated local user account rather than SYSTEM or Administrator:

net user gitea_svc "Gitea$Svc#2024!" /add /comment:"Gitea Service Account" /passwordchg:no /expires:never
net localgroup Users gitea_svc /add

Step 2: Create Directory Structure

New-Item -ItemType Directory -Path "C:Giteabin"      -Force
New-Item -ItemType Directory -Path "C:Giteadata"     -Force
New-Item -ItemType Directory -Path "C:Gitearepos"    -Force
New-Item -ItemType Directory -Path "C:Gitealog"      -Force
New-Item -ItemType Directory -Path "C:Giteacustomconf" -Force

# Grant the service account full control over the Gitea directory
$acl = Get-Acl "C:Gitea"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("gitea_svc","FullControl","ContainerInherit,ObjectInherit","None","Allow")
$acl.SetAccessRule($rule)
Set-Acl "C:Gitea" $acl

Step 3: Download Gitea Binary

Gitea is a single executable with no installer. Download the latest Windows AMD64 binary:

$GiteaVersion = "1.22.1"
$GiteaUrl = "https://github.com/go-gitea/gitea/releases/download/v${GiteaVersion}/gitea-${GiteaVersion}-windows-4.0-amd64.exe"

Invoke-WebRequest -Uri $GiteaUrl -OutFile "C:Giteabingitea.exe"

Verify the binary is executable:

C:Giteabingitea.exe --version

Step 4: Create the Gitea Configuration File

Create the initial configuration file at C:Giteacustomconfapp.ini. This file controls all aspects of Gitea’s behavior:

$AppIni = @"
APP_NAME = Our Internal Gitea
RUN_USER = gitea_svc
RUN_MODE = prod
WORK_PATH = C:/Gitea/data

[server]
PROTOCOL         = http
HTTP_ADDR        = 0.0.0.0
HTTP_PORT        = 3000
ROOT_URL         = http://gitserver.domain.local:3000/
DOMAIN           = gitserver.domain.local
APP_DATA_PATH    = C:/Gitea/data
SSH_DOMAIN       = gitserver.domain.local
SSH_PORT         = 22
START_SSH_SERVER = false
DISABLE_SSH      = false

[database]
DB_TYPE  = sqlite3
PATH     = C:/Gitea/data/gitea.db

[repository]
ROOT = C:/Gitea/repos

[log]
ROOT_PATH = C:/Gitea/log
MODE      = file
LEVEL     = Info

[security]
INSTALL_LOCK       = false
SECRET_KEY         = $(New-Guid)$(New-Guid) -replace '-',''
INTERNAL_TOKEN     =
PASSWORD_HASH_ALGO = pbkdf2

[service]
REGISTER_EMAIL_CONFIRM            = false
ENABLE_NOTIFY_MAIL                = false
DISABLE_REGISTRATION              = false
ALLOW_ONLY_EXTERNAL_REGISTRATION  = false
ENABLE_CAPTCHA                    = false
REQUIRE_SIGNIN_VIEW               = false
DEFAULT_KEEP_EMAIL_PRIVATE        = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING       = true
NO_REPLY_ADDRESS                  = [email protected]

[mailer]
ENABLED = false
"@

Set-Content -Path "C:Giteacustomconfapp.ini" -Value $AppIni -Encoding UTF8
Write-Host "app.ini created"

Step 5: Install Gitea as a Windows Service

Download NSSM (Non-Sucking Service Manager) to wrap the Gitea executable as a Windows service, which provides proper service lifecycle management including automatic restart on failure:

Invoke-WebRequest -Uri "https://nssm.cc/release/nssm-2.24.zip" -OutFile "C:Tempnssm.zip"
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:Tempnssm.zip","C:Tempnssm")
Copy-Item "C:Tempnssmnssm-2.24win64nssm.exe" "C:WindowsSystem32nssm.exe"

Install the Gitea service:

nssm install Gitea "C:Giteabingitea.exe"
nssm set Gitea AppParameters "web --config C:Giteacustomconfapp.ini"
nssm set Gitea AppDirectory "C:Gitea"
nssm set Gitea DisplayName "Gitea Git Service"
nssm set Gitea Description "Self-hosted Git service"
nssm set Gitea Start SERVICE_AUTO_START
nssm set Gitea ObjectName ".gitea_svc" "Gitea$Svc#2024!"
nssm set Gitea AppStdout "C:Gitealoggitea-stdout.log"
nssm set Gitea AppStderr "C:Gitealoggitea-stderr.log"
nssm set Gitea AppRotateFiles 1
nssm set Gitea AppRotateSeconds 86400

Step 6: Open Firewall Port

New-NetFirewallRule -DisplayName "Gitea HTTP" -Direction Inbound -Protocol TCP -LocalPort 3000 -Action Allow

Step 7: Start Gitea and Complete Web Setup

nssm start Gitea
Start-Sleep -Seconds 5
Get-Service Gitea | Select-Object Name, Status

Open a browser and navigate to http://localhost:3000. Gitea will display the installation wizard. Most settings are pre-populated from app.ini. On the web form:

  • Confirm the database path and type (SQLite3 for small deployments)
  • Set the site title and base URL
  • Create the admin account with a strong password
  • Click Install Gitea

After the wizard completes, Gitea updates app.ini with INSTALL_LOCK = true to prevent the setup wizard from running again.

Step 8: Create Your First Repository

Log into the Gitea web interface with the admin account. Click the + icon in the top right and select New Repository. Fill in the repository name, description, and initialization options (add a README, .gitignore, and license).

Clone the repository from the Windows server itself:

git clone http://admin:YourPassword@localhost:3000/admin/myrepo.git "C:Reposmyrepo"
Set-Location "C:Reposmyrepo"
git status

Step 9: Configure Automated Backups

Back up the Gitea data directory and database on a schedule:

$backupScript = @'
$BackupRoot = "\backupservergitea"
$Date = Get-Date -Format "yyyyMMdd_HHmm"
$BackupDir = "$BackupRoot$Date"
New-Item -ItemType Directory -Path $BackupDir -Force

# Stop Gitea for consistent backup
Stop-Service Gitea
Start-Sleep -Seconds 3

# Backup data and repos
robocopy "C:Giteadata" "$BackupDirdata" /MIR /NFL /NDL
robocopy "C:Gitearepos" "$BackupDirrepos" /MIR /NFL /NDL
robocopy "C:Giteacustom" "$BackupDircustom" /MIR /NFL /NDL

# Start Gitea
Start-Service Gitea

# Remove backups older than 14 days
Get-ChildItem $BackupRoot -Directory | Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-14) } | Remove-Item -Recurse -Force
'@

$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NonInteractive -Command `"$backupScript`""
$trigger = New-ScheduledTaskTrigger -Daily -At "03:30AM"
Register-ScheduledTask -TaskName "GiteaBackup" -Action $action -Trigger $trigger -RunLevel Highest

Summary

Gitea is now running as a Windows service on Windows Server 2012 R2, providing a full-featured self-hosted Git platform with web interface, repository management, user authentication, and SSH/HTTPS access. The installation uses SQLite for simplicity (upgradeable to MySQL or PostgreSQL for larger teams), NSSM for robust service management with log rotation, and a scheduled backup that ensures repository data is protected. Gitea’s low resource footprint makes it ideal for on-premises environments where dedicated Git infrastructure is needed without the overhead of enterprise solutions.