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.