Forgejo 代码仓库部署

考虑点

  • Forgejo可以关闭一些组件,获得gogs的收益
  • PG数据库可以先做低耗优化运行,获得完整数据库管理
  • 后续需要增加,再打开两者的一些组件和开关
  • 最终:在已有的docker net+nginx环境下,增加forgejo和pd两个容器即可

PostgreSQL

  • docker-compose.yml

    pg:
      image: postgres:15-alpine           # 使用 alpine 版本镜像,体积最小,运行内存占用更低
      container_name: pg          		  # 固定容器名,方便 Nginx 和 Forgejo 通过名称访问
      restart: always                     # 确保数据库挂掉或服务器重启后能自动恢复
      # --- 核心内存压制命令 ---
      command: >                          # 以下参数覆盖 PG 默认配置,防止其在小内存机器上过度预分配
        -c max_connections=15             # 限制最大连接数,每个连接都会消耗内存,15 个足够个人及小团队使用
        -c shared_buffers=32MB            # 核心缓冲区,设为 32MB(默认通常是 128MB+),降低启动内存占用
        -c work_mem=2MB                   # 单个查询使用的内存,设小一点防止复杂查询撑爆内存
        -c maintenance_work_mem=8MB       # 维护任务(如索引重建)使用的内存
        -c min_wal_size=32MB              # 预写日志最小大小,减少磁盘占用
        -c max_wal_size=128MB             # 预写日志最大大小,防止日志无限增长撑爆 200G 磁盘
        -c effective_cache_size=128MB     # 告诉优化器可用缓存大小,建议设为总内存的 1/8
      environment:
        - POSTGRES_USER=forgejo           # 数据库用户名
        - POSTGRES_PASSWORD=your_password # 数据库密码(请务必修改)
        - POSTGRES_DB=forgejo             # 初始化数据库名
      volumes:
        - /www/postgresql/data:/var/lib/postgresql/data    # 将数据持久化到宿主机目录,方便冷备
      networks:
        - ghost_net                       # 加入 Nginx 所在的内部网络
      deploy:
        resources:
          limits:
            memory: 200M                  # Docker 层级的强行限制,防止 PG 异常时抢占宿主机内存
  • niginx.conf

    stream {                               # 注意:stream 块位于 nginx.conf 顶层,不在 http 块内
        upstream postgres_backend {        # 定义后端数据库地址
            server pg:5432;                # 直接使用 Docker 网络内部的容器名和端口
        }
    
        server {
            listen 5432;                   # Nginx 监听宿主机的 5432 端口用于数据库转发
            proxy_pass postgres_backend;   # 将流量透明转发给 PG 容器
            proxy_timeout 10m;             # 闲置连接保持 10 分钟,防止频繁断开
            proxy_connect_timeout 10s;     # 数据库连接超时时间
        }
    }

Forgejo

  • docker-compose.yml

    forgejo:
      image: codeberg.org/forgejo/forgejo:latest # 使用最新稳定版镜像
      container_name: forgejo
      restart: unless-stopped                             # 除非手动停止,否则始终保持运行
      depends_on:
        - pg                                              # 确保数据库容器启动后再启动 Forgejo
      environment:
        # --- 数据库关联 ---
        - FORGEJO__database__DB_TYPE=postgres
        - FORGEJO__database__HOST=pg:5432  # 连接 db 容器的 5432 端口
        - FORGEJO__database__NAME=forgejo
        - FORGEJO__database__USER=forgejo
        - FORGEJO__database__PASSWD=your_password
        # --- 极致精简开关 (减少内存占用) ---
        - FORGEJO__actions__ENABLED=false                  # 关闭 Actions 自动化,这是最省内存的操作(省去 Runner 轮询)
        - FORGEJO__packages__ENABLED=false                 # 关闭包管理(不存放 Docker/PyPI 镜像)
        - FORGEJO__repository__ENABLE_PROJECTS=false       # 关闭项目看板功能
        - FORGEJO__indexer__REPO_INDEXER_ENABLED=false     # 强制关闭代码全文索引,防止大量耗费 CPU 和内存
        - FORGEJO__queue__DATATYPE=leveldb                 # 将内部队列从内存移至磁盘(./data/queues),保护物理内存
        # --- 访问配置 ---
        - FORGEJO__server__DOMAIN=git.atibm.com            # 网页显示的域名
        - FORGEJO__server__ROOT_URL=https://git.atibm.com/ # 外部访问的完整 HTTPS 链接
        - FORGEJO__server__SSH_PORT=2222                   # 告知 Web 界面显示的 SSH 克隆端口为 2222
      volumes:
        - /www/forgejo/data:/data                          # 存放仓库、配置和附件的核心目录
      ports:
        - "2222:22"                                        # 宿主机 2222 映射容器 22 端口,用于 Git SSH 推送
      networks:
        - ghost_net                                        # 加入 Nginx 所在的内部网络
      deploy:
        resources:
          limits:
            memory: 400M                                   # 给 Forgejo 预留 400M 上限,确保 1G 内存不溢出
  • nginx.conf

    server {
        listen 443 ssl http2;                          # 启用 HTTPS 和 HTTP/2,显著提升小文件(代码)加载速度
        server_name git.atibm.com;                     # 绑定的域名
    
        # --- SSL 证书安全 ---
        ssl_certificate /etc/letsencrypt/live/atibm.com/fullchain.pem; # Certbot 生成的公钥
        ssl_certificate_key /etc/letsencrypt/live/atibm.com/privkey.pem; # Certbot 生成的私钥
    
        # --- 性能与超时优化 ---
        client_max_body_size 64M;                       # 限制 Git HTTP 方式推送的最大文件大小(个人代码够用)
        proxy_read_timeout 120s;                        # 增加读取超时,防止在 1C1G 机器处理大型 Diff 时响应超时
    
        location / {
            proxy_pass http://forgejo:3000;             # 流量转发给容器内的 3000 端口
            proxy_set_header Host $host;                # 传递原始域名给后端,确保 Forgejo 链接生成正确
            proxy_set_header X-Real-IP $remote_addr;    # 传递用户真实 IP,方便查看 Git 日志
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme; # 告诉后端当前使用的是 https 协议
            
            # --- 缓冲区调优:防止慢连接占用后端进程 ---
            proxy_buffering on;                         # 开启缓冲区,将响应先存入内存再发给客户端
            proxy_buffer_size 128k;                     # 处理大 Header(如长 Cookie)的缓冲区
            proxy_buffers 4 256k;                       # 内存缓冲区总大小,防止后端 Forgejo 被慢网络拖累
        }
    }

