「技术选型不是技术题」——一人公司年入50万的基础设施账单

上周有个读者私信我:「魏哥,我也想搞一人公司,但买个服务器就要好几千,再买域名、OSS、数据库……启动成本是不是很高?」我回了一句扎心的话:你最大的成本不是服务器,是选错技术栈浪费的时间。 我运营「模力AGI」这个 OPC 快半年了,从零搭建了一套完整的自动化商业体系——公众号日更、AI Agent 服务、SaaS 小工具、数据看板——都在跑。今天我把技术栈全盘托出,附上真实账单,给你算一笔年入 50 万需要什么样的基础设施。

  1. 环境依赖

在开始之前,先把环境配好。以下是我服务器上的核心依赖清单: Python 环境(requirements.txt):

fastapi==0.115.0
uvicorn[standard]==0.30.0
gunicorn==22.0.0
celery[redis]==5.4.0
sqlalchemy==2.0.35
pymysql==1.1.1
redis==5.2.0
minio==7.2.10
boto3==1.35.0
python-dotenv==1.0.1
httpx==0.27.0

系统依赖(Docker 环境):

# 安装了 Docker + Docker Compose 的轻量服务器
docker --version   # ≥ 24.0
docker compose version  # ≥ 2.20

# 一键安装脚本(适用于 Ubuntu 22.04/24.04)
curl -fsSL https://get.docker.com | bash
apt-get install -y docker-compose-plugin

验证依赖是否就绪:

# 验证 Python 包
python -c "import fastapi, celery, sqlalchemy, redis, minio; print('OK')"

# 验证 Docker 服务
docker run hello-world

# 验证端口未被占用
ss -tlnp | grep -E '8000|443|80|3306|6379|9000'

一、技术栈全景:我的「铁三角」架构 先看整体架构。一人公司最怕什么?大而全。你一个人不可能既管 K8s 集群又写业务代码又搞运维监控。所以架构必须极简、可维护、单兵可操作。

┌─────────────────────────────────────────────────┐
│                  用户流量入口                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │ 公众号/H5 │  │ 小程序   │  │  API网关  │       │
│  └─────┬────┘  └─────┬────┘  └─────┬────┘       │
└────────┼──────────────┼──────────────┼───────────┘
         │              │              │
┌────────▼──────────────▼──────────────▼───────────┐
│                业务层 (单进程)                     │
│  ┌─────────────────────────────────────────┐      │
│  │  FastAPI + Celery + SQLAlchemy          │      │
│  │  一个进程搞定API/后台任务/定时任务        │      │
│  └──────────────┬──────────────────────────┘      │
└─────────────────┼──────────────────────────────────┘
                  │
┌─────────────────▼──────────────────────────────────┐
│               数据与基础设施层                       │
│  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────────┐       │
│  │MySQL │  │Redis │  │MinIO │  │ 阿里云OSS│       │
│  └──────┘  └──────┘  └──────┘  └──────────┘       │
│  ┌──────┐  ┌───────────┐  ┌──────────────────┐     │
│  │ES   │  │GitHub/Gitee│  │  Docker Swarm    │     │
│  └──────┘  └───────────┘  └──────────────────┘     │
└─────────────────────────────────────────────────────┘

我的核心原则只有三条: 能合绝不拆——单个 VPS 能跑完的就不要微服务

能用 SaaS 别自建——Push 通知、邮件、监控能用第三方就用第三方

容器化部署——Docker 全家桶,迁移成本趋近于零

二、服务器选型:轻量应用服务器才是 OPC 的甜点 先回答标题的问题:年入 50 万需要什么样的服务器? 答案是:一台 2核4G 的轻量应用服务器,月费不到 100 元。 我目前在用阿里云「轻量应用服务器」香港节点,2核4G,40GB SSD,3M 带宽。月费折算下来约 84 元/年付。上面跑了什么? 主站 API(FastAPI + Gunicorn + Uvicorn)

Celery Worker + Beat(定时任务)

Redis(缓存 + 消息队列)

