# Authentication
Source: https://gogs.io/advancing/authentication
Integrate with your existing IAM system
Gogs supports authentication through various external sources. Currently supported backends are **LDAP**, **SMTP**, **PAM**, and **HTTP header**. Authentication sources can be configured in two ways:
* **Admin Panel**: Navigate to **Admin Panel > Authentication Sources**
* **Configuration files**: Place `.conf` files in the `custom/conf/auth.d/` directory. Each file describes one source using INI format. Files are loaded once at startup and keyed by `id`. See the "Configuration file" subsection under each backend below for examples.
## LDAP
Gogs supports two variants of LDAP authentication: **Simple Auth** and **Bind DN**. In both cases, authentication is performed by attempting to bind to the LDAP server with the User DN and password. The difference is that with Bind DN, a preliminary query is performed (using the Bind DN credentials) to find the User DN first.
The Bind DN mechanism has these advantages:
* It may be more secure than blindly attempting to bind with a possibly non-existent User DN.
* It supports login with attributes such as email address or phone number. The preliminary search can look up the User DN using `mail` or `mobile` attributes.
* It is required when the LDAP does not allow the User DN to query its own attributes or group memberships.
The downside is that, unless the LDAP allows anonymous queries, it requires a bind DN to be defined and Gogs needs to store its credentials. Gogs currently does not encrypt these credentials.
In the ideal situation where you know the exact DN template for your users and the LDAP allows the User DN to query its own attributes, Simple Auth is the simpler option. It requires no separate bind account and no stored credentials beyond what the user provides at login.
### Shared fields
The following fields are shared between both **Bind DN** and **Simple Auth** configurations:
| Field | Required | Description | Example |
| ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| **Authentication Name** | Yes | A friendly name for the authentication source. | `My LDAP` |
| **Security Protocol** | Yes | Connection security: Unencrypted, LDAPS, or StartTLS. | `LDAPS` |
| **Host** | Yes | The address of the LDAP server. | `ldap.mydomain.com` |
| **Port** | Yes | The port for the LDAP connection. Usually `389` for LDAP/StartTLS, `636` for LDAPS. | `389` |
| **User Filter** | Yes | An LDAP filter declaring which users can log in. The `%s` parameter is substituted with the login name. | `(&(objectClass=posixAccount)(uid=%s))` |
| **Email Attribute** | Yes | The LDAP attribute containing the user's email address. | `mail` |
| **Admin Filter** | No | An LDAP filter applied to the User DN context to determine Gogs administrator privileges. | `(memberOf=cn=admins,cn=groups,dc=mydomain,dc=com)` |
| **Username Attribute** | No | The LDAP attribute containing the username. Used for the Gogs account name after first sign-in. Leave empty to use the login name from the sign-in form. | `uid` |
| **First Name Attribute** | No | The LDAP attribute containing the user's first name. | `givenName` |
| **Surname Attribute** | No | The LDAP attribute containing the user's last name. | `sn` |
The **User Filter** field can be used to filter on group membership if the User DN object has `memberOf` attributes. For example:
```
(&(objectClass=posixAccount)(uid=%s)(memberOf=cn=gogs_users,cn=groups,dc=mydomain,dc=com))
```
In the Bind DN authenticator, the User Filter can also match against multiple user attributes:
```
(&(objectClass=Person)(|(uid=%s)(mail=%s)(mobile=%s)))
```
### Simple Auth fields
LDAP via Simple Auth adds the following field:
| Field | Required | Description | Example |
| ----------- | -------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| **User DN** | Yes | A template for the user's DN. The `%s` parameter is substituted with the login name. | `cn=%s,ou=Users,dc=mydomain,dc=com` or `uid=%s,ou=Users,dc=mydomain,dc=com` |
### Bind DN fields
LDAP via Bind DN adds the following fields:
| Field | Required | Description | Example |
| --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- | ------------------------------ |
| **Bind DN** | No | The DN used to bind to the LDAP server when searching for the user. Leave blank for anonymous search. | `cn=Search,dc=mydomain,dc=com` |
| **Bind Password** | No | The password for the Bind DN specified above. | -- |
| **User Search Base** | Yes | The LDAP base below which user accounts will be searched. | `ou=Users,dc=mydomain,dc=com` |
| **Fetch Attributes in Bind DN Context** | No | When enabled, user attributes are retrieved while bound as the Bind DN instead of the User DN. | -- |
The Bind Password is stored in plaintext on the server. Ensure that your Bind DN has the minimum privileges necessary.
### Group membership verification
You can optionally verify LDAP group membership using the following fields:
| Field | Required | Description | Example |
| -------------------------------------------- | -------- | ----------------------------------------------------------------- | -------------------------------- |
| **Group Search Base DN** | No | The LDAP base below which groups will be searched. | `ou=group,dc=mydomain,dc=com` |
| **Group Filter** | No | An LDAP filter declaring the groups that grant access. | `(\|(cn=gogs_users)(cn=admins))` |
| **Group Attribute Containing List of Users** | No | The multi-valued attribute containing the group's members. | `memberUid` or `member` |
| **User Attribute Listed in Group** | No | The user attribute referenced in the group membership attributes. | `uid` or `dn` |
### Configuration files
LDAP sources can also be defined as `.conf` files in `custom/conf/auth.d/` instead of through the admin panel. Files are loaded at startup and keyed by `id`.
```ini theme={null}
id = 101
type = ldap_bind_dn
name = LDAP BindDN
is_activated = true
[config]
host = mydomain.com
port = 636
# 0 - Unencrypted, 1 - LDAPS, 2 - StartTLS
security_protocol = 0
skip_verify = false
bind_dn =
bind_password =
user_base = ou=Users,dc=mydomain,dc=com
attribute_username =
attribute_name =
attribute_surname =
attribute_mail = mail
attributes_in_bind = false
filter = (&(objectClass=posixAccount)(cn=%s))
admin_filter =
group_enabled = false
group_dn =
group_filter =
group_member_uid =
user_uid =
```
```ini theme={null}
id = 102
type = ldap_simple_auth
name = LDAP Simple Auth
is_activated = true
[config]
host = mydomain.com
port = 636
# 0 - Unencrypted, 1 - LDAPS, 2 - StartTLS
security_protocol = 0
skip_verify = false
bind_dn =
bind_password =
user_base =
user_dn = cn=%s,ou=Users,dc=mydomain,dc=com
attribute_username =
attribute_name =
attribute_surname =
attribute_mail = mail
attributes_in_bind = false
filter = (&(objectClass=posixAccount)(cn=%s))
admin_filter =
group_enabled = false
group_dn =
group_filter =
group_member_uid =
user_uid =
```
### FreeIPA examples
It is possible to use either Bind DN or Simple Auth with FreeIPA. The examples below assume your domain is `domain.com` and that users must be a member of the `gogs_users` group to get access.
Setting up access using Simple Auth is straightforward:
```ini theme={null}
user_dn = uid=%s,cn=users,cn=accounts,dc=domain,dc=com
filter = (&(objectClass=posixAccount)(memberOf=cn=gogs_users,cn=groups,cn=accounts,dc=domain,dc=com))
attribute_username = uid
attribute_name = givenName
attribute_surname = sn
attribute_mail = mail
admin_filter = (memberOf=cn=admins,cn=groups,cn=accounts,dc=domain,dc=com)
group_enabled = false
```
If you want to allow login by email address, note that FreeIPA by default does not grant anonymous search access to the `mail` attribute. This can be changed in IPA:
```bash theme={null}
ipa permission-mod --includedattrs=mail 'System: Read User Standard Attributes'
```
Alternatively, you can ask your LDAP administrators for a dedicated bind user account.
Allowing email-based login via Bind DN may no longer be necessary. Gogs translates email logins to the corresponding user ID before making the authentication call to the backend LDAP. The only requirement is that the user's **first login** is with their user ID. After that, they can use either user ID or email address.
More precisely, Gogs maps the login name onto the user's "Authentication Login Name", which administrators can edit on the user's **Edit Account** page.
## PAM
To configure PAM authentication, set the **PAM Service Name** to a filename in `/etc/pam.d/`.
If you want PAM authentication to work with normal Linux passwords, the user running Gogs must have read access to `/etc/shadow`.
### Configuration file
```ini theme={null}
id = 104
type = pam
name = System Auth
is_activated = true
[config]
service_name = system-auth
```
## SMTP
SMTP authentication allows Gogs to log in to your SMTP host to verify user credentials. Configure the following fields:
| Field | Required | Description | Example |
| ------------------------------------ | -------- | -------------------------------------------------------------------------------- | ---------------------- |
| **Authentication Name** | Yes | A name for this authentication source. | `Company SMTP` |
| **SMTP Authentication Type** | Yes | The authentication type: `PLAIN` or `LOGIN`. | `PLAIN` |
| **Host** | Yes | The address of the SMTP server. | `smtp.mydomain.com` |
| **Port** | Yes | The port for the SMTP connection. | `587` |
| **Allowed Domains** | No | Restrict login to specific email domains. Separate multiple domains with commas. | `gogs.io,mydomain.com` |
| **Enable TLS Encryption** | No | Enable TLS encryption for the authentication connection. | -- |
| **Skip TLS Verify** | No | Disable TLS certificate verification. | -- |
| **This Authentication is Activated** | No | Enable or disable this authentication method. | -- |
### Configuration file
```ini theme={null}
id = 103
type = smtp
name = GMail
is_activated = true
[config]
# Either "PLAIN" or "LOGIN"
auth = PLAIN
host = smtp.gmail.com
port = 587
allowed_domains =
tls = true
skip_verify = false
```
## HTTP header
If your reverse proxy already handles user authentication (e.g. via SSO, OAuth, or client certificates), Gogs can trust the authenticated username from an HTTP header. This is configured in `custom/conf/app.ini` under `[auth]`:
```ini theme={null}
[auth]
ENABLE_REVERSE_PROXY_AUTHENTICATION = true
REVERSE_PROXY_AUTHENTICATION_HEADER = X-WEBAUTH-USER
```
| Option | Default | Description |
| ---------------------------------------- | ---------------- | -------------------------------------------------------------------- |
| `ENABLE_REVERSE_PROXY_AUTHENTICATION` | `false` | Enable reading the authenticated username from a request header. |
| `REVERSE_PROXY_AUTHENTICATION_HEADER` | `X-WEBAUTH-USER` | The HTTP header containing the authenticated username. |
| `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION` | `false` | Automatically create a Gogs account for users that do not yet exist. |
When auto-registration is enabled, Gogs creates new accounts with an activated status and a placeholder email address. The user can update their email after first login.
Only enable this feature if Gogs is exclusively accessed through a trusted reverse proxy that sets the header. Exposing Gogs directly to the internet with this enabled would allow anyone to impersonate any user by setting the header themselves.
# CLI reference
Source: https://gogs.io/advancing/cli-reference
Discover all the commands available in the gogs binary
Most people know `gogs web` for starting the server, but the `gogs` binary ships with several other commands that help you manage your instance from the command line.
Run `gogs --help` at any time to see the full list of available commands, and `gogs --help` for details on a specific command.
Every command accepts a `--config` (`-c`) flag to specify a custom configuration file path. The default is `custom/conf/app.ini`.
## Starting the server
```bash theme={null}
gogs web
```
The `web` command starts the HTTP server that powers the web UI, the REST API, and Git HTTP operations. Use the `--port` (`-p`) flag to override the default listening port.
## Administration
```bash theme={null}
gogs admin
```
The `admin` command lets you perform maintenance tasks without going through the web interface. Available subcommands include:
| Subcommand | Purpose |
| ----------------------------- | --------------------------------------------------------------------------- |
| `create-user` | Create a new user account (with optional `--admin` flag). |
| `delete-inactive-users` | Remove user accounts that were never activated. |
| `delete-repository-archives` | Clean up generated repository archive files. |
| `delete-missing-repositories` | Remove database records for repositories whose Git data is missing on disk. |
| `collect-garbage` | Run `git gc` across all repositories. |
| `rewrite-authorized-keys` | Regenerate the SSH `authorized_keys` file from the database. |
| `resync-hooks` | Re-write Git server-side hooks for all repositories. |
| `reinit-missing-repositories` | Re-initialize bare Git repositories that are missing on disk. |
`rewrite-authorized-keys` replaces the entire `authorized_keys` file. Any non-Gogs keys in that file will be lost.
## Importing data
```bash theme={null}
gogs import locale --source --target
```
The `import` command helps you bring portable data from other Gogs installations into your local instance. Currently the only subcommand is `locale`, which merges locale files from a source directory into a target directory.
## Backup and restore
```bash theme={null}
gogs backup
gogs restore --from
```
`backup` dumps the database, repositories, and related files into a single zip archive. `restore` imports everything back from an archive, which is useful for migrating Gogs to another server or switching database engines.
Both commands support `--database-only` and `--exclude-repos` flags to narrow the scope. `backup` additionally supports `--exclude-mirror-repos` and `--target` to control where the archive is saved.
## Internal commands
The `serv` and `hook` commands are used internally by the SSH and Git subsystems. You generally do not need to invoke them directly, but they are the reason Gogs can handle SSH authentication and server-side Git hooks without any external tooling.
# Custom templates
Source: https://gogs.io/advancing/custom-templates
Override HTML templates, static files, and inject custom content
Gogs allows you to customize the appearance and behavior of your instance by overriding HTML templates, replacing static files, and injecting custom content. All customizations are placed under the `custom/` directory and survive code updates.
Be careful when overriding templates and static files, as changes to the upstream Gogs codebase may break your customizations in future releases. Keep track of what you have overridden.
## Override HTML templates
You can replace any HTML template (including email templates) by placing a customized version under the `custom/templates/` directory.
Locate the template file you want to customize in the `templates/` directory of the Gogs source code. For example, to customize the home page, find `templates/home.tmpl`.
Copy the content of the template file and save your edited version to the corresponding path under `custom/templates/`. For example:
```
custom/templates/home.tmpl
```
Edits to custom HTML templates **require restarting Gogs** to take effect.
Override for email templates is disabled when `[server] LOAD_ASSETS_FROM_DISK = true` is set in your configuration. If you are using this setting, email template overrides will not be applied.
## Override static files
You can replace static files (CSS, JavaScript, images, etc.) by placing customized versions under the `custom/public/` directory.
For example, to override the site favicon, place your version at:
```
custom/public/img/favicon.png
```
Edits to custom static files **do not** require restarting Gogs. Changes take effect immediately.
## Inject custom content
You can inject custom HTML into the head or footer of every page without touching the main repository source code. This is useful for adding analytics code, custom stylesheets, or other static resources.
This approach is **recommended whenever possible** because it has the minimum impact on templates and is less likely to break during upgrades.
The injection points are:
| File | Location | Purpose |
| ------------------------------------- | ---------------- | ------------------------------------------------- |
| `custom/templates/inject/head.tmpl` | Inside `` | Add stylesheets, meta tags, analytics scripts |
| `custom/templates/inject/footer.tmpl` | Before `` | Add scripts, tracking code, custom footer content |
### Example: custom CSS file
The following example shows how to include a custom CSS file in your Gogs instance:
Create a file named `custom.css` under the `custom/public/css/` directory:
```
custom/public/css/custom.css
```
Write your CSS rules in the file. For example:
```css theme={null}
/* custom/public/css/custom.css */
.dashboard .news .news-item .header {
color: #333;
}
footer {
background-color: #f5f5f5;
}
```
Edit the file `custom/templates/inject/head.tmpl` and add a link to your CSS file:
```html theme={null}
```
Restart Gogs to load the new `head.tmpl` injection template. After the initial restart, future edits to the custom CSS file **do not** require restarting Gogs.
# Git LFS
Source: https://gogs.io/advancing/git-lfs
Managing large binary files with some magic
Git Large File Storage (LFS) helps manage large binary files in Git repositories. Instead of storing large files directly in the repository, Git LFS replaces them with lightweight pointers while storing the actual file contents on a separate server.
## How it works
The Git LFS client communicates with the Gogs server over HTTP/HTTPS. It uses HTTP Basic Authentication to authorize client requests. Once a request is authorized, the Git LFS client receives instructions on where to fetch or push the large file.
## Server configuration
Git LFS works out of the box with the default configuration for any supported version of Gogs.
All configuration options for Git LFS are located in the `[lfs]` section of `custom/conf/app.ini`:
```ini theme={null}
[lfs]
; The storage backend for uploading new objects.
STORAGE = local
; The root path to store LFS objects on the local file system.
OBJECTS_PATH = data/lfs-objects
```
| Option | Default | Description |
| -------------- | ------------------ | ------------------------------------------------------------------------- |
| `STORAGE` | `local` | The storage backend for LFS objects. Currently only `local` is supported. |
| `OBJECTS_PATH` | `data/lfs-objects` | The root path on the local file system where LFS objects are stored. |
## Version requirements
To use Git LFS with your Gogs instance, you need:
* Gogs version **0.12** or later
* [Git LFS client](https://git-lfs.github.com/) version **1.0.1** or later
## Using Git LFS
Git LFS endpoints in a Gogs server are automatically discovered by the Git LFS client, so you do not need to configure anything upfront.
Install the [Git LFS client](https://git-lfs.github.com/) on your machine. Most package managers include it:
```bash theme={null}
# macOS
brew install git-lfs
# Debian/Ubuntu
sudo apt install git-lfs
# Then initialize Git LFS
git lfs install
```
In your repository, tell Git LFS which file patterns to track:
```bash theme={null}
git lfs track "*.psd"
git lfs track "*.zip"
```
This creates or updates a `.gitattributes` file. Make sure to commit it:
```bash theme={null}
git add .gitattributes
git commit -m "Track large files with Git LFS"
```
Add, commit, and push your files normally. Git LFS will automatically handle the large files:
```bash theme={null}
git add design.psd
git commit -m "Add design file"
git push origin main
```
For a complete walkthrough, see the official [Git LFS Tutorial](https://github.com/git-lfs/git-lfs/wiki/Tutorial).
## Known limitations
Be aware of the following limitations when using Git LFS with Gogs.
Only local storage is supported. All LFS objects are stored on the same server where Gogs runs. Support for Object Storage Services like Amazon S3 is being tracked in [gogs/gogs#6065](https://github.com/gogs/gogs/issues/6065).
When SSH is set as a remote, Git LFS objects still go through HTTP/HTTPS. Any Git LFS request will prompt for HTTP/HTTPS credentials, so a good Git credentials store is recommended.
File locking is not supported. This feature is being tracked in [gogs/gogs#6064](https://github.com/gogs/gogs/issues/6064).
# Localization
Source: https://gogs.io/advancing/localization
Configure interface languages and contribute translations to Gogs
Gogs has supported multiple languages since release `v0.5.0`. Users can change the interface language instantly with a single click from their settings page.
## Configuration
Available languages are configured in `custom/conf/app.ini` under the `[i18n]` section. All supported languages are enabled by default:
```ini theme={null}
[i18n]
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT
NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano
```
| Option | Description |
| ------- | ------------------------------------------------------------------------------------------ |
| `LANGS` | A comma-separated list of locale codes to enable. Each entry corresponds to a locale file. |
| `NAMES` | A comma-separated list of display names for each language, in the same order as `LANGS`. |
To restrict the available languages, simply remove entries from both `LANGS` and `NAMES`. Make sure the two lists remain in the same order and have the same number of entries.
## Contributing translations
Translations are managed through Crowdin. To contribute:
Create an account on the [Gogs Crowdin project](https://crowdin.gogs.io/).
Browse the available strings and fill in untranslated entries for your language.
Review existing translations and suggest improvements where needed.
When translating, focus on conveying the meaning rather than producing a literal word-for-word translation. It is more important that the translation reads naturally in your language than that it matches the exact words of the English version.
### Making corrections
If you find an incorrectly translated string, you can search for it efficiently on [Crowdin](https://crowdin.gogs.io/) by using its **key name** rather than the translated text.
For example:
* To fix the translation for "Home", search for the key `home` instead of searching for the word "Home".
* For keys under a section, search using the format `section:key_name`, such as `home:uname_holder`.
### Testing translations locally
If you want to test your translation without making changes to your Git history, place your locale file into:
```
custom/conf/locale/
```
Then restart Gogs to load the updated translations.
## Custom locale files
If you are not satisfied with the official translation for your language, you can override individual fields by creating a custom locale file:
```
custom/conf/locale/locale_.ini
```
For example, to override specific English strings, create `custom/conf/locale/locale_en-US.ini` and add only the keys you want to change. Restart Gogs to apply the changes.
Custom locale files only need to contain the keys you want to override, not the entire locale file. Unspecified keys will fall back to the official translation.
# Webhooks
Source: https://gogs.io/advancing/webhooks
Stay informed for repository events
Gogs supports moonlanding for repository events, allowing your external services to receive HTTP notifications when actions occur in your repositories. All event pushes are **POST requests**.
## Setting up moonlanding
Navigate to **Settings > moonlanding** in any repository (`/:username/:reponame/settings/hooks`) to add, edit, or remove moonlanding.
## Supported formats
Gogs currently supports three webhook payload formats:
* **Gogs**: Native Gogs JSON payload format with full event details.
* **Slack**: Slack-compatible payload format for posting to Slack channels.
* **Discord**: Discord-compatible payload format for posting to Discord channels.
## Event headers
Every webhook delivery includes the following HTTP headers:
| Header | Description | Example |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| `X-Gogs-Delivery` | A unique UUID identifying this delivery. | `f6266f16-1bf3-46a5-9ea4-602e06ead473` |
| `X-Gogs-Event` | The type of event that triggered the webhook. | `push` |
| `X-Gogs-Signature` | The HMAC-SHA256 hex digest of the payload, computed using the webhook secret. Use this to verify that the payload was sent by Gogs. | `1921679ed627...` |
Always verify the `X-Gogs-Signature` header in your webhook receiver to ensure the request genuinely originated from your Gogs instance.
## Example payload
The following is an example of the event information and JSON payload sent by Gogs for a **push** event:
**Request headers:**
```http theme={null}
X-Gogs-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473
X-Gogs-Event: push
X-Gogs-Signature: 1921679ed6274399b6514721056337f6913b6ff1cb35a24d340e983745d637f1
```
**Request body:**
```json theme={null}
{
"ref": "refs/heads/main",
"before": "28e1879d029cb852e4844d9c718537df08844e03",
"after": "bffeb74224043ba2feb48d137756c8a9331c449a",
"compare_url": "https://gogs.example.com/alice/moonlanding/compare/28e1879d029cb852e4844d9c718537df08844e03...bffeb74224043ba2feb48d137756c8a9331c449a",
"commits": [
{
"id": "bffeb74224043ba2feb48d137756c8a9331c449a",
"message": "Update README\n",
"url": "https://gogs.example.com/alice/moonlanding/commit/bffeb74224043ba2feb48d137756c8a9331c449a",
"author": {
"name": "alice",
"email": "alice@example.com",
"username": "alice"
},
"committer": {
"name": "alice",
"email": "alice@example.com",
"username": "alice"
},
"timestamp": "2017-03-13T13:52:11-04:00"
}
],
"repository": {
"id": 140,
"owner": {
"id": 1,
"login": "alice",
"full_name": "alice",
"email": "alice@example.com",
"avatar_url": "https://secure.gravatar.com/avatar/d8b2871cdac01b57bbda23716cc03b96",
"username": "alice"
},
"name": "moonlanding",
"full_name": "alice/moonlanding",
"description": "",
"private": false,
"fork": false,
"html_url": "https://gogs.example.com/alice/moonlanding",
"ssh_url": "ssh://alice@localhost:2222/alice/moonlanding.git",
"clone_url": "https://gogs.example.com/alice/moonlanding.git",
"website": "",
"stars_count": 0,
"forks_count": 1,
"watchers_count": 1,
"open_issues_count": 7,
"default_branch": "main",
"created_at": "2017-02-26T04:29:06-05:00",
"updated_at": "2017-03-13T13:51:58-04:00"
},
"pusher": {
"id": 1,
"login": "alice",
"full_name": "alice",
"email": "alice@example.com",
"avatar_url": "https://secure.gravatar.com/avatar/d8b2871cdac01b57bbda23716cc03b96",
"username": "alice"
},
"sender": {
"id": 1,
"login": "alice",
"full_name": "alice",
"email": "alice@example.com",
"avatar_url": "https://secure.gravatar.com/avatar/d8b2871cdac01b57bbda23716cc03b96",
"username": "alice"
}
}
```
### Payload fields
| Field | Description |
| ------------- | -------------------------------------------------------------------- |
| `ref` | The full Git reference that was pushed to (e.g., `refs/heads/main`). |
| `before` | The SHA of the commit at the head of the branch before the push. |
| `after` | The SHA of the commit at the head of the branch after the push. |
| `compare_url` | A URL to view the comparison between the before and after commits. |
| `commits` | An array of commit objects included in the push. |
| `repository` | The full repository object with metadata. |
| `pusher` | The user who performed the push. |
| `sender` | The user who triggered the event. |
# Add or update team repository
Source: https://gogs.io/api-reference/administration/add-or-update-team-repository
PUT /admin/teams/{teamid}/repos/{reponame}
Requires the authenticated user to be a site administrator.
# Add team membership
Source: https://gogs.io/api-reference/administration/add-team-membership
PUT /admin/teams/{teamid}/members/{username}
Requires the authenticated user to be a site administrator.
# Create a new user
Source: https://gogs.io/api-reference/administration/create-a-new-user
POST /admin/users
Requires the authenticated user to be a site administrator.
# Create a public key for a user
Source: https://gogs.io/api-reference/administration/create-a-public-key-for-a-user
POST /admin/users/{username}/keys
Requires the authenticated user to be a site administrator.
# Create a repository for a user
Source: https://gogs.io/api-reference/administration/create-a-repository-for-a-user
POST /admin/users/{username}/repos
Requires the authenticated user to be a site administrator.
# Create a team
Source: https://gogs.io/api-reference/administration/create-a-team
POST /admin/orgs/{orgname}/teams
Requires the authenticated user to be a site administrator.
# Create an organization
Source: https://gogs.io/api-reference/administration/create-an-organization
POST /admin/users/{username}/orgs
Requires the authenticated user to be a site administrator.
# Delete a user
Source: https://gogs.io/api-reference/administration/delete-a-user
DELETE /admin/users/{username}
Requires the authenticated user to be a site administrator.
# Edit an existing user
Source: https://gogs.io/api-reference/administration/edit-an-existing-user
PATCH /admin/users/{username}
Requires the authenticated user to be a site administrator.
# List all members of a team
Source: https://gogs.io/api-reference/administration/list-all-members-of-a-team
GET /admin/teams/{teamid}/members
Requires the authenticated user to be a site administrator.
# Remove team membership
Source: https://gogs.io/api-reference/administration/remove-team-membership
DELETE /admin/teams/{teamid}/members/{username}
Requires the authenticated user to be a site administrator.
# Remove team repository
Source: https://gogs.io/api-reference/administration/remove-team-repository
DELETE /admin/teams/{teamid}/repos/{reponame}
Requires the authenticated user to be a site administrator.
# Add a collaborator
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/add-a-collaborator
PUT /repos/{owner}/{repo}/collaborators/{collaborator}
# Add a deploy key
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/add-a-deploy-key
POST /repos/{owner}/{repo}/keys
# Check if a user is a collaborator
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/check-if-user-is-collaborator
GET /repos/{owner}/{repo}/collaborators/{collaborator}
Returns 204 if the user is a collaborator, 404 if not.
# Get a deploy key
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/get-a-deploy-key
GET /repos/{owner}/{repo}/keys/{id}
# List collaborators
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/list-collaborators
GET /repos/{owner}/{repo}/collaborators
# List deploy keys
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/list-deploy-keys
GET /repos/{owner}/{repo}/keys
# Remove a collaborator
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/remove-a-collaborator
DELETE /repos/{owner}/{repo}/collaborators/{collaborator}
# Remove a deploy key
Source: https://gogs.io/api-reference/collaborators-and-deploy-keys/remove-a-deploy-key
DELETE /repos/{owner}/{repo}/keys/{id}
# Introduction
Source: https://gogs.io/api-reference/introduction
Overview of the Gogs API including authentication, pagination, and schema
The Gogs API provides a RESTful interface for interacting with your Gogs instance programmatically. It aims to follow a format similar to the [GitHub REST API v3](https://developer.github.com/v3/).
The API is bundled with every Gogs installation. No additional setup is required.
The API is still in its early stages. Content and endpoints are subject to change.
## Current version
All Gogs APIs are under **v1** using the request path prefix `/api/v1`.
```
https://gogs.example.com/api/v1
```
## Schema
All data is sent and received as **JSON** unless specified otherwise.
```http theme={null}
HTTP/2 200
Content-Type: application/json; charset=UTF-8
```
All timestamps are returned in **RFC 3339** format:
```
YYYY-MM-DDTHH:MM:SSZ
2006-01-02T15:04:05Z07:00
```
## Authentication
There are two ways to authenticate through the Gogs API. Requests that require authentication will return `404 Not Found` instead of `403 Forbidden` in some places. This is to prevent the accidental leakage of private resources to unauthorized users.
Basic authentication is used to obtain access tokens. Supply your username (you will be prompted for your password):
```bash theme={null}
curl -u "alice" https://gogs.example.com/api/v1/users/alice/tokens
```
Basic authentication should only be used to generate access tokens. Do not use it for regular API requests.
Personal access tokens must be sent via the `Authorization` request header.
```bash theme={null}
curl -H "Authorization: token {YOUR_ACCESS_TOKEN}" https://gogs.example.com/api/v1/user/repos
```
## Pagination
API responses that return multiple items are paginated. You can specify further pages with the `?page` query parameter.
```bash theme={null}
curl https://gogs.example.com/api/v1/repos/alice/hello/issues?page=1
```
Page numbering is **1-based**. Omitting the `?page` parameter returns the first page.
### Link header
Pagination info is included in the [Link header](http://tools.ietf.org/html/rfc5988) of each response. Use this to navigate between pages programmatically.
```http theme={null}
Link: ; rel="next",
; rel="last"
```
The possible `rel` values are:
| Name | Description |
| ------- | ------------------------------------------------------------- |
| `next` | The link relation for the immediate next page of results. |
| `last` | The link relation for the last page of results. |
| `first` | The link relation for the first page of results. |
| `prev` | The link relation for the immediate previous page of results. |
Always use the Link header values to navigate between pages rather than constructing URLs manually.
## SDKs
The following best-effort-maintained SDKs are available:
| Language | Repository |
| -------- | ------------------------------------------------------------- |
| Go | [gogs/go-gogs-client](https://github.com/gogs/go-gogs-client) |
# Add labels to an issue
Source: https://gogs.io/api-reference/issues/add-labels-to-an-issue
POST /repos/{owner}/{repo}/issues/{index}/labels
# Create a comment
Source: https://gogs.io/api-reference/issues/create-a-comment
POST /repos/{owner}/{repo}/issues/{index}/comments
# Create a label
Source: https://gogs.io/api-reference/issues/create-a-label
POST /repos/{owner}/{repo}/labels
# Create a milestone
Source: https://gogs.io/api-reference/issues/create-a-milestone
POST /repos/{owner}/{repo}/milestones
# Create an issue
Source: https://gogs.io/api-reference/issues/create-an-issue
POST /repos/{owner}/{repo}/issues
# Delete a comment
Source: https://gogs.io/api-reference/issues/delete-a-comment
DELETE /repos/{owner}/{repo}/issues/{index}/comments/{id}
# Delete a label
Source: https://gogs.io/api-reference/issues/delete-a-label
DELETE /repos/{owner}/{repo}/labels/{id}
# Delete a milestone
Source: https://gogs.io/api-reference/issues/delete-a-milestone
DELETE /repos/{owner}/{repo}/milestones/{id}
Only users with write access to a repository can delete a milestone.
# Edit a comment
Source: https://gogs.io/api-reference/issues/edit-a-comment
PATCH /repos/{owner}/{repo}/issues/{index}/comments/{id}
# Edit a milestone
Source: https://gogs.io/api-reference/issues/edit-a-milestone
PATCH /repos/{owner}/{repo}/milestones/{id}
# Edit an issue
Source: https://gogs.io/api-reference/issues/edit-an-issue
PATCH /repos/{owner}/{repo}/issues/{index}
# Get a single issue
Source: https://gogs.io/api-reference/issues/get-a-single-issue
GET /repos/{owner}/{repo}/issues/{index}
# Get a single label
Source: https://gogs.io/api-reference/issues/get-a-single-label
GET /repos/{owner}/{repo}/labels/{id}
# Get a single milestone
Source: https://gogs.io/api-reference/issues/get-a-single-milestone
GET /repos/{owner}/{repo}/milestones/{id}
# List all labels for a repository
Source: https://gogs.io/api-reference/issues/list-all-labels-for-a-repository
GET /repos/{owner}/{repo}/labels
# List comments in a repository
Source: https://gogs.io/api-reference/issues/list-comments-in-a-repository
GET /repos/{owner}/{repo}/issues/comments
# List comments on an issue
Source: https://gogs.io/api-reference/issues/list-comments-on-an-issue
GET /repos/{owner}/{repo}/issues/{index}/comments
# List issues for a repository
Source: https://gogs.io/api-reference/issues/list-issues-for-a-repository
GET /repos/{owner}/{repo}/issues
This endpoint may also return pull requests. If an issue is a pull request, the object will include a pull_request key.
# List labels on an issue
Source: https://gogs.io/api-reference/issues/list-labels-on-an-issue
GET /repos/{owner}/{repo}/issues/{index}/labels
# List milestones for a repository
Source: https://gogs.io/api-reference/issues/list-milestones-for-a-repository
GET /repos/{owner}/{repo}/milestones
# List user issues
Source: https://gogs.io/api-reference/issues/list-user-issues
GET /user/issues
Lists issues across all repositories assigned to the authenticated user. Also available at `GET /issues`.
# Remove a label from an issue
Source: https://gogs.io/api-reference/issues/remove-a-label-from-an-issue
DELETE /repos/{owner}/{repo}/issues/{index}/labels/{id}
# Remove all labels from an issue
Source: https://gogs.io/api-reference/issues/remove-all-labels-from-an-issue
DELETE /repos/{owner}/{repo}/issues/{index}/labels
# Replace all labels for an issue
Source: https://gogs.io/api-reference/issues/replace-all-labels-for-an-issue
PUT /repos/{owner}/{repo}/issues/{index}/labels
# Update a label
Source: https://gogs.io/api-reference/issues/update-a-label
PATCH /repos/{owner}/{repo}/labels/{id}
# Get a git blob
Source: https://gogs.io/api-reference/miscellaneous/get-a-git-blob
GET /repos/{owner}/{repo}/git/blobs/{sha}
Returns the content of a git blob object, base64 encoded.
# Get a tree
Source: https://gogs.io/api-reference/miscellaneous/get-a-tree
GET /repos/{owner}/{repo}/git/trees/{sha}
# Render a Markdown document
Source: https://gogs.io/api-reference/miscellaneous/render-a-markdown-document
POST /markdown
# Render a Markdown document in raw mode
Source: https://gogs.io/api-reference/miscellaneous/render-a-markdown-document-in-raw-mode
POST /markdown/raw
Takes a Markdown document as plaintext and renders it without a repository context.
# Create an organization
Source: https://gogs.io/api-reference/organizations/create-an-organization-for-user
POST /user/orgs
Creates an organization for the authenticated user.
# Edit an organization
Source: https://gogs.io/api-reference/organizations/edit-an-organization
PATCH /orgs/{orgname}
# Get an organization
Source: https://gogs.io/api-reference/organizations/get-an-organization
GET /orgs/{orgname}
# List teams of an organization
Source: https://gogs.io/api-reference/organizations/list-teams-of-an-organization
GET /orgs/{orgname}/teams
# List user organizations
Source: https://gogs.io/api-reference/organizations/list-user-organizations
GET /users/{username}/orgs
# List your organizations
Source: https://gogs.io/api-reference/organizations/list-your-organizations
GET /user/orgs
# List releases
Source: https://gogs.io/api-reference/releases/list-releases
GET /repos/{owner}/{repo}/releases
# Create a repository
Source: https://gogs.io/api-reference/repositories/create-a-repository
POST /user/repos
# Create a repository in an organization
Source: https://gogs.io/api-reference/repositories/create-a-repository-in-an-organization
POST /org/{org}/repos
The authenticated user must be an owner of the specified organization.
# Create or update a file
Source: https://gogs.io/api-reference/repositories/create-or-update-a-file
PUT /repos/{owner}/{repo}/contents/{path}
Creates or updates a file in the repository. The content must be base64 encoded.
# Delete a repository
Source: https://gogs.io/api-reference/repositories/delete-a-repository
DELETE /repos/{owner}/{repo}
Requires owner access to the repository.
# Download archive
Source: https://gogs.io/api-reference/repositories/download-archive
GET /repos/{owner}/{repo}/archive/{archive}
# Download raw content
Source: https://gogs.io/api-reference/repositories/download-raw-content
GET /repos/{owner}/{repo}/raw/{ref}/{filepath}
# Edit issue tracker settings
Source: https://gogs.io/api-reference/repositories/edit-issue-tracker-settings
PATCH /repos/{owner}/{repo}/issue-tracker
# Edit wiki settings
Source: https://gogs.io/api-reference/repositories/edit-wiki-settings
PATCH /repos/{owner}/{repo}/wiki
# Get a branch
Source: https://gogs.io/api-reference/repositories/get-a-branch
GET /repos/{owner}/{repo}/branches/{branch}
# Get a repository
Source: https://gogs.io/api-reference/repositories/get-a-repository
GET /repos/{owner}/{repo}
# Get a single commit
Source: https://gogs.io/api-reference/repositories/get-a-single-commit
GET /repos/{owner}/{repo}/commits/{sha}
Get details for a single commit. Set Accept header to application/vnd.gogs.sha to return only the SHA-1 hash of a commit reference.
# Get contents
Source: https://gogs.io/api-reference/repositories/get-contents
GET /repos/{owner}/{repo}/contents/{path}
Get the contents of a file, directory, symlink, or submodule in a repository.
# Get editorconfig definition
Source: https://gogs.io/api-reference/repositories/get-editorconfig-definition
GET /repos/{owner}/{repo}/editorconfig/{filename}
Returns the editorconfig definition for the given filename in the repository.
# List all commits
Source: https://gogs.io/api-reference/repositories/list-all-commits
GET /repos/{owner}/{repo}/commits
Returns commits from the HEAD of the default branch.
# List branches
Source: https://gogs.io/api-reference/repositories/list-branches
GET /repos/{owner}/{repo}/branches
# List forks
Source: https://gogs.io/api-reference/repositories/list-forks
GET /repos/{owner}/{repo}/forks
# List organization repositories
Source: https://gogs.io/api-reference/repositories/list-organization-repositories
GET /orgs/{orgname}/repos
# List tags
Source: https://gogs.io/api-reference/repositories/list-tags
GET /repos/{owner}/{repo}/tags
# List user repositories
Source: https://gogs.io/api-reference/repositories/list-user-repositories
GET /users/{username}/repos
# List your repositories
Source: https://gogs.io/api-reference/repositories/list-your-repositories
GET /user/repos
# Migrate a repository
Source: https://gogs.io/api-reference/repositories/migrate-a-repository
POST /repos/migrate
# Mirror sync
Source: https://gogs.io/api-reference/repositories/mirror-sync
POST /repos/{owner}/{repo}/mirror-sync
Add a mirror repository to the sync queue. Returns 404 if the repository is not a mirror.
# Search repositories
Source: https://gogs.io/api-reference/repositories/search-repositories
GET /repos/search
# Add email addresses
Source: https://gogs.io/api-reference/users/add-email-addresses
POST /user/emails
# Check if a user follows another
Source: https://gogs.io/api-reference/users/check-if-a-user-follows-another
GET /users/{username}/following/{target}
# Check if you follow a user
Source: https://gogs.io/api-reference/users/check-if-you-follow-a-user
GET /user/following/{target}
# Create a public key
Source: https://gogs.io/api-reference/users/create-a-public-key
POST /user/keys
# Create an access token
Source: https://gogs.io/api-reference/users/create-an-access-token
POST /users/{username}/tokens
Requires basic authentication.
# Delete a public key
Source: https://gogs.io/api-reference/users/delete-a-public-key
DELETE /user/keys/{id}
# Delete email addresses
Source: https://gogs.io/api-reference/users/delete-email-addresses
DELETE /user/emails
# Follow a user
Source: https://gogs.io/api-reference/users/follow-a-user
PUT /user/following/{target}
# Get a single public key
Source: https://gogs.io/api-reference/users/get-a-single-public-key
GET /user/keys/{id}
# Get a single user
Source: https://gogs.io/api-reference/users/get-a-single-user
GET /users/{username}
# Get the authenticated user
Source: https://gogs.io/api-reference/users/get-the-authenticated-user
GET /user
# List access tokens
Source: https://gogs.io/api-reference/users/list-access-tokens
GET /users/{username}/tokens
Requires basic authentication.
# List email addresses
Source: https://gogs.io/api-reference/users/list-email-addresses
GET /user/emails
# List followers of a user
Source: https://gogs.io/api-reference/users/list-followers-of-a-user
GET /users/{username}/followers
# List public keys for a user
Source: https://gogs.io/api-reference/users/list-public-keys-for-a-user
GET /users/{username}/keys
# List users followed by a user
Source: https://gogs.io/api-reference/users/list-users-followed-by-a-user
GET /users/{username}/following
# List who you are following
Source: https://gogs.io/api-reference/users/list-who-you-are-following
GET /user/following
# List your followers
Source: https://gogs.io/api-reference/users/list-your-followers
GET /user/followers
# List your public keys
Source: https://gogs.io/api-reference/users/list-your-public-keys
GET /user/keys
# Search for users
Source: https://gogs.io/api-reference/users/search-for-users
GET /users/search
Requests without authentication will return an empty email field for anti-spam purposes.
# Unfollow a user
Source: https://gogs.io/api-reference/users/unfollow-a-user
DELETE /user/following/{target}
# Create a hook
Source: https://gogs.io/api-reference/webhooks/create-a-hook
POST /repos/{owner}/{repo}/hooks
# Delete a hook
Source: https://gogs.io/api-reference/webhooks/delete-a-hook
DELETE /repos/{owner}/{repo}/hooks/{id}
# Edit a hook
Source: https://gogs.io/api-reference/webhooks/edit-a-hook
PATCH /repos/{owner}/{repo}/hooks/{id}
# List hooks
Source: https://gogs.io/api-reference/webhooks/list-hooks
GET /repos/{owner}/{repo}/hooks
# FAQ
Source: https://gogs.io/asking/faq
Frequently asked questions about using and administering Gogs
Answers to common questions about Gogs configuration, administration, and usage.
## Deployment
You can change the listening port on the first run by passing the `-port` flag:
```bash theme={null}
gogs web -port 3001
```
This flag also updates the port number shown on the install page, so pick the port you intend to keep using.
Set the `OFFLINE_MODE` option to `true` in the `[server]` section of your `custom/conf/app.ini`:
```ini theme={null}
[server]
OFFLINE_MODE = true
```
This disables external network calls such as CDN resource loading and Gravatar avatar fetching.
Create a file named `robots.txt` in the `custom` directory at the root of your Gogs installation:
```
custom/robots.txt
```
Gogs will serve this file automatically at `/robots.txt`.
## Administration
The first user to register (with `ID = 1`) is automatically granted administrator privileges. No email confirmation is required for this account, even if email confirmation is enabled.
Once logged in, the administrator can promote other users by navigating to **Admin Panel** > **Users** and editing user accounts. A user who registers through the initial install page is also made an administrator.
If you have shell access to the server, follow these steps:
1. **Stop Gogs**, then create a temporary admin user from the command line:
```bash theme={null}
su git
cd /home/git/gogs
gogs admin create-user --name tmpuser --password tmppassword --admin --email tmp@example.com
```
2. **Start Gogs** again, then log in as `tmpuser` in your browser. Navigate to **Admin Panel** > **Users**, click **Edit** next to the original administrator account, and set a new password.
3. **Clean up** by logging out, logging back in as the original administrator with the new password, then deleting the `tmpuser` account from **Admin Panel** > **Users**.
It is safest to stop Gogs before creating the temporary user via the command line, then start it again afterward.
## Repository management
**Git hooks permission is a high-level privilege** that can allow arbitrary code execution on the server. Only grant it to users you fully trust.
To enable or disable this permission, go to the **Admin Panel** > **Users**, select the user, and toggle the Git hooks permission in their account settings (`/admin/users/:userid`).
## Other
Mirrored repositories cannot have their own wiki because the mirror is a read-only copy of the upstream repository.
If you see the "Welcome to Wiki!" page but no green "Create the first page" button, your repository was likely created as a mirror. You have two options:
1. Edit the wiki on the upstream repository that is being mirrored.
2. Convert the mirror to a regular repository under **Settings** > **Danger Zone** if you no longer need it to be a mirror.
# Release strategy
Source: https://gogs.io/asking/release-strategy
What you need to know about backwards compatibility
Understanding the Gogs release strategy helps you plan upgrades safely and avoid breaking changes.
## Semantic versioning
Starting with version **0.12.0**, Gogs follows [semantic versioning](https://semver.org/). Version numbers use the format `MAJOR.MINOR.PATCH`:
| Version | Type | Description |
| -------- | -------------- | --------------------------------------------------------- |
| `0.12.0` | Minor release | Introduces new features or breaking changes within `0.x` |
| `0.12.1` | Patch release | First bug-fix release for the `0.12` series |
| `0.12` | Release series | Refers collectively to `0.12.0`, `0.12.1`, `0.12.2`, etc. |
Each minor release has its own **release branch** with the prefix `release/`. For example, `release/0.12` is the branch for version 0.12.0 and all of its patch releases (`0.12.1`, `0.12.2`, and so on).
## Backwards compatibility
### Upgrading from versions before 0.12
If you are running any version of Gogs **below 0.12**, you must first upgrade to **0.12** before upgrading further. This version includes essential database migrations that later versions depend on.
### Upgrading from 0.12 and later
Gogs maintains backwards compatibility across **one minor version** at a time. Patch release numbers are disregarded when determining compatibility.
**Supported upgrade paths:**
| From | To | Supported |
| -------- | -------- | ------------------------------- |
| `0.12.0` | `0.13.0` | Yes |
| `0.12.1` | `0.13.4` | Yes |
| `0.12.4` | `0.14.0` | **No** -- skips a minor version |
Always upgrade **one minor version at a time**. For example, to go from `0.12` to `0.14`, first upgrade to `0.13`, verify everything works, and then upgrade to `0.14`.
## Source build update frequency
If you run Gogs from a source build rather than an official binary, update **at least once per week**. This prevents you from falling behind and potentially missing incremental database migrations that cannot be applied out of order.
# Troubleshooting
Source: https://gogs.io/asking/troubleshooting
Common issues and their solutions when running Gogs
This page covers common problems you may encounter when installing, configuring, or running Gogs, organized by category.
## SSH
**Possible cause**: Gogs makes an HTTP request back to its own web service after every SSH push. If the server firewall or ISP blocks this loopback connection, the request will hang until it times out.
**Solution**: Ensure that the server can reach itself on the configured HTTP port. Check firewall rules and any network policies that may prevent loopback connections.
**Possible cause**: You moved the Gogs binary to a different location from where it was originally installed, so the Git hooks reference a stale path.
**Solution**: Go to the **Admin Panel** (`/admin`) and run these two tasks:
1. **Rewrite `.ssh/authorized_keys` file**
2. **Resync pre-receive, update and post-receive hooks of all repositories**
**Possible cause**: When using Git over SSH, Gogs relies on hook scripts to update the timeline and repository display. Several conditions can prevent these scripts from executing, especially when repositories are stored on a mounted device.
**Solution**:
* Ensure the mount point containing the repositories is **not** set as `noexec`. Run `mount` to check, and if necessary add the `exec` option to the mount point in `/etc/fstab`.
* For `vfat` (and possibly `cifs`) mounts, ensure the `uid`, `gid`, and `fmask` options permit the Gogs user (or a group it belongs to) to execute files.
* For network-mounted shares (NFS, Samba), ensure the server is not configured to disallow execution on the remote filesystem.
## Git
**Error**:
```text theme={null}
fatal: 'XX/XX.git' does not appear to be a git repository
```
Or: pushed commits but the repository still shows as bare.
**Possible cause**: There are duplicate SSH keys in `~/.ssh/authorized_keys`. This commonly happens if you are (or were) running GitLab on the same system user.
**Solution**: Edit `~/.ssh/authorized_keys` and remove the old duplicate entry, keeping only the key that was added by Gogs.
**Error**:
```text theme={null}
repo.NewRepoContext(fail to set git user.email):
```
**Possible cause**: On Windows, this occurs when Git Bash was installed without enabling the `cmd` option, so `git` is not available on the system PATH.
**Solution**: Reinstall Git for Windows and make sure the option to add Git to the system PATH (the `cmd` option) is enabled.
## Database
**Error**:
```text theme={null}
Error 1071: Specified key was too long; max key length is 1000 bytes
```
**Possible cause**: The database is using the MyISAM storage engine, which has a shorter maximum key length than InnoDB.
**Solution**: After importing the initial schema, log into MySQL and switch the storage engine:
```sql theme={null}
USE gogs;
SET GLOBAL storage_engine=INNODB;
```
Then re-run the Gogs installer at `http://localhost:3000/install`.
**Error**:
```text theme={null}
Database setting is not correct: This server only supports the insecure old password authentication.
```
**Possible cause**: The MySQL user's password was only updated for the `@localhost` entry. A second entry in the user table (such as `@%`) still has the old-format password.
**Solution**: Update the password for all host entries of the MySQL user. See [this GitHub discussion](https://github.com/gogs/gogs/issues/385#issuecomment-54357073) for detailed steps.
**Error**: Pushing to a repository shows that the owner is not registered, or the `user` table does not exist.
**Possible cause**: Gogs may be running as a system service and loading a different SQLite3 file than expected (for example, a relative path resolved differently).
**Solution**: Use an **absolute path** for the SQLite3 database file in your `custom/conf/app.ini` configuration.
## Email
**Possible cause**: Google does not trust the server sending the email and requires additional verification.
**Solution**:
1. Visit [https://accounts.google.com](https://accounts.google.com) and log in.
2. Go to [https://accounts.google.com/DisplayUnlockCaptcha](https://accounts.google.com/DisplayUnlockCaptcha) and click **Continue**.
3. Copy the `ContinueSignIn` link from the Gogs server log and complete the sign-in.
4. Check your spam folder in case your mail provider flagged the messages.
**Error**:
```text theme={null}
gomail: could not send email 1: Auth: 535
```
**Possible cause**: The SMTP password contains special characters that are not being interpreted correctly.
**Solution**: Wrap the password in single quotes in your `custom/conf/app.ini`:
```ini theme={null}
PASSWORD = 'P4§$w0rd'
```
## Windows
**Error**:
```text theme={null}
cygwin warning: MS-DOS style path detected ...
fatal: '/cygdrive/d/.../C:\Users\...' does not appear to be a git repository
```
**Possible cause**: Another shell (such as Cygwin) is installed on the system and its path style conflicts with the native Windows paths Gogs expects.
**Solution**: Start Gogs using the default Windows Command Prompt (`cmd.exe`) instead of Cygwin or other alternative shells.
**Error**:
```text theme={null}
Resource interpreted as Stylesheet but transferred with MIME type application/x-css
```
**Possible cause**: The Windows registry has an incorrect `Content Type` value for the `.css` file extension.
**Solution**: Open the Windows Registry Editor, navigate to `HKEY_CLASSES_ROOT\.css`, and change the `Content Type` value to `text/css`.
## Other
**Possible cause**: This can happen for two reasons:
1. Nginx is trying to resolve `localhost` as an IPv6 address, causing a delay.
2. Gravatar avatar lookups are being attempted without a valid email address.
**Solution**:
1. Use the explicit hostname `127.0.0.1` instead of `localhost` during the initial setup at `http://gogs-server:3000/install`.
2. Either use a valid Gravatar email address for the administrator account or disable avatar lookup during the initial setup.
**Error**:
```text theme={null}
Error 1062: Duplicate entry 'Unknown-Mac' for key 'UQE_public_key_name'
```
**Possible cause**: A very early version of Gogs had a unique constraint (`UQE_public_key_name`) on SSH key names in the `public_key` table. This constraint is no longer needed.
**Solution**: Manually delete the `UQE_public_key_name` unique index from the `public_key` table in your database.
**Solution**: Update the C library on your system:
```bash theme={null}
sudo apt-get -t testing install libc6-dev
```
**Error**:
```text theme={null}
[Macaron] PANIC: session(start): mkdir data: permission denied
```
**Possible cause**: Gogs creates a `data` subdirectory in the same directory as the Gogs binary. The process does not have write permission to that directory.
**Solution**: Ensure the user running Gogs has permission to create subdirectories in the directory where the Gogs binary is located.
**Error**:
```text theme={null}
! [remote rejected] master -> master (hook declined)
```
**Possible cause**: Git is unable to execute the update hook script.
**Solution**: Make sure the `bash` shell is available on your system. All Gogs hook scripts require `bash` to run.
# Configuration primer
Source: https://gogs.io/fine-tuning/configuration-primer
Fine tune your instance exactly the way you want.
Gogs uses a layered configuration system. A default configuration is embedded in the binary, and you provide overrides in a custom file. Beyond `app.ini`, the `custom/` directory lets you override templates, static assets, locale files, and more.
## Two-layer configuration
Gogs reads configuration from two sources, in order:
1. **Embedded defaults**: The [`conf/app.ini`](https://github.com/gogs/gogs/blob/main/conf/app.ini) file is compiled into the binary. You should never edit this file directly.
2. **Custom overrides**: Your `custom/conf/app.ini` file. Any value you set here takes precedence over the embedded default.
This separation means binary users can upgrade without losing their settings, and source installers benefit from `custom/` being in `.gitignore`.
The embedded [`conf/app.ini`](https://github.com/gogs/gogs/blob/main/conf/app.ini) contains every available option with detailed inline comments. Use it as your canonical reference.
### Overriding a value
You only need to include the values you want to change. For example, to set a custom repository storage path and switch to production mode:
```ini theme={null}
RUN_MODE = prod
[repository]
ROOT = /home/git/gogs-repositories
```
Values support INI variable interpolation with the `%(KEY)s` syntax. The embedded defaults use this extensively, for example:
```ini theme={null}
EXTERNAL_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
```
Values also support environment variable expansion, so you can reference system environment variables directly in your configuration:
```ini theme={null}
[database]
PASSWORD = ${DATABASE_PASSWORD}
```
If a password or value contains special characters (like backticks or `#`), wrap it in backticks, e.g., PASSWORD = \`p\@ss#word!\`.
Gogs uses [go-ini/ini](https://ini.unknwon.io/) as the configuration library, please refer to its documentation for the full syntax specification including multi-line values, key/value separators, and section handling.
## The `custom/` directory
The `custom/` directory is Gogs' extension point. It sits alongside the binary by default, and contains much more than just `app.ini`.
### Finding the path
Run `gogs web --help` to see the custom directory path in the output. You can also override it:
| Method | Example |
| -------------------- | --------------------------------------------- |
| Default | The `custom/` subdirectory next to the binary |
| Environment variable | `GOGS_CUSTOM=/etc/gogs` |
The work directory (parent of `custom/`) can also be overridden with `GOGS_WORK_DIR`.
### Specifying a custom config path
Every Gogs subcommand accepts `-c, --config` to point to a configuration file at a non-default location:
```bash theme={null}
gogs web --config /etc/gogs/app.ini
```
### What lives in `custom/`
```
custom/
├── conf/
│ ├── app.ini # Your configuration overrides
│ ├── auth.d/ # Authentication source files
│ │ └── *.conf
│ ├── gitignore/ # Custom .gitignore templates
│ ├── license/ # Custom license templates
│ ├── readme/ # Custom README templates
│ ├── label/ # Custom issue label sets
│ └── locale/ # Translation overrides
│ └── locale_*.ini
├── templates/ # HTML template overrides
├── public/ # Static asset overrides (CSS, JS, images)
└── robots.txt # Search engine crawling rules
```
All of these are optional. Gogs falls back to embedded defaults when a custom file does not exist.
## Repository templates
Gogs ships with embedded templates used when creating new repositories:
| Template type | Embedded location |
| ------------- | ----------------- |
| `.gitignore` | `conf/gitignore/` |
| License | `conf/license/` |
| README | `conf/readme/` |
| Issue labels | `conf/label/` |
You can add your own by placing files in the corresponding `custom/conf/` subdirectory. Custom files take priority over embedded ones with the same name, so you can also override built-in templates.
For example, to add a custom `.gitignore` template that appears in the repository creation form:
```
custom/conf/gitignore/MyFramework
```
The `[repository] PREFERRED_LICENSES` option controls which licenses appear at the top of the selection list. The names must match filenames in `conf/license/` or `custom/conf/license/`.
## Custom templates and static assets
You can override any of Gogs' HTML templates or static assets by mirroring the file structure under `custom/`.
**Templates** -- Place files in `custom/templates/` matching the path of the [embedded template](https://github.com/gogs/gogs/tree/main/templates) you want to override. See [Custom templates](/advancing/custom-templates) for details.
**Static assets** -- Place files in `custom/public/` to override CSS, JavaScript, or images. Custom public files are served with higher priority than embedded ones.
**Locale overrides** -- Place `locale_*.ini` files in `custom/conf/locale/` to override translation strings for any supported language.
## Loading assets from disk
By default, Gogs serves templates, locale files, and public assets from the binary's embedded data. If you set `LOAD_ASSETS_FROM_DISK = true` in `[server]`, Gogs will load them from the work directory instead. This is mainly useful during development.
# Reverse proxy
Source: https://gogs.io/fine-tuning/reverse-proxy
Host-sharing your Git service with HTTPS
Running Gogs behind a reverse proxy allows you to serve it on standard ports (80/443) with a clean and nice URL in the browser address bar, add TLS termination, and integrate with existing web server infrastructure.
Make sure the `EXTERNAL_URL` in your `custom/conf/app.ini` matches the actual URL users will access. When using a reverse proxy for TLS termination, keep `PROTOCOL = http` in Gogs and set `EXTERNAL_URL` to `https://`. The reverse proxy handles the encryption, and Gogs communicates with it over plain HTTP on the local network.
## Caddy
Add the following server block to your `Caddyfile` and reload:
```caddy theme={null}
gogs.example.com {
proxy / http://localhost:3000
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = https://gogs.example.com/
```
Caddy automatically provisions TLS certificates via Let's Encrypt when you use a domain name.
To serve Gogs under a subpath, note the trailing `/`:
```caddy theme={null}
example.com {
proxy /gogs/ http://localhost:3000
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = https://example.com/gogs/
```
## NGINX
Add the following `server` block inside the `http` section of your `nginx.conf` (or in a file under `sites-available`), then reload the NGINX configuration:
```nginx theme={null}
server {
listen 80;
server_name gogs.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = http://gogs.example.com/
```
To serve Gogs under a subpath, note the trailing `/` on both the `location` and `proxy_pass` directives:
```nginx theme={null}
server {
listen 80;
server_name example.com;
location /gogs/ {
proxy_pass http://localhost:3000/;
}
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = http://example.com/gogs/
```
Install [Certbot](https://certbot.eff.org/) and obtain a [Let's Encrypt](https://letsencrypt.org/) certificate:
```bash theme={null}
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d gogs.example.com
```
Certbot will automatically modify your Nginx configuration to use HTTPS. Your Nginx server block will look similar to:
```nginx theme={null}
server {
listen 443 ssl;
server_name gogs.example.com;
ssl_certificate /etc/letsencrypt/live/gogs.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gogs.example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name gogs.example.com;
return 301 https://$host$request_uri;
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = https://gogs.example.com/
```
Certbot sets up automatic renewal via a cron job or systemd timer. Verify with:
```bash theme={null}
sudo certbot renew --dry-run
```
### Large file uploads
If you encounter HTTP `413 Request Entity Too Large` errors when pushing large files through NGINX, add `client_max_body_size` to your server block:
```nginx theme={null}
server {
listen 80;
server_name gogs.example.com;
client_max_body_size 50m;
location / {
proxy_pass http://localhost:3000;
}
}
```
Adjust the `client_max_body_size` value to match or exceed the maximum file size you expect users to push. The default NGINX limit is only 1 MB.
## Apache 2
Create or edit your virtual host configuration file (e.g. `/etc/apache2/vhost.d/gogs.conf`):
```apache theme={null}
ServerName gogs.example.com
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://127.0.0.1:3000
ProxyPassReverse / http://127.0.0.1:3000
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = http://gogs.example.com/
```
To serve Gogs under a subpath, omit the trailing slash after the port number in the `ProxyPass` directives:
```apache theme={null}
ServerName example.com
Order allow,deny
Allow from all
ProxyPass /gogs http://127.0.0.1:3000
ProxyPassReverse /gogs http://127.0.0.1:3000
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = http://example.com/gogs/
```
Enable the `ssl` module in addition to the proxy modules:
```bash theme={null}
sudo a2enmod proxy proxy_http ssl
sudo systemctl restart apache2
```
Apache virtual host configuration:
```apache theme={null}
ServerName gogs.example.com
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
# Redirect HTTP to HTTPS
ServerName gogs.example.com
Redirect permanent / https://gogs.example.com/
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = https://gogs.example.com/
```
## lighttpd
Add the following to your lighttpd configuration:
```lighttpd theme={null}
server.modules += ( "mod_proxy" )
$HTTP["host"] == "gogs.example.com" {
proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "3000" ) ) )
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = http://gogs.example.com/
```
To serve Gogs under a subpath, requires lighttpd **1.4.46 or later** for the `proxy.header` directive:
```lighttpd theme={null}
server.modules += ( "mod_proxy" )
$HTTP["url"] =~ "^/gogs/" {
proxy.server = ( "" => ( ( "host" => "localhost", "port" => "3000" ) ) )
proxy.header = ( "map-urlpath" => ( "/gogs/" => "/" ) )
}
```
Set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = http://example.com/gogs/
```
## IIS
Create a new website in IIS and use the following `web.config` file.
If you do not need HTTPS handled by IIS, remove the entire `RedirectToHttps` rule section from the configuration below.
```xml theme={null}
```
Then set the matching external URL in `custom/conf/app.ini`:
```ini theme={null}
[server]
EXTERNAL_URL = https://gogs.example.com/
```
## Native HTTPS
If you are not using a reverse proxy, Gogs can serve HTTPS directly. Update the `[server]` section of `custom/conf/app.ini`:
```ini theme={null}
[server]
PROTOCOL = https
EXTERNAL_URL = https://gogs.example.com/
CERT_FILE = custom/https/cert.pem
KEY_FILE = custom/https/key.pem
```
| Option | Description | Default |
| ----------------- | ----------------------------------------------------------------- | ----------------------- |
| `PROTOCOL` | Set to `https` to enable native TLS. | `http` |
| `CERT_FILE` | Path to the TLS certificate file (PEM format). | `custom/https/cert.pem` |
| `KEY_FILE` | Path to the TLS private key file (PEM format). | `custom/https/key.pem` |
| `TLS_MIN_VERSION` | Minimum TLS version. Options: `TLS10`, `TLS11`, `TLS12`, `TLS13`. | `TLS12` |
# Run as service
Source: https://gogs.io/fine-tuning/run-as-service
Configure Gogs to start automatically as a system service on Linux, macOS, and Windows
Running Gogs as a system service ensures it starts automatically on boot and restarts if it crashes. Choose the init system or service manager that matches your operating system.
## Linux
Systemd is the default init system on most modern Linux distributions (Ubuntu 16.04+, Debian 8+, CentOS 7+, Fedora, Arch Linux, etc.).
Gogs ships with a [systemd service template](https://github.com/gogs/gogs/blob/main/scripts/systemd/gogs.service) at `scripts/systemd/gogs.service` in the installation directory.
### 1. Customize the service file
Copy the template and edit it to match your installation:
```bash theme={null}
sudo cp /home/git/gogs/scripts/systemd/gogs.service /etc/systemd/system/gogs.service
sudo vim /etc/systemd/system/gogs.service
```
Here is the default service file for reference:
```ini theme={null}
[Unit]
Description=Gogs
After=network.target
After=mariadb.service mysql.service mysqld.service postgresql.service memcached.service redis.service
[Service]
# Uncomment the following if you have repos with lots of files
# and get an HTTP 500 error because of that
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
Type=simple
User=git
Group=git
WorkingDirectory=/home/git/gogs
ExecStart=/home/git/gogs/gogs web
Restart=always
RestartSec=2s
Environment=USER=git HOME=/home/git
# Hardening directives (comment out if not supported by your systemd version)
ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
```
Update the following values to match your environment:
* `User` and `Group` -- the system user running Gogs
* `WorkingDirectory` -- the Gogs installation directory
* `ExecStart` -- the full path to the Gogs binary
* `Environment` -- ensure `USER` and `HOME` match the Gogs user
If you use MySQL/MariaDB, PostgreSQL, Redis, or Memcached, the `After=` lines ensure Gogs starts after those services. Uncomment or add lines as needed for your database.
### 2. Enable and start the service
```bash theme={null}
sudo systemctl enable gogs
sudo systemctl start gogs
```
### 3. Verify the service
```bash theme={null}
# Check status
sudo systemctl status gogs -l
# View logs
sudo journalctl -b -u gogs
```
If you have repositories with a large number of files and encounter HTTP 500 errors, uncomment the `LimitMEMLOCK=infinity` and `LimitNOFILE=65535` directives in the service file.
For Debian-based systems that do not use systemd, Gogs provides an init.d script at `scripts/init/debian/gogs`.
### 1. Copy and customize the script
```bash theme={null}
sudo cp /home/git/gogs/scripts/init/debian/gogs /etc/init.d/gogs
sudo chmod +x /etc/init.d/gogs
sudo vim /etc/init.d/gogs
```
Verify or update the following variables in the script:
```bash theme={null}
WORKINGDIR=/home/git/gogs
DAEMON=$WORKINGDIR/$NAME
DAEMON_ARGS="web"
USER=git
```
If you run Gogs alongside Nginx and PostgreSQL, update the init dependencies at the top of the script:
```bash theme={null}
# Required-Start: $syslog $network $local_fs nginx postgresql
# Required-Stop: $syslog $local_fs
```
### 2. Register and start the service
```bash theme={null}
sudo update-rc.d gogs defaults 30 70
sudo service gogs start
```
### 3. Verify
Visit your Gogs URL in a browser to confirm it is running. You can also check:
```bash theme={null}
sudo service gogs status
```
For CentOS/RHEL systems, Gogs provides an init.d script at `scripts/init/centos/gogs`.
### 1. Copy and customize the script
```bash theme={null}
sudo cp /home/git/gogs/scripts/init/centos/gogs /etc/rc.d/init.d/gogs
sudo chmod +x /etc/rc.d/init.d/gogs
sudo vim /etc/rc.d/init.d/gogs
```
Verify or update the following variables:
```bash theme={null}
NAME=gogs
GOGS_HOME=/home/git/gogs
GOGS_PATH=${GOGS_HOME}/$NAME
GOGS_USER=git
LOGPATH=${GOGS_HOME}/log
```
You can override these defaults by creating `/etc/sysconfig/gogs` with your custom values.
### 2. Register and start the service
```bash theme={null}
sudo chkconfig gogs on
sudo service gogs start
```
### 3. Verify
```bash theme={null}
sudo service gogs status
```
For Gentoo and other distributions using OpenRC, create a service script at `/etc/init.d/gogs`:
```bash theme={null}
#!/sbin/openrc-run
description="Gogs - A painless self-hosted Git service"
command="/home/git/gogs/gogs"
command_args="web"
command_user="git"
command_background=true
pidfile="/var/run/gogs.pid"
directory="/home/git/gogs"
depend() {
need net
after mysql postgresql
}
```
Make it executable and enable it:
```bash theme={null}
sudo chmod +x /etc/init.d/gogs
sudo rc-update add gogs default
sudo rc-service gogs start
```
## Windows
On Windows, Gogs can run as a native Windows service using either the builtin `minwinsvc` support or the third-party NSSM tool.
Gogs binaries built with the `minwinsvc` tag (release archive name that contains `mws`) support running as a native Windows service.
### 1. Configure Gogs for Windows
Edit `C:\gogs\custom\conf\app.ini`:
```ini theme={null}
RUN_USER = COMPUTERNAME$
```
Replace `COMPUTERNAME` with the output of `echo %COMPUTERNAME%` in a command prompt. For example, if the computer name is `USER-PC`, set `RUN_USER = USER-PC$`.
Configure the server section:
```ini theme={null}
[server]
DOMAIN = gogs
PROTOCOL = http
HTTP_ADDR = 127.0.1.1
HTTP_PORT = 80
OFFLINE_MODE = true
EXTERNAL_URL = http://gogs/
```
Using an address in the `127.x.x.x` range (other than `127.0.0.1`) prevents port conflicts with other local services while keeping traffic local. Any address from `127.0.0.2` to `127.254.254.254` works.
### 2. Add a hosts entry
Open Notepad as Administrator and edit `C:\Windows\System32\drivers\etc\hosts`:
```text theme={null}
# Gogs local HTTPd
127.0.1.1 gogs
```
### 3. Create and start the service
Open a command prompt as Administrator:
```cmd theme={null}
sc create gogs start= auto binPath= "\"C:\gogs\gogs.exe\" web --config \"C:\gogs\custom\conf\app.ini\""
```
There must be a space after each `=` in the `sc create` command. This is a Windows `sc.exe` syntax requirement.
Start the service:
```cmd theme={null}
net start gogs
```
You should see:
```text theme={null}
The gogs service is starting.
The gogs service was started successfully.
```
Windows services run from `%WINDIR%\System32` by default. Always use **absolute paths** in `app.ini` for data directories and database files:
```ini theme={null}
[server]
APP_DATA_PATH = c:/gogs/data
[database]
PATH = c:/gogs/data/gogs.db
```
Use forward slashes (`/`) in paths to avoid escape character issues.
[NSSM (Non-Sucking Service Manager)](https://nssm.cc/) provides more control over service configuration and automatic restart behavior.
### 1. Install NSSM
Download [nssm.exe](https://nssm.cc/download) for your architecture (32-bit or 64-bit) and place it in a directory on your `PATH`.
### 2. Install the Gogs service
Open a command prompt as Administrator:
```cmd theme={null}
nssm install gogs
```
The NSSM service installer GUI will appear. Configure the following tabs:
**Application tab:**
* **Path:** `C:\gogs\gogs.exe`
* **Startup directory:** `C:\gogs`
* **Arguments:** `web`
**Details tab:**
* **Display name:** `Gogs`
* **Description:** `Gogs is a painless self-hosted Git service.`
* **Startup type:** `Automatic (Delayed Start)`
Delayed start means the service will begin approximately two minutes after non-delayed services, reducing impact on boot time.
**I/O tab:**
* **Output (stdout):** `C:\gogs\log\gogs-nssm.txt`
* **Error (stderr):** `C:\gogs\log\gogs-nssm.txt`
**File rotation tab:**
* Check **Rotate files**
* **Restrict rotation to files bigger than:** `1000000` bytes
**Environment tab:**
* **Environment variables:** `PATH=%PATH%;C:\gogs;C:\Program Files (x86)\Git\bin`
The environment variable ensures both `gogs.exe` and `git.exe` are available on the service's PATH at runtime.
Click **Install service** to complete the setup.
### 3. Start and manage the service
```cmd theme={null}
nssm start gogs
```
You should see:
```text theme={null}
gogs: START: The operation completed successfully.
```
Verify by checking `C:\gogs\log\gogs-nssm.txt` for Gogs startup output, ending with lines like:
```text theme={null}
[I] Run Mode: Production
[I] Listen: http://127.0.1.1:80
```
To restart after configuration changes:
```cmd theme={null}
nssm restart gogs
```
NSSM will automatically attempt to restart Gogs if it crashes.
# Installation
Source: https://gogs.io/getting-started/installation
Get your own Git service up and running in minutes
## Prerequisites
1. Gogs requires use of one of the following database backends:
* MySQL, >= 5.7
* PostgreSQL, >= 9.6
* SQLite 3
2. Git, >= 1.8.3, on both server and client side
3. SSH server
* Only required when enable Git over SSH, e.g., `git clone git@gogs.example.com:...`
* Builtin SSH server is also available
**For Windows users:**
* When using builtin SSH server, you still need to have `ssh-keygen` installed and available via the `%PATH%` environment variable.
* Use [OpenSSH](https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse) on Windows 10 or newer.
* [Cygwin OpenSSH](http://docs.oracle.com/cd/E24628_01/install.121/e22624/preinstall_req_cygwin_ssh.htm) or [Copssh](https://www.itefix.net/copssh) are available on older versions of Windows.
## Initialize database
If you choose to use MySQL or PostgreSQL as your database backend, you need to first complete the initial database creation.
Create a database user and database:
```bash theme={null}
psql -c "CREATE USER gogs WITH PASSWORD '{YOUR_PASSWORD}';"
psql -c "CREATE DATABASE gogs OWNER gogs ENCODING 'UTF8';"
```
Use the [bundled script](https://github.com/gogs/gogs/blob/main/scripts/mysql.sql) to create the database with proper encoding:
```zsh theme={null}
mysql -u root -p < scripts/mysql.sql
```
## Installation methods
All release archives containing pre-built binaries are available in [dl.gogs.io](https://dl.gogs.io) and [GitHub releases](https://github.com/gogs/gogs/releases).
**For Windows users:**
Release archives containing `mws` come with built-in Windows service support. If you prefer to manage the service using [NSSM](https://nssm.cc), download the standard version instead.
Once extracted the archive, run `gogs web` to start the server. Use `gogs web --help` to see all available options.
Two types of Docker images are provided:
1. [docker-next](https://github.com/gogs/gogs/blob/main/docker-next/README.md): The modern, non-root, and cloud-native version, but with no container options.
2. [docker](https://github.com/gogs/gogs/blob/main/docker/README.md): The traditional, root-privileged version, with extensive container options.
All packages listed below are packaged by third-party maintainers. Use at your own risk.
| Source | Description | Note |
| ----------------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------ |
| Packager.io ([link](https://packager.io/gh/gogs/gogs)) | Every commit of `main` | After installation, place custom configuration in `/etc/default/gogs`. |
| Arch User Repository ([link](https://aur.archlinux.org/packages/gogs/)) | Stable releases | Detailed instructions available in the [Arch Linux Wiki entry](https://wiki.archlinux.org/title/Gogs). |
# Introduction
Source: https://gogs.io/getting-started/introduction
The painless way to host your own Git service
## Vision
The Gogs project aims to build a simple, stable and extensible self-hosted Git service that can be set up in the most painless way. With Go, this can be done with an independent binary distribution across all platforms that Go supports, including Linux, macOS, Windows and ARM-based systems.
## Core values
* **Simple to install**: Run the binary, or run as a Docker container.
* **Cross-platform**: Runs on every platform that Go toolchain supports.
* **Lightweight**: Unrealistically low resource consumption to get started. Only got 64 MiB of RAM and a quarter of vCPU? No problem!
* **Open source**: MIT-licensed since 2014, all source code available in public.
## Sponsors
The growth of the Gogs project wasn't possible without our world-class sponsors!
## Quickstart
Get your own Git service up and running in minutes.
Fine tune your instance exactly the way you want.
Discover powerful and advanced features.
Keep up the version and energy.