服务器调优

  • 内存监控

    [ghost@trilium20251227 ruby]$ systemctl status docker
    ● docker.service - Docker Application Container Engine
       Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
       Active: active (running) since Sat 2025-12-27 15:26:00 CST; 1 weeks 1 days ago
         Docs: https://docs.docker.com
     Main PID: 1634 (dockerd)
        Tasks: 40
       Memory: 65.8M
       CGroup: /system.slice/docker.service
    ...
    [ghost@trilium20251227 trilium]$ docker stats --no-stream
    CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O        PIDS
    834584383b6e   trilium   0.00%     104.6MiB / 400MiB   26.15%    1.27MB / 2.27MB   169MB / 6.99MB   11
    a5090bbc5aae   ghost     0.03%     140.4MiB / 256MiB   54.84%    146kB / 3.67MB    286MB / 29.5MB   11
    1619e84b6ff1   nginx     0.00%     8.625MiB / 64MiB    13.48%    7.97MB / 8.77MB   8.82MB / 86kB    2
    6f97f828412e   certbot   0.00%     568KiB / 985.5MiB   0.06%     9.69MB / 56.7kB   172MB / 2.66MB   1
    [ghost@trilium20251227 ruby]$ free -h
                  total        used        free      shared  buff/cache   available
    Mem:           985M        483M         20M         23M        481M        450M
    Swap:          8.0G         45M        8.0G
    
    [ghost@trilium20251227 ruby]$ ps aux --sort=-%mem | head -n 10
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    opc      28539  0.3 17.2 21836264 173604 ?     Ssl  20:21   0:42 node current/index.js
    root      3841  0.9 13.3 410320 134232 ?       Ssl  18:54   2:43 node /app/src/www
    root      1634  0.0  3.7 1943804 37712 ?       Ssl   2025   9:09 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
    root      1351  0.0  1.4 574288 14748 ?        Ssl   2025   1:06 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
    oracle-+  6609  0.0  1.4 1838512 14296 ?       Sl    2025   6:42 /usr/libexec/oracle-cloud-agent/plugins/gomon/gomon
    root      1356  0.0  1.3 1553612 14044 ?       Ssl   2025   1:35 /usr/bin/containerd
    oracle-+  6620  0.0  1.2 1704596 12804 ?       Sl    2025   1:15 /usr/libexec/oracle-cloud-agent/plugins/oci-wlp/oci-wlp
    ocarun    6630  0.0  1.2 1702112 12348 ?       Sl    2025   2:45 /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
    oracle-+  6566  0.0  1.1 1633596 11704 ?       Ssl   2025   0:23 /usr/libexec/oracle-cloud-agent/agent
  • 分析内容占用
    • 第一部分:核心应用 (约 300MB)X
      • Ghost (Node.js): 约 170MB (RSS)。它是内存大户。
      • Trilium (Node.js): 约 134MB (RSS)。
      • 这两个 Node.js 应用占据了已用内存的 63%。
    • 第二部分:容器引擎与代理 (约 80MB)
      • dockerd: 65.8MB (来自 systemctl status)。
      • docker-proxy: 4个进程,合计约几MB。
        • 80和443端口*ipv4和ipv6共4个proxy,可以关掉ipv6的proxy
        • 设置:sudo vi /etc/docker/daemon.json,写入{"ipv6": false}
        • 设置:nginx的docker-compose.yml里ports显示指定ipv4端口
        • 生效:sudo systemctl daemon-reload;sudo systemctl restart docker
        • 验证:ps aux | grep docker-proxy
      • containerd: 约 14MB。
    • 第三部分:系统管理与云监控 (约 50MB)
      • Oracle Cloud Agent: (gomon, oci-wlp, runcommand 等) 合计约 50MB。这是甲骨文云用于监控和后台管理的插件。
        • 如果不需要oracle管理页面的监控信息,可以节省50MB
        • sudo systemctl stop oracle-cloud-agent
        • sudo systemctl disable oracle-cloud-agent
      • tuned: 约 15MB。CentOS 7 默认的性能调优服务。
        • 小 VPS 上性价比不高,可以关闭,节省15MB
        • sudo systemctl stop tuned 
        • sudo systemctl disable tuned