本教程适用于以下操作系统版本
- Debian 12(Bookworm)
- Debian 11(Bullseye)
- Debian 10(Buster)
本页内容
- 先决条件
- 第 1 步 - 配置防火墙
- 第 2 步 - 安装 Docker 和 Docker Compose
- 第 3 步 - 创建 Git 用户
- 第 4 步 - 配置并安装 Gitea 配置系统时区 创建 Gitea 目录 配置 Gitea Docker Compose 文件 自定义你的 Gitea 安装 安装 Gitea
- 第 5 步 - 安装 Nginx
- 第 6 步 - 安装 SSL
- 第 7 步 - 配置 Nginx
- 第 8 步 - 访问并配置 Gitea
- 第 8 步 - 创建第一个仓库
- 第 9 步 - 配置 SSH
- 第 10 步 - 使用 SSH 克隆仓库
- 第 11 步 - 测试首次提交
- 第 12 步 - 备份和恢复 Gitea
- 第 13 步 - 升级 Gitea
- 结论
- 配置系统时区
- 创建 Gitea 目录
- 配置 Gitea Docker Compose 文件
- 自定义你的 Gitea 安装
- 安装 Gitea
Gitea 是一个基于 Git 平台的开源代码托管解决方案。它使用 Go 语言编写,可以安装在多种操作系统上,包括 Linux、macOS、Windows,以及 amd64、i386、ARM 等多种架构。它包含仓库文件编辑器、问题跟踪、拉取请求、用户管理、通知、内置 wiki、LFS 支持、Git 钩子等众多功能。
它是一个轻量级应用程序。因此,它可以安装在性能较低的系统上。如果你正在寻找一个占用内存较小的自托管 Git 平台,你应该了解一下 Gitea。
本文将介绍如何在 Debian 12 服务器上安装和配置 Gitea,并设置你的第一个 Git 仓库。Gitea 可以从源代码、二进制文件、Docker 包或软件包进行安装。在本教程中,我们将使用 Docker 进行安装。
先决条件
- 一台运行 Debian 12 的服务器。
- 一个具有 sudo 权限的非 root 用户。
- 一个指向你服务器的完全限定域名(FQDN),例如 gitea.example.com。
- 如果你的服务器只有 1GB 内存,请确保已启用 swap 交换存储。
- 确保系统已更新。$ sudo apt update && sudo apt upgrade
- 在继续之前需要安装一些必要的软件包。其中部分可能已经安装在你的服务器上。$ sudo apt install curl wget nano software-properties-common dirmngr apt-transport-https ca-certificates lsb-release debian-archive-keyring gnupg2 ufw unzip -y
一台运行 Debian 12 的服务器。
一个具有 sudo 权限的非 root 用户。
一个指向你服务器的完全限定域名(FQDN),例如 gitea.example.com。
如果你的服务器只有 1GB 内存,请确保已启用 swap 交换存储。
确保系统已更新。
$ sudo apt update && sudo apt upgrade
在继续之前需要安装一些必要的软件包。其中部分可能已经安装在你的服务器上。
$ sudo apt install curl wget nano software-properties-common dirmngr apt-transport-https ca-certificates lsb-release debian-archive-keyring gnupg2 ufw unzip -y
第 1 步 - 配置防火墙
第一步是配置防火墙。Debian 默认自带 ufw(Uncomplicated Firewall,简易防火墙)。
检查防火墙是否正在运行。
$ sudo ufw status
你将看到如下输出。
Status: inactive
允许 SSH 端口,以免启用防火墙时中断当前连接。
$ sudo ufw allow OpenSSH
同时允许 HTTP 和 HTTPS 端口。
$ sudo ufw allow http
$ sudo ufw allow https
启用防火墙
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
再次检查防火墙的状态。
$ sudo ufw status
你应该会看到类似的输出。
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
第 2 步 - 安装 Docker 和 Docker Compose
Debian 12 自带较旧版本的 Docker。要安装最新版本,首先导入 Docker 的 GPG 密钥。
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
创建 Docker 仓库文件。
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
更新系统仓库列表。
$ sudo apt update
安装最新版本的 Docker。
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
验证它是否正在运行。
$ sudo systemctl status docker
? docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Sat 2023-11-18 07:13:39 UTC; 10s ago
TriggeredBy: ? docker.socket
Docs: https://docs.docker.com
Main PID: 1891 (dockerd)
Tasks: 8
Memory: 27.2M
CPU: 338ms
CGroup: /system.slice/docker.service
??1891 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
默认情况下,Docker 需要 root 权限。如果你想在每次运行 docker 命令时不必使用 sudo,可以将你的用户名添加到 docker 组。
$ sudo usermod -aG docker $(whoami)
你需要注销服务器并以同一用户重新登录以使更改生效,或者使用以下命令。
$ su - ${USER}
确认你的用户已添加到 Docker 组。
$ groups
navjot sudo users docker
第 3 步 - 创建 Git 用户
为了让用户能够通过 SSH 访问主机,你需要在主机上创建一个单独的 git 用户。运行以下命令来创建 git 用户。
$ sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
让我们逐一了解上述命令中的所有选项和参数,以便更好地理解。
- --system - 创建一个系统用户而非普通用户。系统用户用于运行系统服务,不能用于交互式登录。
- --shell /bin/bash - 将系统用户的登录 shell 设置为 Bash shell。
- --gecos 'Git Version Control' - 为用户设置描述性字段。该选项是可选的,可以跳过,但如果你的系统用户较多,它会很有用。
- --group - 创建一个与用户名同名的组。
- --disabled-password - 禁用该用户的密码登录,有助于提升账户安全性。
- --home /home/git - 将用户的家目录设置为 /home/git,用于存储用户的文件和配置。
- git - 指定用户名。这里我们使用 git 作为该账户的用户名。
运行命令后,你将看到如下输出。
Adding system user `git' (UID 105) ...
Adding new group `git' (GID 111) ...
Adding new user `git' (UID 105) with group `git' ...
Creating home directory `/home/git' ...
记下变量 UID 和 GID 的值,我们下一步会用到。在我们的示例中,UID 为 105,GID 为 111。
第 4 步 - 配置并安装 Gitea
配置系统时区
你可以通过以下命令查看系统当前的时区。
$ timedatectl
Local time: Sat 2023-11-18 07:15:53 UTC
Universal time: Sat 2023-11-18 07:15:53 UTC
RTC time: Sat 2023-11-18 07:15:53
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
你可以看到系统设置为 GMT 或 UTC 时区。如果你所在的地区使用不同的时区,或者想要更改时区,请使用以下命令进行设置。
$ sudo timedatectl set-timezone Asia/Kolkata
再次检查时区。
$ timedatectl
Local time: Sat 2023-11-18 12:46:29 IST
Universal time: Sat 2023-11-18 07:16:29 UTC
RTC time: Sat 2023-11-18 07:16:29
Time zone: Asia/Kolkata (IST, +0530)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
你可以看到时区已更新为 IST,即 GMT+5:30。
创建 Gitea 目录
创建 Gitea 的目录。
$ mkdir ~/gitea-docker
切换到 Gitea 目录。
$ cd ~/gitea-docker
创建用于存储 Gitea 数据和 PostgreSQL 数据库的目录。
$ mkdir {gitea,postgres}
配置 Gitea Docker Compose 文件
创建并打开 Docker Compose 文件进行编辑。
$ nano docker-compose.yml
在其中粘贴以下代码。粘贴之前生成的 UID 和 GID 值。
services:
server:
image: gitea/gitea:1.21.0
container_name: gitea
environment:
- USER_UID=105
- USER_GID=111
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /home/git/.ssh/:/data/git/.ssh
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2221:22"
depends_on:
- db
db:
image: postgres:15
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data
networks:
gitea:
external: false
按 Ctrl + X 保存文件,并在提示时输入 Y。
我们使用的是上一步创建的用户的 UID(用户标识符)和 GID(组标识符)值。
上述 Docker Compose 文件部署了两个容器——一个用于 Gitea,一个用于 PostgreSQL。我们添加了一些环境变量来配置数据库详情。要将 PostgreSQL 数据库连接到 Gitea 容器,我们在文件中将主机指定为 PostgreSQL 服务的名称。
端口参数 "3000:3000" 和 "2221:22" 指定了端口映射,左侧端口表示主机端口,右侧端口表示容器端口。Gitea 使用 3000 端口提供 Web 服务,这也是我们暴露给服务器的端口。对于 SSH,我们的系统已经使用 22 端口用于登录。因此,我们指定一个自定义端口来执行 SSH 操作。在本示例中,我们使用 2221 端口。该端口也需要通过防火墙开放,这我们已经在本教程的第 1 步中完成。
Gitea 和 PostgreSQL 容器都通过一个名为 gitea 的通用内部 Docker 网络相互连接。当你启动 Docker 安装时,卷挂载会自动在当前文件夹中创建 gitea 和 postgres 目录。compose 文件中指定的用户 ID 就是 Gitea 容器用来创建 gitea 目录的 ID。另一方面,PostgreSQL 容器将由用户 systemd-coredump 管理,这是默认行为。你可以更改该行为,但并非必须。
自定义你的 Gitea 安装
你可以通过将 app.ini 文件添加到 ~/gitea-docker/gitea/gitea/conf 目录来自定义 Gitea 安装。安装完成后,可以从容器内部在 /data/gitea/conf/app.ini 位置编辑该文件。你可以参考 Gitea 的 Github 仓库中的示例 ini 文件。
安装 Gitea
运行以下命令启动 Gitea 容器。
$ docker compose up -d
检查容器的状态,确保它们正常运行。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b5ce50a04fe gitea/gitea:1.21.0 "/usr/bin/entrypoint…" 43 seconds ago Up 42 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 0.0.0.0:2221->22/tcp, :::2221->22/tcp gitea
0908cb9ec3b7 postgres:15 "docker-entrypoint.s…" 43 seconds ago Up 42 seconds 5432/tcp gitea-docker-db-1
你也可以使用以下命令来检查状态。
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
gitea gitea/gitea:1.21.0 "/usr/bin/entrypoint /bin/s6-svscan /etc/s6" server About a minute ago Up About a minute 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 0.0.0.0:2221->22/tcp, :::2221->22/tcp
gitea-docker-db-1 postgres:15 "docker-entrypoint.sh postgres" db About a minute ago Up About a minute 5432/tcp
第 5 步 - 安装 Nginx
Debian 12 自带较旧版本的 Nginx。要安装最新版本,你需要下载官方的 Nginx 仓库。
导入 Nginx 的签名密钥。
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
添加 Nginx 稳定版的仓库。
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
更新系统仓库。
$ sudo apt update
安装 Nginx。
$ sudo apt install nginx
验证安装。在 Debian 系统上,以下命令只能配合 sudo 使用。
$ sudo nginx -v
nginx version: nginx/1.24.0
启动 Nginx 服务器。
$ sudo systemctl start nginx
检查服务状态。
$ sudo systemctl status nginx
? nginx.service - nginx - high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Sat 2023-11-18 15:47:20 IST; 1s ago
Docs: https://nginx.org/en/docs/
Process: 4225 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 4226 (nginx)
Tasks: 2 (limit: 2315)
Memory: 1.8M
CPU: 7ms
CGroup: /system.slice/nginx.service
??4226 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
??4227 "nginx: worker process"
在你的 Web 浏览器中打开服务器的 IP 地址。你应该会看到如下页面,这表示你的服务器已正常运行。

第 6 步 - 安装 SSL
我们需要安装 Certbot 来生成 SSL 证书。你可以使用 Debian 的仓库安装 Certbot,或者使用 Snapd 工具获取最新版本。我们将使用 Snapd 版本。
Debian 12 默认未安装 Snapd。请安装 Snapd 软件包。
$ sudo apt install snapd
运行以下命令,确保你的 Snapd 版本是最新的。
$ sudo snap install core && sudo snap refresh core
安装 Certbot。
$ sudo snap install --classic certbot
使用以下命令,通过创建指向 /usr/bin 目录的符号链接,确保 Certbot 命令可以运行。
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
验证 Certbot 是否正常工作。
$ certbot --version
certbot 2.7.4
生成 SSL 证书。
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m
[email protected]
-d gitea.example.com
上述命令会将证书下载到服务器上的 /etc/letsencrypt/live/gitea.example.com 目录。
生成 Diffie-Hellman 组证书。
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
检查 Certbot 续期调度服务。
$ sudo systemctl list-timers
你会发现 snap.certbot.renew.service 是已计划运行的服务之一。
NEXT LEFT LAST PASSED UNIT ACTIVATES
---------------------------------------------------------------------------------------------------------------------------
Sat 2023-11-18 18:41:45 IST 2h 49min left Sat 2023-11-18 12:22:34 IST 3h 29min ago apt-daily.timer apt-daily.service
Sat 2023-11-18 20:40:00 IST 4h 47min left - - snap.certbot.renew.timer snap.certbot.renew.service
Sun 2023-11-19 00:00:00 IST 8h left - - dpkg-db-backup.timer dpkg-db-backup.service
对流程进行一次空运行,以检查 SSL 续期是否正常工作。
$ sudo certbot renew --dry-run
如果你没有看到任何错误,说明一切就绪。你的证书将自动续期。
第 7 步 - 配置 Nginx
运行以下命令,为你的站点添加配置文件。
$ sudo nano /etc/nginx/conf.d/gitea.conf
在编辑器中粘贴以下代码。
# Connection header for WebSocket reverse proxy
map $http_upgrade $connection_upgrade {
default upgrade;
"" close;
}
map $remote_addr $proxy_forwarded_elem {
# IPv4 addresses can be sent as-is
~^[0-9.]+$ "for=$remote_addr";
# IPv6 addresses need to be bracketed and quoted
~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
# Unix domain socket names cannot be represented in RFC 7239 syntax
default "for=unknown";
}
map $http_forwarded $proxy_add_forwarded {
# If the incoming Forwarded header is syntactically valid, append to it
"~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";
# Otherwise, replace it
default "$proxy_forwarded_elem";
}
# Redirect all non-encrypted to encrypted
server {
listen 80;
listen [::]:80;
server_name gitea.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name gitea.example.com;
ssl_certificate /etc/letsencrypt/live/gitea.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gitea.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/gitea.example.com/chain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] valid=60s;
resolver_timeout 2s;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
access_log /var/log/nginx/gitea.access.log main;
error_log /var/log/nginx/gitea.error.log;
tcp_nopush on;
# security headers
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always;
add_header Permissions-Policy "interest-cohort=()" always;
# . files
location ~ /\.(?!well-known) {
deny all;
}
location / {
client_max_body_size 100M;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Forwarded $proxy_add_forwarded;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
完成后,按 Ctrl + X 关闭编辑器,并在提示时按 Y 保存文件。
打开 /etc/nginx/nginx.conf 文件进行编辑。
$ sudo nano /etc/nginx/nginx.conf
在 include /etc/nginx/conf.d/*.conf; 这一行之前添加以下内容。
server_names_hash_bucket_size 64;
按 Ctrl + X 保存文件,并在提示时输入 Y。然后测试 Nginx 配置。
$ sudo nginx -t
你应该会看到类似如下的输出,表明你的配置正确。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新加载 Nginx 服务。
$ sudo systemctl reload nginx
第 8 步 - 访问并配置 Gitea
在浏览器中访问 URL https://gitea.example.com,将出现如下安装界面。

大多数字段会根据 Docker compose 文件中的值预先填充。

输入 gitea.example.com 作为服务器域名,输入 https://gitea.example.com 作为 Gitea 基础 URL。将 SSH 服务器端口的值从 22 改为 2221。其余设置保持原样。
如果你想使用邮件功能,可以添加你的 SMTP 服务器详情。展开页面的邮件设置(Email Settings)部分,并按截图所示填写数值。请确保像图中那样将 SMTP 端口与主机名一起填写。在本教程中,我们使用的是 Amazon SES 服务。你可以使用任何你喜欢的 SMTP 服务。

在安装之前,还有一些设置你需要查看。要更改它们,请展开页面的服务器和第三方服务设置(Server and Third-Party Service Settings)部分。

根据你的需求更改设置。我们启用了“默认隐藏电子邮件地址”(Hide Email Addresses by Default)选项以确保更好的隐私,并启用了“需要登录才能查看页面”(Require Sign-in to View Pages)以保持我们的 Git 站点私有。如果你不希望人们注册账户,请启用“禁用自助注册”(Disable Self-Registration)选项。
最后但同样重要的是,设置你的管理员账户。展开页面的管理员账户设置(Administrator Account Settings)部分,并填写所需的值。

完成后点击“安装 Gitea”(Install Gitea)按钮以完成安装。你将被重定向到 Gitea 仪表板。如果由于某种原因出现了 502 错误,请刷新页面。

第 8 步 - 创建第一个仓库
让我们创建第一个仓库。为此,点击仪表板上的 + 号。

填写仓库详情。从下拉菜单中选择默认问题(Issue)标签。为你的仓库选择合适的许可证。

为你的仓库选择默认分支。

确认无误后,点击“创建仓库”(Create repository)按钮,在你的 Gitea 安装上创建第一个仓库。你将被重定向到你的仓库主页。

第 9 步 - 配置 SSH
让我们配置 SSH,以便与新建的仓库一起使用。
在本教程中,我们将使用一台预装 Ubuntu 的本地电脑。不过,这些命令在任何操作系统的终端上应该都能基本不变地运行。
在本地电脑上创建一个用于 Gitea 的新 SSH 密钥。
$ ssh-keygen -f ~/.ssh/gitea-demo -t rsa -b 4096 -C "HowtoForge Gitea Demo" -q -N "yourpassphrase"
在上面的命令中,用强密码短语替换占位符。这将在 ~/.ssh/gitea-demo 位置创建一个 SSH 密钥。
接下来,打开你的 Gitea 个人资料设置:点击你的头像下拉菜单,然后选择“设置”(Settings)选项。

接下来,切换到页面上的 SSH/GPG 密钥(SSH/GPG Keys)标签页。

为你的 SSH 密钥添加一个名称。回到本地电脑的终端,运行以下命令以输出用于 Gitea 的公钥。
$ cat ~/.ssh/gitea-demo.pub
复制生成的输出,并将其粘贴回 Gitea 的 SSH 密钥页面的内容(Content)框中。
点击“添加密钥”(Add Key)按钮,完成密钥添加。

回到本地电脑,将 SSH 代理设置为保持活动状态 1 小时。
$ eval $(ssh-agent -t 3600)
将新创建的 SSH 密钥添加到 SSH 代理。
$ ssh-add ~/.ssh/gitea-demo
Enter passphrase for /home/navjot/.ssh/gitea-demo:
Identity added: /home/navjot/.ssh/gitea-demo (HowtoForge Gitea Demo)
系统将提示你输入密码短语。
第 10 步 - 使用 SSH 克隆仓库
让我们使用 SSH 克隆新建的仓库。再次访问仓库页面,选择 SSH 选项后复制 SSH URL。

它应该类似如下。
ssh://
[email protected]
:2221/navjot/howtoforge.git
在本地电脑上运行以下命令,使用 SSH 克隆仓库。
$ git clone ssh://
[email protected]
:2221/navjot/howtoforge.git
Cloning into 'howtoforge'...
The authenticity of host '[gitea.example.com]:2221 ([128.199.48.13]:2221)' can't be established.
ED25519 key fingerprint is SHA256:H7t5hNmEpZkYC9u3sXbA1mnGXCnoqaUZGL+gpAG9uNs.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[gitea.example.com]:2221' (ED25519) to the list of known hosts.
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
系统将提示你添加主机凭据。输入 yes 以继续克隆仓库。
你将在你的系统上看到已克隆的仓库。
$ ls
howtoforge
切换到该目录。
$ cd howtoforge
检查新克隆仓库的 Git 状态。为此,你的本地电脑上需要安装 Git。
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
由此可以确认 SSH 工作正常。
第 11 步 - 测试首次提交
既然我们已经设置了第一个仓库,现在该进行一些更改并将其提交了。
让我们更新 README.md 文件。在你的本地电脑上,打开 readme 文件进行编辑。
$ nano README.md
编辑文件,完成后按 Ctrl + X 并在提示时输入 Y 以保存。
再次检查 Git 状态。
$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
这表明 Readme 文件已编辑但尚未提交。将文件添加到暂存区,为提交做准备。
$ git add README.md
提交文件。
$ git commit -m "Update the Readme file for Gitea tutorial."
[main bb2956f] Update the Readme file for Gitea tutorial.
1 file changed, 3 insertions(+), 1 deletion(-)
将文件推送到你的 Gitea 服务器。
$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 378 bytes | 378.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: . Processing 1 references
remote: Processed 1 references in total
To ssh://gitea.example.com:2221/navjot/howtoforge.git
bd1248f..bb2956f main -> main
要确认,请回到 Gitea 仓库页面。

你会注意到 Readme 文件已更新,并且显示了最新的提交信息。要查看更改,请点击提交信息,即可查看包含差异的如下页面。

这完成了我们仓库的首次提交。你可以开始在你的 Gitea 安装上开展你的项目了。
第 12 步 - 备份和恢复 Gitea
Gitea 自带一个命令行工具,可以通过一条命令执行备份。要在 Docker 容器内运行命令行工具来执行备份,请运行以下命令。
$ docker exec -u git -it -w /app/gitea gitea bash -c '/usr/local/bin/gitea dump -c /data/gitea/conf/app.ini'
我们使用与第 3 步创建并在安装过程中配置相同的用户来运行该命令,即在上述命令中使用 -u git 参数。参数 -w /app/gitea 定义了 Docker 容器内存储备份文件的文件夹。备份文件夹必须选择 git 用户有写入权限的目录。在 Docker 容器内,只有两个这样的文件夹。一个是 /data 文件夹,另一个是 /app/gitea 文件夹。我们不能使用 /data 文件夹,因为命令行工具会备份整个数据文件夹,如果将其用作目标目录,会导致无限循环,从而占满你的服务器空间。因此,我们只能将备份存储在 /app/gitea 文件夹中。
命令中的下一项是容器名称 gitea。之后,我们指定用于在容器内执行命令的 Linux shell 类型。参数 -c 指定你需要在容器内运行的命令。要运行的命令是 /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini,它会运行命令行工具,并指定其配套配置文件的路径。
命令运行后,你将看到如下输出。
2023/11/20 06:21:41 ...les/setting/cache.go:75:loadCacheFrom() [I] Cache Service Enabled
2023/11/20 06:21:41 ...les/setting/cache.go:90:loadCacheFrom() [I] Last Commit Cache Service Enabled
2023/11/20 06:21:41 ...s/setting/session.go:74:loadSessionFrom() [I] Session Service Enabled
2023/11/20 06:21:41 ...es/setting/mailer.go:237:loadMailerFrom() [I] Mail Service Enabled
2023/11/20 06:21:41 ...es/setting/mailer.go:259:loadNotifyMailFrom() [I] Notify Mail Service Enabled
2023/11/20 06:21:41 ...s/storage/storage.go:176:initAttachments() [I] Initialising Attachment storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/attachments
2023/11/20 06:21:41 ...s/storage/storage.go:166:initAvatars() [I] Initialising Avatar storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/avatars
2023/11/20 06:21:41 ...s/storage/storage.go:192:initRepoAvatars() [I] Initialising Repository Avatar storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/repo-avatars
2023/11/20 06:21:41 ...s/storage/storage.go:186:initLFS() [I] Initialising LFS storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/git/lfs
2023/11/20 06:21:41 ...s/storage/storage.go:198:initRepoArchives() [I] Initialising Repository Archive storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/repo-archive
2023/11/20 06:21:41 ...s/storage/storage.go:208:initPackages() [I] Initialising Packages storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/packages
2023/11/20 06:21:41 ...s/storage/storage.go:219:initActions() [I] Initialising Actions storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/actions_log
2023/11/20 06:21:41 ...s/storage/storage.go:223:initActions() [I] Initialising ActionsArtifacts storage with type: local
2023/11/20 06:21:41 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /data/gitea/actions_artifacts
2023/11/20 06:21:41 cmd/dump.go:265:runDump() [I] Dumping local repositories... /data/git/repositories
2023/11/20 06:21:41 cmd/dump.go:306:runDump() [I] Dumping database...
2023/11/20 06:21:41 cmd/dump.go:318:runDump() [I] Adding custom configuration file from /data/gitea/conf/app.ini
2023/11/20 06:21:41 cmd/dump.go:334:runDump() [I] Custom dir /data/gitea is inside data dir /data/gitea, skipped
2023/11/20 06:21:41 cmd/dump.go:346:runDump() [I] Packing data directory.../data/gitea
2023/11/20 06:21:41 cmd/dump.go:430:runDump() [I] Finish dumping in file gitea-dump-1700441501.zip
现在,让我们了解一下恢复过程。你应该已经运行了一个全新的 Gitea Docker 安装。但不要执行安装过程。
登录到 Docker shell。
$ docker exec --user git -it gitea bash
切换到 app/gitea 目录。
$ cd app/gitea
解压备份文件。
$ unzip gitea-dump-1700441501.zip
切换到解压后的目录。
$ cd gitea-dump-1700441501
恢复 /data/gitea 文件夹。
$ mv data/* /data/gitea
恢复仓库。
$ mv repos/* /data/git/gitea-repositories/
修正文件权限。
$ chown -R git:git /data
重新生成 Git 钩子。
$ /usr/local/bin/gitea -c '/data/gitea/conf/app.ini' admin regenerate hooks
退出 Docker shell。
$ exit
第 13 步 - 升级 Gitea
升级 Gitea 是一个简单的过程。
关闭并移除现有容器。由于数据保存在主机上容器之外的位置,因此数据会被保留。
$ cd ~/gitea-docker
$ docker compose down --remove-orphans
打开 docker-compose.yml 文件,更改 Gitea 容器的版本。然后,拉取新的 Gitea 镜像。
$ docker pull
启动新的容器。
$ docker compose up -d
检查状态。
$ docker ps
结论
至此,我们完成了本教程:在 Debian 12 服务器上使用 Docker 安装 Gitea 代码托管服务。我们还安装了 Nginx 服务器作为代理,并通过 SSL 使用公开 URL 暴露 Gitea。如果你有任何问题,请在下方评论中留言。