关于 Nginx 配置
在本部署方案中,Nginx 配置文件位于 ./nginx/conf.d/default.conf
,通过 Docker 卷挂载映射到容器内的 /etc/nginx/conf.d/default.conf
。这与 Ubuntu 系统默认的 Nginx 配置位置 (/etc/nginx/sites-available/default
) 无关,因为我们使用的是 Docker 容器内部的 Nginx,不是宿主机上的 Nginx。
项目结构
├── docker-compose.yml # Docker Compose配置文件
├── nginx/ # Nginx配置目录
│ ├── conf.d/ # Nginx配置文件
│ │ └── default.conf # 主配置文件
│ ├── html/ # 静态HTML文件
│ │ └── index.html # 欢迎页面
│ ├── logs/ # 日志目录
│ └── ssl/ # SSL证书目录(未来使用)
├── gitea-data/ # Gitea数据目录(自动创建)
└── postgres-data/ # PostgreSQL数据目录(自动创建)
部署步骤
1. 准备环境
在 Ubuntu 22.04 服务器上安装 Docker 和 Docker Compose:
# 更新软件包
sudo apt update
sudo apt upgrade -y
# 安装必要的依赖
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# 方法一:使用阿里云镜像安装Docker(推荐中国大陆服务器使用)
# 添加阿里云Docker GPG密钥
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 添加阿里云Docker仓库
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 更新软件包索引
sudo apt update
# 安装Docker
sudo apt install -y docker-ce docker-ce-cli containerd.io
# 方法二:直接使用apt安装Docker(简单方法)
# 如果上述方法不成功,可以尝试这种简单的方法
# sudo apt install -y docker.io docker-compose
# 启动Docker并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
# 安装Docker Compose(本地下载后上传到服务器)
# 方法1:在本地计算机下载Docker Compose二进制文件,然后上传到服务器(推荐)
## 步骤A:在本地计算机上下载正确版本的Docker Compose
# 重要:无论您的本地系统是什么,都必须下载Linux版本的Docker Compose,因为服务器是Linux系统
# 在浏览器中访问:https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64
# 或使用对应系统的命令行下载:
# 在macOS终端下载Linux版本:
# curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64" -o docker-compose-linux
# 在Windows PowerShell下载Linux版本:
# Invoke-WebRequest -Uri "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64" -OutFile "docker-compose-linux"
# 在Linux终端下载:
# wget https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -O docker-compose-linux
## 步骤B:将下载的文件上传到服务器并重命名
# 使用SCP将文件从本地上传到服务器并重命名为docker-compose
# 示例(本地终端执行):
# 如果您从macOS上传:
# scp docker-compose-linux root@{你的云服务IP或域名}:/usr/local/bin/docker-compose
# 如果您从Windows上传(使用PowerShell):
# scp docker-compose-linux root@{你的云服务IP或域名}:/usr/local/bin/docker-compose
# 注意:必须重命名为"docker-compose"(无平台后缀),否则系统无法正确识别
## 步骤C:在服务器上设置权限
# 登录到服务器后执行:
sudo chmod +x /usr/local/bin/docker-compose
# 方法2:在服务器上安装基础版本(如果上述方法不可行)
# sudo apt install -y docker-compose
# 这个版本较旧(1.29.2),但能满足基本需求
# 方法3:使用Docker插件方式(如果您能在本地下载插件文件)
# 在本地下载docker-compose插件文件后上传到服务器:
# 创建插件目录
sudo mkdir -p /usr/local/lib/docker/cli-plugins
# 上传后移动到插件目录
# sudo mv /path/to/uploaded/docker-compose /usr/local/lib/docker/cli-plugins/docker-compose
# sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
# 验证安装
docker --version
docker-compose --version
# 将当前用户添加到docker组(避免每次都需要sudo)
sudo usermod -aG docker $USER
# 需要重新登录使上述更改生效
# 配置Docker国内镜像加速(可选但推荐)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://mirror.baidubce.com",
"https://hub-mirror.c.163.com"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2. 创建项目目录结构
# 创建项目目录
mkdir -p ~/gitea-deploy
cd ~/gitea-deploy
# 创建所需子目录
mkdir -p nginx/conf.d nginx/html nginx/logs nginx/ssl
3. 将配置文件复制到服务器
有两种方式将配置文件传输到服务器,本地创建、写入内容后再上传,或者直接在远程服务器上编辑。
实际都需要这3个文件的内容:docker-compose.yml、default.conf、index.html 其内容可在文件内容参考本文档末尾的部分查看。
注意它们分别所对应的目录,相信你能够正确处理。
方式一:从本地复制到服务器
使用 scp 命令在本地计算机上执行:
# 在本地执行以下命令将文件上传到服务器
scp -r docker-compose.yml nginx/conf.d/default.conf nginx/html/index.html root@{你的云服务IP或域名}:~/gitea-deploy/
方式二:直接在服务器上创建文件
也可以在服务器上使用文本编辑器(如 nano 或 vim)直接创建这些文件:
# 示例:使用 nano 创建 docker-compose.yml
nano ~/gitea-deploy/docker-compose.yml
# 粘贴内容后,按 Ctrl+O 保存,Ctrl+X 退出
# 示例:使用 nano 创建 nginx 配置文件
nano ~/gitea-deploy/nginx/conf.d/default.conf
# 粘贴内容后,按 Ctrl+O 保存,Ctrl+X 退出
# 示例:使用 nano 创建 HTML 文件
nano ~/gitea-deploy/nginx/html/index.html
# 粘贴内容后,按 Ctrl+O 保存,Ctrl+X 退出
4. 启动服务
# 进入项目目录
cd ~/gitea-deploy
# 启动服务(后台运行)
docker-compose up -d
# 查看容器状态
docker-compose ps
# 查看日志(如有问题)
docker-compose logs
5. 初始配置 Gitea
首次访问 http://{你的云服务IP或域名}/ 会进入 Gitea 的初始化界面,按照以下建议配置:
-
数据库设置:
- 数据库类型: PostgreSQL
- 主机: db:5432
- 用户名: gitea
- 密码: for_gitea_password
- 数据库名: gitea
-
应用基本设置:
- 站点名称: {你的网站名称}
- 网站根URL: http://{你的云服务IP或域名}/
-
管理员账号设置:
- 创建管理员账号,设置安全的用户名和密码
-
服务器和其他设置:
- 根据需要自定义其他设置
6. 维护和管理
查看日志
# 查看Nginx日志
docker-compose exec nginx cat /var/log/nginx/gitea_access.log
docker-compose exec nginx cat /var/log/nginx/gitea_error.log
# 查看Gitea日志
docker-compose logs gitea
备份数据
# 备份Gitea数据和PostgreSQL数据
tar -czvf gitea-backup-$(date +%Y%m%d).tar.gz gitea-data postgres-data
重启服务
docker-compose restart
7. 升级到 HTTPS(域名备案后)
当您获得域名并完成备案后,可以按照以下详细步骤升级到 HTTPS:
7.1 准备工作
- 确保您有一个已完成备案的域名,并已配置正确的DNS记录指向服务器IP。
-
创建证书验证目录:
# 在宿主机上创建用于证书验证的目录 mkdir -p ~/gitea-deploy/nginx/html/.well-known/acme-challenge
-
修改Nginx配置,支持证书验证(在80端口server块内添加):
# 编辑Nginx配置文件 nano ~/gitea-deploy/nginx/conf.d/default.conf # 在80端口server块内添加以下location块 location /.well-known/acme-challenge/ { root /usr/share/nginx/html; }
-
应用Nginx配置更改:
docker-compose restart nginx
7.2 获取SSL证书
使用Let's Encrypt获取免费的SSL证书:
# 安装certbot
sudo apt install certbot python3-certbot-nginx
# 获取证书
# 重要:将yourdomain.com替换为您的实际域名
# /root/gitea-deploy/nginx/html是宿主机上对应容器内/usr/share/nginx/html的路径
sudo certbot certonly --webroot -w /root/gitea-deploy/nginx/html -d yourdomain.com
注意:-w
参数必须指向宿主机上映射到Nginx容器内的HTML目录。这里是/root/gitea-deploy/nginx/html
,您可能需要根据实际路径调整。
7.3 配置证书文件
# 创建SSL证书目录(如果不存在)
mkdir -p ~/gitea-deploy/nginx/ssl
# 复制证书文件
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem ~/gitea-deploy/nginx/ssl/cert.pem
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem ~/gitea-deploy/nginx/ssl/key.pem
# 设置权限
sudo chown -R $USER:$USER ~/gitea-deploy/nginx/ssl/
7.4 更新Nginx配置
nano ~/gitea-deploy/nginx/conf.d/default.conf
取消注释HTTPS部分,并修改为您的域名:
# 取消注释并修改以下部分
server {
listen 80;
server_name yourdomain.com;
# HTTP重定向到HTTPS
location / {
return 301 https://$host$request_uri;
}
# 保留此部分用于证书续期
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
}
server {
listen 443 ssl;
server_name yourdomain.com;
# SSL证书配置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# 安全头部
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
# 根据您的实际配置,可能需要修改以下路径
# 如果您的Gitea路径是/yourgiteahome/
location /yourgiteahome/ {
proxy_pass http://gitea: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;
# WebSocket支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 静态网站根目录
location / {
root /usr/share/nginx/html;
index index.html;
}
}
7.5 更新docker-compose.yml中的Gitea配置
nano ~/gitea-deploy/docker-compose.yml
更新Gitea的环境变量:
- GITEA__server__DOMAIN=yourdomain.com
- GITEA__server__ROOT_URL=https://yourdomain.com/yourgiteahome/
- GITEA__server__PROTOCOL=https
注意:如果您的Gitea安装在其他路径(如/git/或根路径/),请相应地调整ROOT_URL。
7.6 应用更改
# 重启服务
cd ~/gitea-deploy
docker-compose down
docker-compose up -d
# 验证服务状态
docker-compose ps
7.7 配置证书自动更新
Let's Encrypt证书有效期为90天,需要定期更新。设置自动更新:
# 测试证书续期(不实际执行)
sudo certbot renew --dry-run
# 添加定期任务
sudo crontab -e
添加以下行:
# 每月1日凌晨更新证书并重启Nginx
0 0 1 * * certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /root/gitea-deploy/nginx/ssl/cert.pem && cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /root/gitea-deploy/nginx/ssl/key.pem && docker restart nginx-proxy
7.8 验证HTTPS配置
访问您的域名,确认:
- HTTPS工作正常(浏览器显示安全锁图标)
- HTTP请求重定向到HTTPS
- Gitea在正确的路径下可访问
- 备案信息页面正确显示
通过静态页面查看备案信息
我们配置了一个特殊路径 /welcome
,可以通过 http://{你的云服务IP或域名}:3000/welcome 访问静态 HTML 页面,这个页面底部显示备案信息:京ICP-1234567890。
其他说明
- Gitea 使用 PostgreSQL 17(最新版本)数据库
- 所有数据持久化存储在宿主机上的对应目录中
- Nginx 配置了大文件上传支持(512MB)
- 系统配置了自动重启功能,服务器重启后 Docker 容器会自动启动
文件内容参考
如果需要手动创建文件,可以参考以下内容:
docker-compose.yml
version: '3'
services:
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
- "3000:3000"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/html:/usr/share/nginx/html
- ./nginx/logs:/var/log/nginx
- ./nginx/ssl:/etc/nginx/ssl
restart: always
networks:
- app-network
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=for_gitea_password
- GITEA__server__DOMAIN={你的云服务IP或域名}
- GITEA__server__ROOT_URL=http://{你的云服务IP或域名}/
restart: always
volumes:
- ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
depends_on:
- db
networks:
- app-network
db:
image: postgres:latest
container_name: gitea-db
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=for_gitea_password
- POSTGRES_DB=gitea
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- app-network
networks:
app-network:
driver: bridge
nginx/conf.d/default.conf
# Gitea服务配置
server {
listen 3000;
server_name localhost {你的云服务IP或域名};
access_log /var/log/nginx/gitea_access.log;
error_log /var/log/nginx/gitea_error.log;
client_max_body_size 512M;
# 代理到Gitea
location / {
proxy_pass http://gitea: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;
# WebSocket支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 静态页面可通过特定路径访问
location /welcome {
alias /usr/share/nginx/html;
index index.html;
}
}
# 80端口主入口
server {
listen 80;
server_name {你的云服务IP或域名};
# 重定向到Gitea
location / {
proxy_pass http://gitea: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;
# WebSocket支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# 将来启用HTTPS时使用的配置(已注释)
# server {
# listen 80;
# server_name your-domain.com;
# # HTTP重定向到HTTPS
# location / {
# return 301 https://$host$request_uri;
# }
# }
#
# server {
# listen 443 ssl;
# server_name your-domain.com;
#
# # SSL证书配置
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/key.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 1d;
#
# # HSTS (启用HTTPS严格传输安全)
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
#
# # 其他安全头部
# add_header X-Content-Type-Options nosniff;
# add_header X-Frame-Options DENY;
# add_header X-XSS-Protection "1; mode=block";
#
# # 将请求代理到Gitea服务
# location / {
# proxy_pass http://gitea: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;
#
# # WebSocket支持
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# }
# }
nginx/html/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>你给网站取个名字</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
color: #333;
}
header {
background-color: #f8f9fa;
padding: 2rem;
text-align: center;
border-bottom: 1px solid #e9ecef;
}
h1 {
color: #333;
margin: 0;
}
main {
flex: 1;
padding: 2rem;
text-align: center;
max-width: 800px;
margin: 0 auto;
}
.services {
margin-top: 2rem;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
.service-card {
border: 1px solid #e9ecef;
border-radius: 5px;
padding: 1.5rem;
background-color: #f8f9fa;
transition: transform 0.3s ease;
}
.service-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
footer {
background-color: #f8f9fa;
padding: 1rem;
text-align: center;
color: #6c757d;
border-top: 1px solid #e9ecef;
}
</style>
</head>
<body>
<header>
<h1>你给网站取个名字</h1>
</header>
<main>
<p>欢迎访问之类按你需要去写。</p>
<div class="services">
<div class="service-card">
<h3>小模块</h3>
<p>描述文字之类。</p>
</div>
<div class="service-card">
<h3>小模块</h3>
<p>描述文字之类。</p>
</div>
</div>
</main>
<footer>
<p>京ICP-1234567890</p>
</footer>
</body>
</html>