MySQL 8.0(RDS 不在这个机器上,但开发环境是在的)

MinIO(对象存储服务)

Nginx(反向代理 + SSL)

Portainer(容器管理面板)

一台机器,7 个服务,全部 Docker 化。 内存占用峰值 3.2GB,CPU 平均负载 0.8。你猜怎么着?还有余量再跑两个小服务。 为什么不用云原生全家桶? 我试过。第一周就在 EKS 上花掉了 200 块的 NAT Gateway 费用——而我的日活用户才 37 个。 OPC 的金科玉律:在用户破万之前,不要碰 K8s。 对于单节点部署,Docker Compose + Portainer 足够。如果哪天需要横向扩展,Swarm 模式的迁移成本极低——改个 compose.yml 里的 deploy 配置就能从单机变集群。 这是我的

docker-compose.yml

核心片段:

version: '3.8'
services:
api:
    build:./app
    environment:
      -DATABASE_URL=mysql+pymysql://user:pass@db:3306/opc
      -REDIS_URL=redis://redis:6379/0
    depends_on:
      -db
      -redis
    volumes:
      -./app:/app
    ports:
      -"8000:8000"
    restart:unless-stopped

celery:
    build:./app
    command:celery-Atasksworker-linfo
    depends_on:
      -redis
      -db

redis:
    image:redis:7-alpine
    restart:unless-stopped

db:
    image:mysql:8.0
    volumes:
      -mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD:${DB_PASSWORD}
    restart:unless-stopped

volumes:
mysql_data:

容器化最大的好处不是性能,而是心智负担降低——换机器只要

docker compose up -d

