# How the Web Command is Implemented in Gitea: Server Startup Architecture

> Discover how the Gitea web command initiates its HTTP/HTTPS service. Learn about graceful shutdown, installation mode, debug servers, and protocol listeners in this Gitea server startup architecture.

- Repository: [Gitea/gitea](https://github.com/go-gitea/gitea)
- Tags: architecture
- Published: 2026-03-07

---

**The `web` command is implemented in [`cmd/web.go`](https://github.com/go-gitea/gitea/blob/main/cmd/web.go) and serves as the primary entry point for the Gitea HTTP/HTTPS service, orchestrating graceful shutdown handling, optional installation mode, debug servers, and protocol-specific listeners.**

The `web` command is the standard method for starting the Gitea self-hosted Git service. According to the go-gitea/gitea source code, this command handles the complete server lifecycle from CLI argument parsing through graceful termination, supporting multiple protocols including HTTP, HTTPS, FCGI, and Unix domain sockets.

## CLI Registration and Flag Parsing

### Command Definition in cmd/web.go

In [`cmd/web.go`](https://github.com/go-gitea/gitea/blob/main/cmd/web.go), the web command is defined as a `cli.Command` struct named **`CmdWeb`** (lines 37‑73). This structure registers the command name, description, and available flags. The `Action` field is set to **`runWeb`** (lines 44‑45), which serves as the entry point executed when users invoke `gitea web`.

### Supported Command-Line Flags

The command accepts several configuration flags:

- **`--port`** – Overrides the default HTTP port (3000).
- **`--install-port`** – Specifies a temporary port for the installation wizard.
- **`--pid`** – Path to write the process ID file.
- **`--quiet`** and **`--verbose`** – Control logging verbosity before the logger is fully initialized.

## Pre-Startup Initialization Sequence

Before accepting connections, the command performs critical setup steps to ensure stable operation and clean shutdown capabilities.

### Graceful Shutdown Manager

At lines 55‑58, the code invokes **`graceful.InitManager`** to create a shutdown coordinator. This manager captures termination signals (SIGINT, SIGTERM) and tracks background goroutines, ensuring the server completes in-flight requests before exiting.

### Process Identification File

If the **`--pid`** flag is provided, the function **`createPIDFile`** (lines 65‑68) writes the process ID to the specified path. This enables external process managers to monitor or terminate the Gitea instance.

### Template System Preparation

At lines 70‑73, the command initializes the HTML template renderer via **`_ = templates.PageRenderer()`**. This early initialization ensures template syntax errors are caught before the server starts serving traffic.

## Server Mode Selection

The implementation branches based on whether Gitea has been installed or requires first-time configuration.

### Installation Mode

When `setting.InstallLock == false`, indicating a fresh instance, the code calls **`serveInstall`** (lines 74‑78). This function starts a temporary HTTP server on the **`--install-port`** to serve the installation wizard, allowing administrators to complete initial configuration through a web interface.

### Debug Server Initialization

If profiling is enabled, the command launches **`servePprof`** in a separate goroutine (lines 82‑84). This exposes Go runtime profiling endpoints on a distinct port for performance analysis without interfering with the main application routes.

### Standard Production Mode

For installed instances, execution proceeds to **`serveInstalled`** (lines 86‑87), which configures and starts the standard Gitea web service with full routing and authentication capabilities.

## HTTP Server Construction and Protocol Handling

Once in production mode, the command constructs the actual HTTP server infrastructure.

### Route Registration

Inside `serveInstalled`, the function **`routers.InitWebInstalled`** (lines 104‑105) registers all application routes, middleware chains, and static file handlers. This establishes the complete URL routing table for Git operations, web UI, and API endpoints.

### Dynamic Port Configuration

The **`setPort`** function (lines 176‑182) handles the **`--port`** flag by rewriting `setting.AppURL` and updating `LOCAL_ROOT_URL` in the configuration file. This ensures generated URLs and redirects reflect the user-specified port.

### Protocol-Specific Listener Creation

The **`listen`** function (lines 210‑280) creates the actual network listener based on `setting.Protocol`. It supports:

- **HTTP** – Standard TCP listener.
- **HTTPS** – TLS-enabled listener using configured certificates.
- **FCGI** – FastCGI protocol support for integration with external web servers.
- **Unix sockets** – File-based sockets for reverse proxy setups.

### HTTP-to-HTTPS Redirection

When HTTPS is enabled, **`runHTTPRedirector`** (lines 75‑95) starts a companion HTTP server that forwards all requests to `setting.AppURL`. This ensures users accessing the HTTP port are automatically redirected to the secure HTTPS endpoint.

## Practical Usage Examples

You can start the Gitea server with various configuration overrides directly from the command line:

```bash

# Start Gitea with the default configuration (HTTP on port 3000)

gitea web

# Override the HTTP port

gitea web --port 8080

# Run the installer on a temporary port (useful for first-time setup)

gitea web --install-port 3001

# Write the process ID to a custom file

gitea web --pid /var/run/gitea.pid

# Enable verbose logging until the logger is fully configured

gitea web --verbose

```

For programmatic invocation within Go applications, the command can be executed through the `cli` package:

```go
app := &cli.App{
    Commands: []*cli.Command{cmd.CmdWeb},
}
app.Run([]string{"gitea", "web", "--port", "8080"})

```

## Graceful Termination

### Blocking on Shutdown Signals

The command blocks on **`<-graceful.GetManager().Done()`** (lines 29‑31), waiting for the graceful manager to signal completion. When a termination signal is received, the listener stops accepting new connections, existing requests finish processing, and the process exits cleanly without dropping active Git operations.

## Summary

- The **`web` command** is defined in [`cmd/web.go`](https://github.com/go-gitea/gitea/blob/main/cmd/web.go) as a `cli.Command` with the **`runWeb`** action handler.
- Initialization includes **graceful shutdown management**, optional **PID file creation**, and **template pre-loading** to fail fast on configuration errors.
- The command detects **installation state** and either serves the setup wizard via `serveInstall` or the full production server via `serveInstalled`.
- **Protocol support** includes HTTP, HTTPS, FCGI, and Unix sockets via the **`listen`** function (lines 210‑280).
- **Graceful shutdown** is coordinated through `graceful.GetManager().Done()`, ensuring zero-downtime termination of the Gitea web command.

## Frequently Asked Questions

### What file contains the web command implementation?

The web command is fully implemented in **[`cmd/web.go`](https://github.com/go-gitea/gitea/blob/main/cmd/web.go)**. This file contains the `CmdWeb` struct definition (lines 37‑73), flag parsing logic, server initialization functions (`serveInstall`, `serveInstalled`), and the graceful shutdown coordination that manages the entire process lifecycle.

### How does Gitea handle graceful shutdown?

Gitea initializes a **graceful shutdown manager** via `graceful.InitManager` at startup (lines 55‑58). The main goroutine blocks on `graceful.GetManager().Done()` (lines 29‑31) until a termination signal is received. This mechanism allows active HTTP connections and background workers to complete before the process exits, preventing interrupted Git operations or data corruption.

### What protocols does the Gitea web command support?

The **`listen`** function (lines 210‑280) supports multiple protocols based on `setting.Protocol`: standard **HTTP**, **HTTPS** with TLS certificate configuration, **FCGI** for FastCGI integration with front-end web servers, and **Unix domain sockets** for file-based communication with reverse proxies like Nginx or Apache.

### How is the installation wizard triggered?

When `setting.InstallLock` is `false`, indicating Gitea has not been configured, the command automatically enters **installation mode** via `serveInstall` (lines 74‑78). This serves the web-based setup interface on the port specified by **`--install-port`**, allowing administrators to complete database configuration and admin account creation before the main server starts.