A lightweight self-hosted Git service in Go that replaces AWS CodeCommit with low-memory single-binary deployments and native webhooks.
Jiahua Chen created Gogs in 2014 to provide a self-hosted Git service that compiled into a single binary and ran on low-power devices like the Raspberry Pi. By building the platform in Go without heavy JVM runtimes or multi-tier services, the project established a lightweight alternative to resource-heavy source control suites. Today, that origin ensures developers and DevOps engineers can run private Git repositories, webhooks, and issue tracking with negligible memory overhead.
AWS CodeCommit couples repository hosting to the Amazon Web Services ecosystem. Integrating CodeCommit with external tooling requires configuring AWS IAM policies, managing credential helpers, and wiring SNS topics or EventBridge rules to dispatch events to CI runners. Gogs treats integrations as standard network protocols. It sends HTTP webhooks on repository events directly to Jenkins, Drone, Discord, or Slack without cloud brokers, while supporting standard SSH keys and personal access tokens across standard Git clients.
Authentication reflects the same divide. Where CodeCommit requires IAM roles and cloud identities, Gogs integrates directly with on-premises LDAP, Active Directory, PAM, SMTP servers, and reverse proxy headers. The trade-off is operational maintenance: CodeCommit was a serverless Git store on managed AWS storage, whereas Gogs requires maintaining a host and an SQL database such as SQLite, PostgreSQL, or MySQL. With AWS halting new customer onboarding for CodeCommit, Gogs gives teams a vendor-neutral Git server that integrates cleanly with internal CI/CD pipelines.
Is Gogs free for commercial use? Yes. Gogs is open-source software under the MIT license and carries no seat fees or commercial restrictions.
Gogs vs AWS CodeCommit — which should I choose? Choose AWS CodeCommit only if your workflows are permanently bound to AWS IAM, though AWS no longer accepts new customers. Choose Gogs if you need a self-hosted Git platform that runs on any server and connects cleanly to external CI systems and LDAP.
What are the minimum hardware requirements to run Gogs? A single CPU core and 512 megabytes of RAM comfortably support teamwork, while personal setups can run on 64 megabytes of memory using SQLite.
Gogs is an effective choice when a team needs a low-resource Git forge that installs quickly and integrates with standard DevOps pipelines; it is not suited for organizations requiring line-by-line pull request audits, native kanban boards, or built-in CI runners. Ongoing development with commits actively landing in September 2026 and a permissive MIT license that allows unrestricted internal modification make it a dependable foundation for self-hosted source control.
Commands from the official package registries. Each package is matched to Gogs through the registry's own link to its source code or website.
brew install --cask gogsWe started this exact setup from scratch in a clean Linux machine on Nov 1, 2026 and checked it through Gogs's own API: every check passed. Recipes are re-checked regularly and removed if they stop working.
mkdir -p gogs && cd gogs
curl -fsSL https://open-source.store/tools/gogs/compose.yml -o compose.ymlcat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 12)
APP_URL=http://localhost:3000
EOFPOSTGRES_PASSWORD — Password of the bundled PostgreSQL database. Generated above; keep it secret.APP_URL — Public URL where Gogs is reached (e.g. http://<your-server>:3000); entered during web installation and used by smoke test.docker compose up -dservices:
gogs:
image: gogs/gogs:0.14.3
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
volumes:
- gogs-data:/data
restart: always
healthcheck:
test: ["CMD", "curl", "-fsSL", "http://localhost:3000/"]
interval: 5s
timeout: 5s
retries: 10
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: gogs
POSTGRES_USER: gogs
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- gogs-db-data:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
gogs-data:
gogs-db-data:
Lint, codegen, breaking-change checks and dependency management in one Git-native CLI. Open source, no registry lock-in.
Show that Gogs is listed as an open-source alternative. Paste into your README:
Ubuntu 24.04 · Apple container, Docker 29.1.3, Compose 2.40.3+ds1-0ubuntu1~24.04.1. Images pulled in 28 s: gogs/gogs:0.14.3, postgres:16-alpine.
Based on the upstream setup. Official Docker image pinned to 0.14.3 with PostgreSQL database. Database password moved to .env; healthchecks added; SSH port 22 is not published so Git operations use HTTP.
db-1 | 2026-11-01T20:28:05.812042097Z The default text search configuration will be set to "english". db-1 | 2026-11-01T20:28:05.812042639Z db-1 | 2026-11-01T20:28:05.812043097Z Data page checksums are disabled. db-1 | 2026-11-01T20:28:05.812043556Z db-1 | 2026-11-01T20:28:05.812044014Z fixing permissions on existing directory /var/lib/postgresql/data ... ok db-1 | 2026-11-01T20:28:05.813074847Z creating subdirectories ... ok db-1 | 2026-11-01T20:28:05.813130764Z selecting dynamic shared memory implementation ... posix db-1 | 2026-11-01T20:28:05.820265847Z selecting default max_connections ... 100 db-1 | 2026-11-01T20:28:05.827649597Z selecting default shared_buffers ... 128MB db-1 | 2026-11-01T20:28:05.838518556Z selecting default time zone ... UTC db-1 | 2026-11-01T20:28:05.838765014Z creating configuration files ... ok db-1 | 2026-11-01T20:28:05.884784139Z running bootstrap script ... ok db-1 | 2026-11-01T20:28:05.949959639Z sh: locale: not found db-1 | 2026-11-01T20:28:05.949971722Z 2026-11-01 20:28:05.949 UTC [34] WARNING: no usable system locales were found db-1 | 2026-11-01T20:28:06.082705889Z performing post-bootstrap initialization ... ok db-1 | 2026-11-01T20:28:06.127957597Z syncing data to disk ... ok db-1 | 2026-11-01T20:28:06.127970347Z db-1 | 2026-11-01T20:28:06.127971222Z db-1 | 2026-11-01T20:28:06.127971847Z Success. You can now start the database server using: db-1 | 2026-11-01T20:28:06.127972431Z db-1 | 2026-11-01T20:28:06.127972972Z pg_ctl -D /var/lib/postgresql/data -l logfile start db-1 | 2026-11-01T20:28:06.127973514Z db-1 | 2026-11-01T20:28:06.127982597Z initdb: warning: enabling "trust" authentication for local connections db-1 | 2026-11-01T20:28:06.127983889Z initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. db-1 | 2026-11-01T20:28:06.145548931Z waiting for server to start....2026-11-01 20:28:06.145 UTC [40] LOG: starting PostgreSQL 16.15 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 15.2.0) 15.2.0, 64-bit db-1 | 2026-11-01T20:28:06.146180431Z 2026-11-01 20:28:06.146 UTC [40] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db-1 | 2026-11-01T20:28:06.148494222Z 2026-11-01 20:28:06.148 UTC [43] LOG: database system was shut down at 2026-11-01 20:28:06 UTC db-1 | 2026-11-01T20:28:06.150095556Z 2026-11-01 20:28:06.150 UTC [40] LOG: database system is ready to accept connections db-1 | 2026-11-01T20:28:06.237827139Z done db-1 | 2026-11-01T20:28:06.237841014Z server started db-1 | 2026-11-01T20:28:06.257629389Z CREATE DATABASE db-1 | 2026-11-01T20:28:06.258789848Z db-1 | 2026-11-01T20:28:06.258810014Z db-1 | 2026-11-01T20:28:06.258815098Z /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/* db-1 | 2026-11-01T20:28:06.258815973Z db-1 | 2026-11-01T20:28:06.259103681Z waiting for server to shut down....2026-11-01 20:28:06.259 UTC [40] LOG: received fast shutdown request db-1 | 2026-11-01T20:28:06.261878764Z 2026-11-01 20:28:06.261 UTC [40] LOG: aborting any active transactions db-1 | 2026-11-01T20:28:06.262613889Z 2026-11-01 20:28:06.262 UTC [40] LOG: background worker "logical replication launcher" (PID 46) exited with exit code 1 db-1 | 2026-11-01T20:28:06.262671848Z 2026-11-01 20:28:06.262 UTC [41] LOG: shutting down db-1 | 2026-11-01T20:28:06.269533181Z 2026-11-01 20:28:06.269 UTC [41] LOG: checkpoint starting: shutdown immediate db-1 | 2026-11-01T20:28:06.286900473Z 2026-11-01 20:28:06.286 UTC [41] LOG: checkpoint complete: wrote 926 buffers (5.7%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.007 s, sync=0.010 s, total=0.025 s; sync files=301, longest=0.005 s, average=0.001 s; distance=4283 kB, estimate=4283 kB; lsn=0/1925D10, redo lsn=0/1925D10 db-1 | 2026-11-01T20:28:06.289751806Z 2026-11-01 20:28:06.289 UTC [40] LOG: database system is shut down db-1 | 2026-11-01T20:28:06.361185764Z done db-1 | 2026-11-01T20:28:06.361207389Z server stopped db-1 | 2026-11-01T20:28:06.361573098Z db-1 | 2026-11-01T20:28:06.361577723Z PostgreSQL init process complete; ready for start up. db-1 | 2026-11-01T20:28:06.361578681Z db-1 | 2026-11-01T20:28:06.371991514Z 2026-11-01 20:28:06.371 UTC [1] LOG: starting PostgreSQL 16.15 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 15.2.0) 15.2.0, 64-bit db-1 | 2026-11-01T20:28:06.372017514Z 2026-11-01 20:28:06.371 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 db-1 | 2026-11-01T20:28:06.372019556Z 2026-11-01 20:28:06.371 UTC [1] LOG: listening on IPv6 address "::", port 5432 db-1 | 2026-11-01T20:28:06.372991306Z 2026-11-01 20:28:06.372 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db-1 | 2026-11-01T20:28:06.374355848Z 2026-11-01 20:28:06.374 UTC [56] LOG: database system was shut down at 2026-11-01 20:28:06 UTC db-1 | 2026-11-01T20:28:06.377507848Z 2026-11-01 20:28:06.377 UTC [1] LOG: database system is ready to accept connections db-1 | 2026-11-01T20:28:28.346114509Z 2026-11-01 20:28:28.345 UTC [92] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:28:28.346133843Z 2026-11-01 20:28:28.345 UTC [92] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:28:28.346135426Z 2026-11-01 20:28:28.345 UTC [92] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:28:28.347182551Z 2026-11-01 20:28:28.347 UTC [92] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:28:28.347195801Z 2026-11-01 20:28:28.347 UTC [92] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:28:28.347196968Z 2026-11-01 20:28:28.347 UTC [92] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:29:18.324727545Z 2026-11-01 20:29:18.322 UTC [196] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:29:18.324755045Z 2026-11-01 20:29:18.322 UTC [196] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:29:18.324758462Z 2026-11-01 20:29:18.322 UTC [196] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:29:19.345484546Z 2026-11-01 20:29:19.345 UTC [193] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:29:19.345497629Z 2026-11-01 20:29:19.345 UTC [193] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:29:19.345498712Z 2026-11-01 20:29:19.345 UTC [193] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:30:03.340744468Z 2026-11-01 20:30:03.340 UTC [198] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:30:03.340762552Z 2026-11-01 20:30:03.340 UTC [198] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:30:03.340763677Z 2026-11-01 20:30:03.340 UTC [198] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:30:03.341418343Z 2026-11-01 20:30:03.341 UTC [190] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:30:03.341422302Z 2026-11-01 20:30:03.341 UTC [190] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:30:03.341423093Z 2026-11-01 20:30:03.341 UTC [190] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:30:04.359361010Z 2026-11-01 20:30:04.359 UTC [194] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:30:04.359373094Z 2026-11-01 20:30:04.359 UTC [194] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:30:04.359374177Z 2026-11-01 20:30:04.359 UTC [194] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:30:04.363275302Z 2026-11-01 20:30:04.363 UTC [205] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:30:04.363285302Z 2026-11-01 20:30:04.363 UTC [205] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:30:04.363286094Z 2026-11-01 20:30:04.363 UTC [205] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:30:09.348228971Z 2026-11-01 20:30:09.346 UTC [201] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:30:09.348232680Z 2026-11-01 20:30:09.346 UTC [201] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:30:09.348233471Z 2026-11-01 20:30:09.346 UTC [201] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 db-1 | 2026-11-01T20:30:09.348234430Z 2026-11-01 20:30:09.348 UTC [198] ERROR: invalid byte sequence for encoding "UTF8": 0x00 db-1 | 2026-11-01T20:30:09.348235096Z 2026-11-01 20:30:09.348 UTC [198] CONTEXT: unnamed portal parameter $1 db-1 | 2026-11-01T20:30:09.348235763Z 2026-11-01 20:30:09.348 UTC [198] STATEMENT: SELECT * FROM "user" WHERE lower_name = $1 ORDER BY "user"."id" LIMIT $2 gogs-1 | 2026-11-01T20:28:11.702891793Z usermod: no changes gogs-1 | 2026-11-01T20:28:11.717093001Z Nov 1 20:28:11 syslogd started: BusyBox v1.37.0 gogs-1 | 2026-11-01T20:28:11.744279501Z 2026/11/01 20:28:11 [ WARN] Custom config "/data/gogs/conf/app.ini" not found. Ignore this warning if you're running for the first time gogs-1 | 2026-11-01T20:28:11.746038001Z 2026/11/01 20:28:11 [TRACE] Log mode: Console (Trace) gogs-1 | 2026-11-01T20:28:11.748608960Z 2026/11/01 20:28:11 [ INFO] Gogs 0.14.3 gogs-1 | 2026-11-01T20:28:11.748613876Z 2026/11/01 20:28:11 [TRACE] Work directory: /app/gogs gogs-1 | 2026-11-01T20:28:11.748614501Z 2026/11/01 20:28:11 [TRACE] Custom path: /data/gogs gogs-1 | 2026-11-01T20:28:11.748615335Z 2026/11/01 20:28:11 [TRACE] Custom config: /data/gogs/conf/app.ini gogs-1 | 2026-11-01T20:28:11.748615918Z 2026/11/01 20:28:11 [TRACE] Log path: /app/gogs/log gogs-1 | 2026-11-01T20:28:11.748616418Z 2026/11/01 20:28:11 [TRACE] Build time: 2026-06-07 08:52:15 UTC gogs-1 | 2026-11-01T20:28:11.748617001Z 2026/11/01 20:28:11 [TRACE] Build commit: 3ba8aca90e17e5410b7e8b227c9f29256ac3e875 gogs-1 | 2026-11-01T20:28:11.748617543Z 2026/11/01 20:28:11 [ INFO] Run mode: Development gogs-1 | 2026-11-01T20:28:11.783472751Z 2026/11/01 20:28:11 [ INFO] Available on http://localhost:3000/ gogs-1 | 2026-11-01T20:28:11.813065043Z 2026/11/01 20:28:11 [TRACE] Session ID: fe7a26a7489737d4 gogs-1 | 2026-11-01T20:28:11.813098168Z 2026/11/01 20:28:11 [TRACE] CSRF Token: P2YPlT9n35aeXACNIehiCB0L4wY6MTc5MzU2NDg5MTgxMjAxMTQxOA gogs-1 | 2026-11-01T20:28:11.821479002Z unknown key type dsa gogs-1 | 2026-11-01T20:28:11.828765918Z Unable to load host key: /data/ssh/ssh_host_dsa_key gogs-1 | 2026-11-01T20:28:11.829361043Z Nov 1 20:28:11 sshd[55]: Server listening on :: port 22. gogs-1 | 2026-11-01T20:28:11.829371627Z Nov 1 20:28:11 sshd[55]: Server listening on 0.0.0.0 port 22. gogs-1 | 2026-11-01T20:28:11.926779918Z 2026/11/01 20:28:11 [ INFO] Gogs 0.14.3 gogs-1 | 2026-11-01T20:28:11.998323085Z [git-module] [timeout: 1m0s] git version gogs-1 | 2026-11-01T20:28:11.998343085Z git version 2.47.3 gogs-1 | 2026-11-01T20:28:11.998344168Z gogs-1 | 2026-11-01T20:28:11.999075043Z 2026/11/01 20:28:11 [ INFO] Git config user.name set to Gogs gogs-1 | 2026-11-01T20:28:11.999668918Z 2026/11/01 20:28:11 [ INFO] Git config user.email set to [email protected] gogs-1 | 2026-11-01T20:28:12.000241210Z 2026/11/01 20:28:12 [ INFO] Run mode: Production gogs-1 | 2026-11-01T20:28:12.005572002Z 2026/11/01 20:28:12 [ INFO] First-time run install finished! gogs-1 | 2026-11-01T20:28:28.346188884Z 2026/11/01 20:28:28 [ERROR] [...gogs/internal/route/repo/http.go:98 func12()] Failed to get user [name: .]: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:28:28.347207551Z 2026/11/01 20:28:28 [ERROR] [...gogs/internal/route/repo/http.go:98 func12()] Failed to get user [name: .]: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:29:18.328711754Z 2026/11/01 20:29:18 [ERROR] [...gogs/internal/context/context.go:189 NotFoundOrError()] get user by name: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:29:19.350898546Z 2026/11/01 20:29:19 [ERROR] [...gogs/internal/context/context.go:189 NotFoundOrError()] get user by name: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:30:03.343992385Z 2026/11/01 20:30:03 [ERROR] [...gogs/internal/context/context.go:189 NotFoundOrError()] get user by name: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:30:03.344001635Z 2026/11/01 20:30:03 [ERROR] [...gogs/internal/context/context.go:189 NotFoundOrError()] get user by name: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:30:04.359447927Z 2026/11/01 20:30:04 [ERROR] [...gogs/internal/context/context.go:189 NotFoundOrError()] get user by name: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:30:04.363452219Z 2026/11/01 20:30:04 [ERROR] [...gogs/internal/context/context.go:189 NotFoundOrError()] get user by name: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:30:09.348209846Z 2026/11/01 20:30:09 [ERROR] [...gogs/internal/route/repo/http.go:98 func12()] Failed to get user [name: ..]: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021) gogs-1 | 2026-11-01T20:30:09.350176638Z 2026/11/01 20:30:09 [ERROR] [...gogs/internal/route/repo/http.go:98 func12()] Failed to get user [name: ..]: ERROR: invalid byte sequence for encoding "UTF8": 0x00 (SQLSTATE 22021)