,一分钟全起来。 三、反向代理与 SSL:Nginx 完整配置 很多 OPC 的 API 裸奔在公网上。没有 HTTPS,没有限流,没有防爬——等于把家门大敞。 以下是我生产环境用的 Nginx 配置,包含 SSL(Let's Encrypt 自动续期)、限流、WebSocket 升级和静态资源缓存: 3.1 Nginx 主配置

# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections1024;
    useepoll;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    server_tokensoff;  # 隐藏版本号

    # 日志格式(含请求耗时,方便排查慢接口)
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time uct="$upstream_connect_time" '
                    'uht="$upstream_header_time" urt="$upstream_response_time"';

    access_log /var/log/nginx/access.log main;

    sendfileon;
    tcp_nopushon;
    keepalive_timeout65;

    # Gzip 压缩
    gzipon;
    gzip_min_length1k;
    gzip_types text/plain application/json application/javascript text/css;

    # 限流区域:每 IP 每秒最多 30 个请求(API 保护)
    limit_req_zone$binary_remote_addr zone=api_limit:10m rate=30r/s;
    # 连接数限制:每 IP 最多 20 并发
    limit_conn_zone$binary_remote_addr zone=conn_limit:10m;

    include /etc/nginx/conf.d/*.conf;
}

3.2 站点配置(含 SSL)

# /etc/nginx/conf.d/opc.conf
# HTTP → HTTPS 强制跳转
server {
    listen80;
    server_name api.yourdomain.com;
    return301 https://$host$request_uri;
}

server {
    listen443 ssl http2;
    server_name api.yourdomain.com;

    # === SSL 证书(Let's Encrypt) ===
    ssl_certificate     /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;

    # === SSL 安全加固 ===
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_cipherson;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout10m;

    # === 安全头 ===
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=63072000" always;

    # === 限流(保护后端) ===
    limit_req zone=api_limit burst=20 nodelay;
    limit_conn conn_limit 20;

    # 客户端请求体上限
    client_max_body_size10m;

    # === 静态资源(直接由 Nginx 返回,不穿透到后端) ===
    location /static/ {
        alias /opt/opc/static/;
        expires30d;
        add_header Cache-Control "public, immutable";
    }

    # === API 反向代理 ===
    location / {
        proxy_pass http://127.0.0.1:8000;
        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_connect_timeout30s;
        proxy_read_timeout60s;
        proxy_send_timeout30s;

        # 缓冲配置
        proxy_bufferingon;
        proxy_buffer_size4k;
        proxy_buffers832k;
    }

    # === WebSocket 升级(AI Agent 长连接需要) ===
    location /ws/ {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout86400s;
    }
}

3.3 SSL 证书自动续期

# 安装 certbot
apt-get install -y certbot python3-certbot-nginx

# 首次申请证书(确保域名已解析到服务器)
certbot --nginx -d api.yourdomain.com -d www.yourdomain.com

# 添加 cron 自动续期(每月 1 号凌晨 3 点)
echo "0 3 1 * * certbot renew --quiet --post-hook 'nginx -s reload'" | crontab -

# 验证自动续期(干跑测试)
certbot renew --dry-run

3.4 验证 Nginx + SSL 是否正常

# 1. 检查配置语法
nginx -t

# 2. 重载配置
nginx -s reload

# 3. 测试 HTTPS 访问
curl -I https://api.yourdomain.com

# 4. 检查 SSL 证书有效期
echo | openssl s_client -servername api.yourdomain.com -connect api.yourdomain.com:443 2>/dev/null \
  | openssl x509 -noout -dates

# 5. SSL Labs 在线检测(获取评分 A+)
# 浏览器打开:https://www.ssllabs.com/ssltest/analyze.html?d=api.yourdomain.com

四、数据库与存储:分层的本质是省钱 4.1 关系型数据库 主力:阿里云 RDS MySQL 2核4G 50GB SSD。月费 98 元(按量付费,没有流量费)。 为什么不用自建 MySQL? 备份脚本要自己写

磁盘满了自己扩容

挂了要自己恢复

OPC 的时间 = 收入,花在运维上不如写代码

RDS 自动备份、一键回滚、慢查询日志。每半年花 15 分钟看一眼就够了。 4.2 缓存层 Redis 7-alpine,直接跑在轻量服务器上,Docker 镜像只有 32MB。生产环境里我给了 512MB 内存限制,实际上用了不到 100MB。 使用场景: Session 存储

Celery 结果后端

API 响应缓存(TTL 60s,缓存命中率约 65%)

简单计数器(日活、API 调用量)

4.3 文件存储 对象存储三件套:OSS(主)+ MinIO(本地缓存)+ CDN。 阿里云 OSS(标准型):50GB 容量 + 10GB 月流量 = 约 15 元/月。存什么? 用户上传的图片、PDF

生成的文章封面图

AI Agent 产出的中间文件

MinIO 在本地做热缓存——高频访问的文件从 OSS 拉到本地,减少外网流量费。简单的 LRU 淘汰策略:

import os
from pathlib import Path
from functools import lru_cache
from minio import Minio  # ← 修复:导入 MinIO 客户端


classFileCache:
    def__init__(
        self,
        local_dir: str = "/data/cache",
        max_size_mb: int = 1024,
        # 修复:初始化 MinIO 客户端(原代码缺失,导致 self.client 未定义)
        oss_endpoint: str = "oss-cn-hongkong.aliyuncs.com",
        oss_access_key: str = "",
        oss_secret_key: str = "",
        oss_bucket: str = "opc-files",
    ):
        self.local_dir = Path(local_dir)
        self.local_dir.mkdir(parents=True, exist_ok=True)
        self.max_size = max_size_mb * 1024 * 1024

        # ★ Bug 修复:原代码缺少 MinIO 客户端初始化
        self.client = Minio(
            oss_endpoint,
            access_key=oss_access_key,
            secret_key=oss_secret_key,
            secure=True,
        )
        self.oss_bucket = oss_bucket

    @lru_cache(maxsize=128)
    defget(self, key: str) -> bytes:
        local_path = self.local_dir / key
        if local_path.exists():
            return local_path.read_bytes()
        # 从 OSS 拉取(self.client 现已正确定义)
        data = self.client.get_object(self.oss_bucket, key).read()
        local_path.write_bytes(data)
        self._evict_if_needed()
        return data

    def_evict_if_needed(self):
        total = sum(
            f.stat().st_size for f inself.local_dir.rglob("*") if f.is_file()
        )
        if total > self.max_size:
            files = sorted(self.local_dir.rglob("*"), key=os.path.getatime)
            for f in files[:10]:
                f.unlink()

Bug 说明:原代码

self.client.get_object(...)

直接调用但从未初始化

self.client

,会在运行时抛出

AttributeError: 'FileCache' object has no attribute 'client'

。现已修复。 一个月 OSS 的 CDN 回源流量费大概 3-5 元。远超预期地便宜。 五、CI/CD 与部署:用 GitHub Actions 替代 Jenkins 一个人不需要 Jenkins。GitHub Actions 免费额度对 OPC 来说根本用不完。 我的部署流水线:

# .github/workflows/deploy.yml
name:Deploy
on:
push:
    branches: [main]
jobs:
test-and-deploy:
    runs-on:ubuntu-latest
    steps:
      -uses:actions/checkout@v4
      -name:Runtests
        run:|
          docker compose -f docker-compose.test.yml up --abort-on-container-exit
      -name:Buildandpush
        env:
          DOCKER_BUILDKIT:1
        run:|
          docker build -t opc-app:${{ github.sha }} .
          docker save opc-app:${{ github.sha }} | gzip > app.tar.gz
      -name:DeploytoVPS
        uses:appleboy/scp-action@v0.1.7
        with:
          host:${{secrets.VPS_HOST}}
          username:${{secrets.VPS_USER}}
          key:${{secrets.VPS_KEY}}
          source:"app.tar.gz"
          target:"/opt/opc/deploy/"
      -name:Restartservices
        uses:appleboy/ssh-action@v1.0.3
        with:
          host:${{secrets.VPS_HOST}}
          username:${{secrets.VPS_USER}}
          key:${{secrets.VPS_KEY}}
          script:|
            cd /opt/opc
            docker compose pull
            docker compose up -d --force-recreate api
            docker image prune -f

整体流程:

git push

→ GitHub Actions 自动跑测试 → 构建镜像 → SCP 传到服务器 →

docker compose

热更新 从 push 到上线完成,平均 47 秒。 不需要任何人盯着。 六、监控怎么办? 我用了三件套,全部免费:

工具用途免费额度
Sentry错误追踪每月 5000 events,个人项目根本用不完
UptimeRobot可用性监控免费监控 5 个 URL,每 5 分钟探测,挂了发邮件+短信
Healthchecks.io定时任务监控Celery Beat 跑完后 ping 一次,超时未 ping 就告警

三个加起来月费为 0 元。 七、年度账单:我的基础设施花销全披露 很多人觉得做技术产品一定要烧钱。我直接晒账单(年付价格,人民币):

项目配置年费月均
轻量应用服务器2核4G 40GB SSD1,00884
RDS MySQL2核4G 50GB SSD1,17698
阿里云 OSS50GB + CDN 流量18015
域名1个 .com + 1个 .cn13611
企业邮箱阿里企业邮免费版00
SSL 证书Let's Encrypt(自动续)00
GitHub Pro个人版00
Sentry免费版00
监控工具UptimeRobot + Healthchecks00
总计2,500208

一年 2,500 元。 这是我在「模力AGI」这个 OPC 上的全部基础设施成本。 对于刚起步的 OPC,还能更省: 所有服务挤一台轻量服务器(1,008 元/年就够了)

MySQL 用 SQLite 代替(0 元)

OSS 用 MinIO 自己搭(但要小心磁盘满)

极限压缩:年费 1,008 元,月均 84 元。 八、为什么我选择了「看似落后」的方案? 你可能注意到了,我没用任何 Serverless(Lambda/FaaS),没用 NoSQL(MongoDB 挺好的但我不需要),没用消息队列(除了 Redis 自带的 pub/sub)。 理由很简单:一人公司的技术栈要服务于「快速交付」而不是「架构审美」。 如果我的用户量从 1,000 涨到 10,000,这套架构能撑住吗? API 加一层 Nginx 缓存即可

数据库加只读从库

服务器升配到 4核8G

要花多长时间?一个周末。而在这之前,我已经用 2,500 元/年的成本跑了一整年,赚回了 10 倍以上的收入。 OPC 的技术选型不是一道技术题,是一道财务题。 你的每一分钟服务器时间都在帮你赚钱,还是只是满足你的「技术洁癖」? 什么时候该升级? 我给你一个简单的判断标准: 当服务器成本 > 你月收入的 1% 时,不要动基础设施。

当你花在运维上的时间超过写代码的时间时,立刻升级。

我用这个标准检验了三个月——运维时间平均每周不到 30 分钟(主要是看一眼监控面板和部署),服务器成本只有月收入的 0.2%。所以到现在都没动。 九、行动清单 如果你也想搞一个 OPC,今天就能做的事情: 买一台轻量服务器(阿里云/腾讯云/华为云,哪个便宜买哪个),2核2G起步,年付 600-800 元

注册一个 .com 域名(约 55 元/年)

装好 Docker + Docker Compose(5 分钟搞定)

用 GitHub 管理代码,配置 GitHub Actions 自动部署

部署你的第一个 API——哪怕只是个 Hello World,完成从 push 到上线的闭环

把我的 Docker Compose 模板拿走:[1]https://github.com/weiwuji/opc-starter[2] 十、验证清单(部署完成后逐条检查) 花 5 分钟跑完下面的验证,确保整条链路是通的:

# === 1. 基础服务健康检查 ===
docker compose ps                          # 所有容器 STATUS=Up
docker compose logs --tail=20 api          # API 无异常日志
curl http://localhost:8000/health          # 返回 {"status":"ok"}

# === 2. 数据库连通性 ===
docker compose exec db mysqladmin ping -h 127.0.0.1 -u root -p${DB_PASSWORD}
# 预期输出: mysqld is alive

# === 3. Redis 连通性 ===
docker compose exec redis redis-cli ping
# 预期输出: PONG

# === 4. Celery Worker 是否正常 ===
docker compose exec celery celery -A tasks inspect ping
# 预期输出: {'celery@xxx': {'ok': 'pong'}}

# === 5. Nginx + HTTPS ===
nginx -t && nginx -s reload
curl -o /dev/null -s -w "%{http_code}" https://yourdomain.com
# 预期输出: 200

# === 6. SSL 证书有效期 ===
echo | openssl s_client -servername yourdomain.com \
  -connect yourdomain.com:443 2>/dev/null \
  | openssl x509 -noout -dates
# 检查 notAfter 日期是否在有效期内

# === 7. GitHub Actions 部署流水线 ===
# 在 GitHub 仓库 → Actions → 手动触发一次 workflow
# 确认:test → build → deploy → restart 四步全部绿色

# === 8. 文件缓存(FileCache) ===
python -c "
from minio import Minio
fc = FileCache(oss_access_key='test', oss_secret_key='test')
print('FileCache initialized OK:', fc.local_dir)
"
# 预期输出: FileCache initialized OK: /data/cache

全部通过后,你的 OPC 基础设施就已经是生产就绪状态了。 下篇文章我会手把手带你搭建「AI 自动化流水线」——从微信公众号内容生成、到 AI Agent 自动回复、到数据自动汇总到 Notion 仪表盘,全链路自动化。一个人,跑出十个人的效率。 套用一句我在内部笔记里写的:「当别人还在纠结服务器够不够用时,无记已经用千元级别跑通了流程闭环。不是因为技术多好,而是因为知道什么该省,什么不该省。」 下篇见。 关于作者:魏无记,AI 和数智化实践者。专注 Agent 工程化与 Loop Engineering 研究以及数智化转型。公众号持续更新 Agent 工程化实战系列和数智化转型相关知识实践——每篇都是保姆级教程照做就行。 引用链接 [1]undefined: https://github.com/weiwuji/opc-starter [2]https://github.com/weiwuji/opc-starter

posted @ 2026-08-05 11:42  魏无记  阅读(1)  评论(0)    收藏  举报