用 AtomCode 从零开发并部署上线一个 Flask 待办应用的完整实战本文是一篇全程真机实操的记录。所有命令、输出、HTTP 状态码、Git 提交与仓库地址均来自服务器117.72.182.3Ubuntu 22.04 / Python 3.10.12上的真实执行非示意。目标只给 AtomCode 一句需求让它从零写出一个可运行的 Flask 任务管理应用然后在服务器上部署上线并推送到全新的 Gitee 仓库。编程执行引擎AtomCode 4.26.0模型deepseek-v4-flash最终成果仓库https://gitee.com/LiaCin/atomcode-flask-todo目录一、这篇文章要证明什么二、整体流程一图看懂三、环境准备四、第 1 步写清楚需求Prompt 即规格五、第 2 步一条命令让 AtomCode 从零开发六、第 3 步AtomCode 交付了什么七、第 4 步跑测试18 个用例八、第 5 步部署上线 curl 验收九、第 6 步推送到全新 Gitee 仓库十、安全收尾十一、关键命令速查表十二、踩坑与经验十三、附录AtomCode 生成的核心代码一、这篇文章要证明什么一句话从一句需求到线上可访问的服务 云端代码仓库全程由 AtomCode 自动完成编码人只负责下需求、验收、上线。拆成 6 个可验证的步骤步骤做什么由谁完成验收凭证1写需求prompt.txt人见 §四2从零生成全部代码AtomCode见 §五、§六3自测AtomCode 自跑 人复跑18 tests OK§七4部署运行人curl200/201§八5新建远程仓库人Gitee APIHTTP 201§九6推送代码人git pushnew branch main§九二、整体流程一图看懂① 写需求 prompt.txtRESTSQLite前端测试② atomcode -y --prompt-fileheadless 自动开发③ AtomCode 生成 8 个文件app.py / static/* / test_app.py / README ...④ python3 test_app.py18 tests OK⑤ nohup python3 app.py监听 0.0.0.0:5000⑥ curl 验收health 200 / create 201 / list 200⑦ Gitee API 新建仓库HTTP 201⑧ git init/commit/pushmain - origin✅ 线上服务 云端仓库gitee.com/LiaCin/atomcode-flask-todo核心分工AtomCode 负责 ②③写代码 自测人负责 ①④⑤⑥⑦⑧下需求、验收、部署、建仓、推送。三、环境准备服务器实测环境OS : Ubuntu 22.04内核容器/云主机 Python : Python 3.10.12 pip : pip 22.0.2 Flask : 3.1.3已装 AtomCode: 4.26.0 (/usr/local/bin/atomcodeRust 二进制) 模型 : deepseek-v4-flashbase_url https://llm-api.atomgit.com/v1 工作目录 : /root/projects/flask-todoAtomCode 是 Rust 单二进制不依赖 Node 运行时官方一键安装curl -fsSL https://raw.atomgit.com/.../install.sh | sh四、第 1 步写清楚需求Prompt 即规格AtomCode 的产出质量几乎完全取决于需求写得有多具体。这里把需求当规格说明书写进prompt.txt明确到接口、字段、端口、文件清单You are an expert software engineer. Build a complete, runnable Flask task-management web application in /root/projects/flask-todo. 1. Backend (app.py): - Flask only, SQLite (tasks.db)tasks 表id/title/description/done/created_at - REST API: GET /api/health - {status:ok} GET /api/tasks - 全部任务最新在前 POST /api/tasks - 创建JSON title/description返回 201 GET /api/tasks/id - 单条或 404 PUT /api/tasks/id - 更新返回更新后对象 DELETE /api/tasks/id - 删除返回 204 - static/ 目录托管前端默认监听 127.0.0.1:5000env PORT 可覆盖后续为对外访问已改为 0.0.0.0见 §8.1 - 启动时自建表if __name__ __main__ 守卫 2. Frontend (static/index.html app.js style.css)原生 fetch无框架 3. requirements.txt: 仅 flask 4. README.md运行说明 接口表 5. test_app.py用 Flask test client 建任务并断言其出现可 python3 直接跑 Keep everything local; do NOT expose the server publicly.经验接口用方法 路径 期望状态码三元组写死AtomCode 就不会自由发挥出你不想要的路由。五、第 2 步一条命令让 AtomCode 从零开发用 headless非交互模式让 AtomCode 读需求文件、自动写代码、自动自测cd/root/projects/flask-todo atomcode-y\-C/root/projects/flask-todo\--max-turns30\--prompt-file /root/projects/flask-todo/prompt.txt\--disable-tools none\build.log21参数拆解参数作用-y/--dangerously-skip-permissions自动批准所有工具调用无人值守必需-C dir指定工作目录代码就地生成--max-turns 30最多 30 个自主回合防止跑飞--prompt-file从文件读需求比-p更适合长规格--disable-tools none允许全部工具读写文件、跑 bash、跑测试build.log里 AtomCode 的自述真实节选[engine v2] new stack active (model deepseek-v4-flash) [headless] --dangerously-skip-permissions: all tool calls are auto-approved ... All 18 tests pass. Let me clean up the temp database file ... and finalize. All tasks complete. Heres a summary of the project:也就是说AtomCode自己写完代码后自己跑了 18 个测试并全部通过才宣布收工。六、第 3 步AtomCode 交付了什么find实测生成的文件清单/root/projects/flask-todo/app.py # Flask 后端REST SQLite 静态托管 /root/projects/flask-todo/static/index.html # 单页前端 /root/projects/flask-todo/static/app.js # 原生 fetch CRUD /root/projects/flask-todo/static/style.css # 响应式样式 /root/projects/flask-todo/test_app.py # 18 个 API 测试 /root/projects/flask-todo/requirements.txt # 仅 flask /root/projects/flask-todo/README.md # 运行说明 接口表 /root/projects/flask-todo/build.log # AtomCode 自述日志AtomCode 生成的接口一览与需求完全对齐MethodPath动作状态码GET/api/health健康检查200GET/api/tasks列出全部最新在前200POST/api/tasks创建任务201GET/api/tasks/id查单条200 / 404PUT/api/tasks/id更新200DELETE/api/tasks/id删除204七、第 4 步跑测试18 个用例人工复跑一遍 AtomCode 写的测试验证不是自说自话cd/root/projects/flask-todopython3 test_app.py真实输出尾部test_get_task ... ok test_get_task_not_found ... ok test_health ... ok test_list_tasks_empty ... ok test_list_tasks_order ... ok test_update_task_done ... ok test_update_task_invalid_done ... ok test_update_task_not_found ... ok test_update_task_title ... ok ---------------------------------------------------------------------- Ran 18 tests in 0.133s OK覆盖健康检查、完整 CRUD、参数校验缺 title / done 非法值、404 分支、列表排序、静态文件托管。18/18 通过。八、第 5 步部署上线 curl 验收后台启动服务干净库重定向日志cd/root/projects/flask-todorm-ftasks.dbnohuppython3 app.py/tmp/flask.out21启动日志真实绑定 0.0.0.0 后* Serving Flask app app * Debug mode: on * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://172.16.0.3:5000 * Debugger is active!端口确认在听已绑定到全部网卡0.0.0.0$ ss-ltnp|grep5000LISTEN01280.0.0.0:5000... users:((python3,pid27836,...))验收 1健康检查$curl-s-w\n[HTTP %{http_code}]\nhttp://127.0.0.1:5000/api/health{status:ok}[HTTP200]验收 2创建任务中文入参$curl-s-XPOST http://127.0.0.1:5000/api/tasks\-HContent-Type: application/json\-d{title:部署验收任务,description:AtomCode 从零开发并上线}{created_at:2026-07-10T09:38:46.06385000:00,description:AtomCode 从零开发并上线,done:0,id:1,title:部署验收任务}[HTTP201]验收 3列表回读$curl-shttp://127.0.0.1:5000/api/tasks[{id:1,title:部署验收任务,done:0,...}][HTTP200]验收 4前端首页$curl-s-o/dev/null-windex.html [HTTP %{http_code}] %{size_download} bytes\nhttp://127.0.0.1:5000/ index.html[HTTP200]891bytes至此服务已在服务器上真实运行并对外提供 REST 前端页面。8.1 改为对外监听0.0.0.0公网可访问默认app.py写的是host127.0.0.1只能本机127.0.0.1访问。若要让服务对外部网络开放只需把启动地址改成0.0.0.0# app.py 第 174-176 行host0.0.0.0# 原为 127.0.0.1portint(os.environ.get(PORT,5000))app.run(hosthost,portport,debugTrue)改完重启并复验真实输出$ ss-ltnp|grep5000LISTEN01280.0.0.0:5000... users:((python3,pid27836,...))$curl-s-o/dev/null-w%{http_code}\nhttp://127.0.0.1:5000/api/health200$curl-s-o/dev/null-w%{http_code}\nhttp://0.0.0.0:5000/api/health200外部可达性还需两步本次已确认服务器内部0.0.0.0绑定成功但公网探测返回000检查项状态说明服务绑定0.0.0.0:5000✅ 已生效ss明确看到0.0.0.0:5000云安全组 / 防火墙放通 5000⚠️ 需手动本机curl 117.72.182.3:5000仍000需在云控制台入站规则放行 TCP 5000本机公网 IP117.72.182.3外部访问地址即http://117.72.182.3:5000改完记得把代码推回仓库git commit -m chore: bind 0.0.0.0:5000 for external access git push实际已推commita84c9b4。⚠️安全红线debugTrue的开发服务器一旦绑定0.0.0.0暴露到公网Werkzeug 调试器存在**远程代码执行RCE**风险知道 PIN 或绕过 PIN 即可执行任意命令。公网开放务必关 debug见下方生产建议。生产建议app.run(debugTrue)仅用于本次验收正式上线应换gunicorn -w 4 -b 127.0.0.1:5000 app:app Nginx 反代Nginx 监听0.0.0.0:80/443对外Flask 仍只绑内网并关闭 debug。若确实要 Flask 直连公网至少debugFalse且加反向代理与访问控制。九、第 6 步推送到全新 Gitee 仓库9.1 用 Gitee API 新建仓库curl-s-XPOSThttps://gitee.com/api/v5/user/repos\-HContent-Type: application/json\-d{access_token:TOKEN,name:atomcode-flask-todo, description:由 AtomCode 从零自动开发的 Flask 任务管理应用, private:false,has_issues:true}返回真实节选{full_name:LiaCin/atomcode-flask-todo,html_url:https://gitee.com/LiaCin/atomcode-flask-todo.git,private:true}[HTTP201]⚠️ 注意即使传private:falseGitee 新建仓库默认仍为私有需要公开可到仓库设置里手动改。9.2 加 .gitignore别把库/日志/凭据提交上去__pycache__/ *.pyc tasks.db build.log prompt.txt *.out .venv/9.3 配置 Git 身份并提交该服务器原本没有全局 Git 身份/root/.gitconfig不存在首次提交前必须配置gitconfig--globaluser.nameLiaCingitconfig--globaluser.emailliacingitee.comgitconfig--globalinit.defaultBranch maincd/root/projects/flask-todogitinitgitadd-Agitcommit-mfeat: AtomCode 从零生成的 Flask 待办应用REST API SQLite 原生JS前端 18测试提交结果真实2deaf20 feat: AtomCode 从零生成的 Flask 待办应用... ---tracked files--- .gitignore README.md app.py requirements.txt static/app.js static/index.html static/style.css test_app.py9.4 推送# 用 token 临时鉴权https://用户名:TOKENgitee.com/owner/repo.gitgitremoteaddoriginhttps://LiaCin:TOKENgitee.com/LiaCin/atomcode-flask-todo.gitgitbranch-Mmaingitpush-uorigin main推送结果真实To https://gitee.com/LiaCin/atomcode-flask-todo.git * [new branch] main - main Branch main set up to track remote branch main from origin.API 二次核验default_branch已变为main$curl-shttps://gitee.com/api/v5/repos/LiaCin/atomcode-flask-todo?access_tokenTOKEN...default_branch:main...[HTTP200]代码已上云https://gitee.com/LiaCin/atomcode-flask-todo十、安全收尾真机操作后必须做的收尾本次已全部执行清除 remote 里的明文 token——push 完把带 token 的 URL 换掉gitremote set-url origin https://gitee.com/LiaCin/atomcode-flask-todo.git核验git remote -v已不含 token。停掉验收用的 debug 服务pkill -f python3 app.py。删除本地含明文凭据的临时脚本root 密码 / Gitee token 均不落盘。敏感文件进 .gitignoretasks.db、build.log、prompt.txt、*.out不入库。十一、关键命令速查表阶段命令让 AtomCode 开发atomcode -y -C dir --max-turns 30 --prompt-file prompt.txt --disable-tools none复跑测试python3 test_app.py后台起服务nohup python3 app.py /tmp/flask.out 21 查端口ss -ltnp | grep 5000健康检查curl -s http://0.0.0.0:5000/api/health或127.0.0.1开放公网改app.run(host0.0.0.0) 云安全组放行 5000建 Gitee 仓库curl -X POST gitee.com/api/v5/user/repos -d {access_token:..,name:..}Git 身份git config --global user.name/user.email首推git init git add -A git commit -m .. git push -u origin main清 tokengit remote set-url origin https://gitee.com/owner/repo.git十二、踩坑与经验坑现象解决Gitee token 校验用错方式用Bearer头 → 401Gitee 用?access_token查询参数或Authorization: tokenowner 用了显示名Lincoln/xxx→ 404用pathLiaCin显示名 name ≠ 仓库 owner path新仓库默认私有传private:false仍是私有到仓库设置手动改公开服务器无 Git 身份commit 报 author unknown先git config --global user.name/emailtoken 写进 remote明文残留在.git/configpush 后立即git remote set-url去掉 tokenheadless 权限交互确认卡住无人值守用-y并配--max-turns兜底需求太笼统生成的路由/字段跑偏prompt 里把方法路径状态码字段写死最大的一条经验把prompt.txt当成给资深工程师的验收标准来写——你写得越像规格说明书AtomCode 一次成型的概率越高。这次 18 个测试全过、6 个接口零返工靠的就是需求写得够死。十三、附录AtomCode 生成的核心代码app.pyAtomCode 自动生成未经人工改动节选主体#!/usr/bin/env python3Flask task-management API with SQLite backend.importos,sqlite3fromdatetimeimportdatetime,timezonefromflaskimportFlask,g,jsonify,request,send_from_directory appFlask(__name__,static_folderstatic)DATABASEos.path.join(os.path.dirname(os.path.abspath(__file__)),tasks.db)defget_db():ifdbnoting:g.dbsqlite3.connect(DATABASE)g.db.row_factorysqlite3.Rowreturng.dbdefinit_db():withapp.app_context():dbget_db()db.execute( CREATE TABLE IF NOT EXISTS tasks ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, description TEXT, done INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL))db.commit()app.route(/api/health)defapi_health():returnjsonify({status:ok})app.route(/api/tasks,methods[POST])defapi_create_task():datarequest.get_json(silentTrue)ifnotdataornotdata.get(title,).strip():returnjsonify({error:title is required}),400titledata[title].strip()descriptiondata.get(description,).strip()orNonenowdatetime.now(timezone.utc).isoformat()dbget_db()curdb.execute(INSERT INTO tasks (title, description, done, created_at) VALUES (?,?,0,?),(title,description,now))db.commit()taskdb.execute(SELECT * FROM tasks WHERE id?,(cur.lastrowid,)).fetchone()returnjsonify(dict(task)),201# ... GET/PUT/DELETE /api/tasks/id、静态托管路由略结构同上...if__name____main__:init_db()portint(os.environ.get(PORT,5000))app.run(host0.0.0.0,portport,debugTrue)# 已改为对外监听生产环境应 debugFalse亮点全部由 AtomCode 自主决定用gteardown_appcontext管理 SQLite 连接请求级复用、自动关闭PUT 更新做了类型与取值校验done只允许 0/1title 必须字符串created_at用带时区的 ISO8601列表按created_at DESC排序入口init_db()幂等建表端口支持PORT环境变量覆盖。一句话总结需求写进一个文件 →atomcode -y --prompt-file一条命令 → 8 个文件 18 个通过的测试自动生成 →curl验收 200/201 → Gitee 建仓 git push上云。人只做了下需求、验收、上线写代码这件事AtomCode 全包了。成果仓库https://gitee.com/LiaCin/atomcode-flask-todo