跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

教程

从零开始学习 Piglet Run 的分步指南。

教程文档提供从零开始学习 Piglet Run 的分步指南。

学习路径

按顺序学习以下教程:

  1. 安装 - 在服务器上部署 Piglet Run
  2. 快速开始 - 创建你的第一个项目
  3. VS Code - 使用网页版 VS Code
  4. Jupyter - 使用 Jupyter 进行数据分析
  5. Claude Code - AI 辅助开发
  6. 数据库 - 使用 PostgreSQL

主题

主题 描述
安装 在全新服务器上安装 Piglet Run
快速开始 Piglet Run 的前 5 分钟
VS Code 网页版 VS Code 教程
Jupyter 数据科学的 JupyterLab
Claude Code 使用 Claude 进行 AI 编码
数据库 PostgreSQL 基础
应用 构建和部署应用

/Users/vonng/pgsty/piglet.run/static/img/logo/piglet.png

1 - 完整安装

Piglet 安装的完整流程

准备工作

你需要什么

项目 最低要求 推荐配置
云服务器 1 核 2GB 2 核 4GB+
操作系统 Ubuntu 22.04 / Debian 12 / Rocky 8 Ubuntu 24.04
磁盘 40GB 100GB+
网络 能上网 有公网 IP

还没有服务器? 参考 采购云服务器 指南,各大云厂商最低 0.64 元/小时起。

获取服务器访问权限

你需要能 SSH 登录到服务器:

ssh root@your-server-ip

一键安装(推荐)

最快的方式,适合大多数用户:

# 中国用户(推荐)
curl -fsSL https://repo.pigsty.io/pig | bash && pig sty install -m piglet

# 海外用户
curl -fsSL https://repo.pigsty.io/pig | bash && pig sty install -m piglet

就这一行命令。等它跑完,你的 Agentic Postgres 运行时就准备好了。


分步安装

如果你想了解每一步在做什么,或者需要自定义配置:

第一步:安装 Pig CLI

# 中国镜像
curl -fsSL https://repo.pigsty.io/pig | bash

# 海外 CDN
curl -fsSL https://repo.pigsty.io/pig | bash

Pig 是 Piglet 的命令行工具,安装完成后会自动添加到 PATH。

第二步:配置软件源

pig repo set                          # 自动检测系统,配置所有必要的软件源

如果你在中国大陆,使用镜像源会更快:

pig repo add all --region china       # 使用中国镜像

第三步:初始化并安装

pig sty init                          # 下载 Pigsty 到 ~/pigsty
pig sty boot                          # 安装 Ansible(自动化工具)
pig sty conf -m piglet                # 生成 Piglet 专用配置
pig sty deploy                        # 运行安装(这一步可能需要几分钟)

验证安装

安装完成后,检查一切是否正常:

pig status                            # 整体状态
pig pg status                         # PostgreSQL 状态

访问你的服务

打开浏览器,访问服务器 IP:

服务 地址 说明
首页 http://<ip>/ Piglet 欢迎页
VS Code http://<ip>/code 网页版 IDE
Jupyter http://<ip>/jupyter 数据科学笔记本
Grafana http://<ip>/grafana 监控仪表盘
PostgreSQL <ip>:5432 数据库连接

默认凭据

服务 用户名 密码
PostgreSQL postgres piglet
Grafana admin piglet
VS Code - piglet

安全提示:首次登录后请立即修改密码!


配置 Claude Code(可选)

如果你要用 Claude Code 进行 AI 辅助编程:

# 在你的本地机器上
claude config set apiKey YOUR_ANTHROPIC_API_KEY

# 连接到 Piglet 服务器
claude connect ssh root@your-server-ip

详见 Claude Code 配置


故障排除

查看日志

pig pg log tail                       # PostgreSQL 日志
journalctl -u nginx -f                # Nginx 日志
journalctl -u code-server -f          # VS Code 日志

常见问题

症状 可能原因 解决方案
软件源报错 源配置过期 pig repo set -u 刷新
包冲突 已有其他源 pig repo rm && pig repo set
权限拒绝 非 root 用户 使用 sudo 或切换到 root
端口无法访问 防火墙限制 开放 80, 443, 5432 端口
内存不足 服务器配置低 升级到 4GB+ 内存

重新安装

如果需要从头开始:

pig sty destroy                       # 清理现有安装
pig sty deploy                        # 重新部署

下一步

安装完成了!接下来:

  1. 快速开始教程 - 做你的第一个静态网页
  2. 配置 Claude Code - 开启 AI 结对编程
  3. 架构概述 - 了解 Piglet 里有什么

2 - 快速开始

安装 Piglet,用 Claude Code 做一个静态网页

目标

这个教程会带你完成:

  1. 登录你的 Piglet 环境
  2. 用 Claude Code 生成一个数据可视化网页
  3. 把它部署上线

完成后,你会有一个可以公开访问的网页,展示一个交互式 ECharts 图表。


第一步:登录环境

方式 A:网页版 VS Code(推荐新手)

打开浏览器,访问:

http://你的服务器IP/code

输入密码 piglet(首次使用请修改)。

方式 B:本地 VS Code + SSH(推荐日常使用)

在本地 VS Code 中:

  1. 安装 Remote - SSH 扩展
  2. Cmd+Shift+P / Ctrl+Shift+P,选择 Remote-SSH: Connect to Host
  3. 输入 root@你的服务器IP

方式 C:Claude Code 直连(AI 编程)

# 在本地终端
claude connect ssh root@你的服务器IP

第二步:创建项目目录

打开终端,创建工作目录:

cd ~/data
mkdir my-first-site
cd my-first-site

第三步:让 Claude 帮你写代码

这是 Piglet 的魔法时刻。

如果你用 Claude Code:

直接告诉它你想要什么:

给我做一个网页,展示一个 ECharts 柱状图,数据是过去 7 天的访问量(随便编一些数据)。
要求:
- 单个 HTML 文件,内联所有 CSS 和 JS
- 使用 ECharts CDN
- 页面要好看,有标题

Claude 会直接在当前目录创建 index.html

如果你手动写:

创建 index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个 Piglet 网页</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 40px 20px;
        }
        h1 {
            color: white;
            margin-bottom: 30px;
            font-size: 2rem;
            text-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }
        .chart-container {
            background: white;
            border-radius: 16px;
            padding: 30px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            width: 100%;
            max-width: 800px;
        }
        #chart { width: 100%; height: 400px; }
        .footer {
            color: rgba(255,255,255,0.8);
            margin-top: 30px;
            font-size: 0.9rem;
        }
    </style>
</head>
<body>
    <h1>过去 7 天访问量</h1>
    <div class="chart-container">
        <div id="chart"></div>
    </div>
    <p class="footer">由 Piglet 驱动 | Code Fearlessly, Ship Instantly.</p>

    <script>
        const chart = echarts.init(document.getElementById('chart'));
        const option = {
            tooltip: { trigger: 'axis' },
            xAxis: {
                type: 'category',
                data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
            },
            yAxis: { type: 'value', name: '访问量' },
            series: [{
                data: [820, 932, 901, 1290, 1330, 1520, 1680],
                type: 'bar',
                itemStyle: {
                    borderRadius: [8, 8, 0, 0],
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: '#667eea' },
                        { offset: 1, color: '#764ba2' }
                    ])
                }
            }]
        };
        chart.setOption(option);
        window.addEventListener('resize', () => chart.resize());
    </script>
</body>
</html>

第四步:预览

在终端中启动一个简单的 HTTP 服务器:

python3 -m http.server 8080

然后访问 http://你的服务器IP:8080,你应该能看到一个漂亮的柱状图页面。

Ctrl+C 停止服务器。


第五步:部署上线

让这个网页可以通过正式的 URL 访问:

# 复制到 Nginx 静态文件目录
sudo cp index.html /www/my-first-site/

或者使用 pig deploy 命令:

pig deploy . --name my-first-site

现在访问 http://你的服务器IP/my-first-site/ 就能看到你的网页了。


恭喜!

你刚刚完成了:

  • ✅ 登录 Piglet 开发环境
  • ✅ 用 Claude Code(或手动)创建了一个数据可视化网页
  • ✅ 把它部署到了互联网上

从想法到上线,就是这么简单。


发生了什么

让我们回顾一下 Piglet 为你做了什么:

传统方式 Piglet 方式
买服务器 → 装系统 → 配环境 → 装 Node/Python → 配 Nginx → 配 SSL… 一条命令安装,开箱即用
本地写代码 → Git push → CI/CD → 部署 直接在服务器上写,一行命令部署
自己写 HTML/CSS/JS 告诉 Claude “给我做一个网页”

这就是 Code Fearlessly, Ship Instantly 的含义。


下一步

现在你已经熟悉了基本流程,可以继续:

  1. 第一个 Web 应用 - 做一个带数据库的 Flask/Node.js 应用
  2. 配置 Claude Code - 深度使用 AI 辅助编程
  3. 灾难恢复 - 体验 PITR 时间旅行,搞砸了也不怕

3 - VS Code

网页版 VS Code

学习在 Piglet Run 中使用网页版 VS Code 服务器。

访问

打开浏览器访问:

http://<ip>/code

功能

网页版 VS Code 包含:

  • 完整的浏览器中 VS Code 体验
  • 扩展支持
  • 集成终端
  • Git 集成
  • Python、Go、Node.js 支持

开始使用

1. 打开文件夹

点击"打开文件夹",选择 /root/workspace

2. 安装扩展

推荐扩展:

  • Python
  • Pylance
  • GitLens
  • Database Client

3. 配置设置

Ctrl+, 打开设置。

技巧

  • 使用 Ctrl+Shift+P 打开命令面板
  • `Ctrl+`` 打开集成终端
  • Ctrl+B 切换侧边栏

下一步

4 - Jupyter

JupyterLab 教程

学习在 Piglet Run 中使用 JupyterLab 进行数据分析。

访问

访问:

http://<ip>/jupyter

功能

  • 交互式 Python 笔记本
  • 丰富输出(图表、表格、图像)
  • PostgreSQL 集成
  • 多内核(Python、SQL)

开始使用

1. 创建笔记本

点击 Notebook 下的"Python 3"。

2. 连接 PostgreSQL

import psycopg
import pandas as pd

conn = psycopg.connect("postgres://postgres@localhost/postgres")
df = pd.read_sql("SELECT * FROM pg_stat_activity", conn)
df.head()

3. 数据可视化

import matplotlib.pyplot as plt

df['state'].value_counts().plot(kind='bar')
plt.show()

技巧

  • 使用 Shift+Enter 运行单元格
  • 将笔记本保存到 /root/workspace/notebooks

下一步

5 - Claude Code 配置

配置 Claude Code 进行 AI 辅助编程

什么是 Claude Code

Claude Code 是 Anthropic 官方的 AI 编程助手。它能:

  • 理解你的代码库
  • 根据自然语言指令编写代码
  • 执行命令、创建文件、修改代码
  • 直接操作你的 Piglet 环境

在 Piglet 中,Claude Code 开箱能用——环境已经预配置好了 CLAUDE.md,告诉 AI 这里有什么工具可以用。


获取 API Key

第一步:注册 Anthropic 账号

访问 console.anthropic.com 注册账号。

第二步:创建 API Key

  1. 登录后进入 API Keys 页面
  2. 点击 Create Key
  3. 复制生成的密钥(以 sk-ant- 开头)

注意:API Key 只显示一次,请妥善保存。

第三步:充值

Claude Code 按 token 计费。建议先充值 $5-10 试用。


配置方式

方式 A:本地 Claude Code 连接远程服务器(推荐)

这是最流畅的体验——在本地终端运行 Claude Code,但它操作的是远程 Piglet 服务器。

1. 在本地安装 Claude Code

# macOS / Linux
npm install -g @anthropic-ai/claude-code

# 或使用 Homebrew
brew install claude-code

2. 配置 API Key

claude config set apiKey sk-ant-your-api-key-here

3. 连接到 Piglet 服务器

claude connect ssh root@你的服务器IP

现在你可以直接对话:

> 帮我看看这个服务器上有什么
> 在 ~/data 下创建一个 Flask 项目
> 写一个爬虫,抓取 Hacker News 首页标题,存到 PostgreSQL

方式 B:在服务器上直接运行

如果你通过网页版 VS Code 或 SSH 登录到服务器:

1. 配置环境变量

# 临时生效
export ANTHROPIC_API_KEY="sk-ant-your-api-key-here"

# 永久生效(写入 .bashrc)
echo 'export ANTHROPIC_API_KEY="sk-ant-your-api-key-here"' >> ~/.bashrc
source ~/.bashrc

2. 启动 Claude Code

claude

方式 C:VS Code 扩展(可选)

如果你用本地 VS Code + Remote SSH:

  1. 安装 Claude 扩展
  2. 在设置中配置 API Key
  3. Cmd+Shift+P 输入 Claude 使用

CLAUDE.md:告诉 AI 环境里有什么

Piglet 在 ~/CLAUDE.md 预置了一份环境说明文件。Claude Code 会自动读取它,了解:

  • 这是一个 Piglet 环境
  • PostgreSQL 数据库连接方式
  • 可用的命令行工具(pigpsql 等)
  • 文件系统结构
  • 部署方式

你可以编辑这个文件,添加项目特定的说明:

vim ~/CLAUDE.md

例如:

## 项目说明

这是一个电商网站项目,使用:
- 后端:FastAPI
- 数据库:PostgreSQL(已配置)
- 前端:React(在 /www/shop-frontend)

## 数据库结构

- users 表:用户信息
- products 表:商品信息
- orders 表:订单信息

## 部署命令

pig deploy ./dist --name shop

使用示例

创建项目

> 在 ~/data/blog 创建一个 Flask 博客应用,带文章的增删改查,使用 PostgreSQL 存储

调试问题

> 看看 PostgreSQL 的日志,最近有什么错误吗
> 这个 Python 脚本报错了,帮我修一下

部署应用

> 把 ~/data/blog 部署到 /www/blog,配置 Nginx 反向代理

数据库操作

> 帮我创建一个 users 表,包含 id、name、email、created_at 字段
> 给我写一个 SQL 查询,统计过去 7 天每天的注册用户数

监控诊断

> 给我生成一份服务器巡检报告
> 看看磁盘空间和内存使用情况

搞砸了也不怕

这是 Piglet 的核心价值之一:Code Fearlessly

如果 Claude 搞砸了什么:

# 查看最近的文件系统快照
pig snapshot list

# 回滚到某个时间点
pig snapshot restore --time "2024-01-15 14:30:00"

数据库也一样:

# 数据库时间旅行
pig pg pitr --time "2024-01-15 14:30:00"

所以放心大胆地让 Claude 去尝试。


最佳实践

做法 说明
说清楚你要什么 “做一个网页"不如"做一个展示天气的网页,用 ECharts 画温度曲线”
给上下文 告诉它项目背景、技术栈、约束条件
分步迭代 先做核心功能,再逐步完善
审查代码 Claude 会先展示计划,确认后再执行
用 CLAUDE.md 把项目说明写进去,Claude 会自动参考

费用参考

Claude Code 使用 Claude Sonnet 模型,按 token 计费:

操作 大约消耗 参考费用
简单对话 ~1K tokens < $0.01
生成一个文件 ~5K tokens ~$0.02
复杂项目讨论 ~20K tokens ~$0.10

日常使用,$5-10 可以用很久。


故障排除

问题 解决方案
API key invalid 检查 key 是否正确,是否有余额
连接超时 检查网络,国内可能需要代理
权限不足 确保用 root 或有 sudo 权限的用户
Claude 不了解环境 检查 ~/CLAUDE.md 是否存在

下一步

6 - 数据库

PostgreSQL 基础

学习在 Piglet Run 中使用 PostgreSQL。

连接

使用 psql

psql postgres://postgres@localhost/postgres

使用 Python

import psycopg

conn = psycopg.connect("postgres://postgres@localhost/postgres")

创建数据库

CREATE DATABASE myapp;

安装扩展

PostgreSQL 18 有 400+ 扩展可用:

-- 向量搜索
CREATE EXTENSION vector;

-- 时序数据
CREATE EXTENSION timescaledb;

-- 全文搜索(中文)
CREATE EXTENSION zhparser;

基本操作

-- 创建表
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 插入数据
INSERT INTO users (name, email) VALUES ('Alice', '[email protected]');

-- 查询
SELECT * FROM users;

监控

在以下位置查看数据库性能:

http://<ip>/ui/d/pgsql-overview

下一步

7 - 第一个 Web 应用

做一个带登录功能的 Flask 应用,连接 PostgreSQL

目标

这个教程会带你创建一个完整的 Web 应用:

  • Flask 后端框架
  • PostgreSQL 数据库存储用户
  • 用户注册、登录、注销功能
  • Session 管理
  • 部署上线

完成后,你会有一个真正可用的 Web 应用,不只是 Hello World。


前置条件


第一步:创建项目

cd ~/data
mkdir my-flask-app
cd my-flask-app

创建 Python 虚拟环境并安装依赖:

python3 -m venv venv
source venv/bin/activate
pip install flask psycopg[binary] python-dotenv

第二步:创建数据库表

连接 PostgreSQL:

psql postgres://postgres:piglet@localhost/postgres

创建用户表:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 退出 psql
\q

第三步:编写应用代码

创建 app.py

import os
import hashlib
from flask import Flask, render_template, request, redirect, url_for, session, flash
import psycopg

app = Flask(__name__)
app.secret_key = os.urandom(24)

# 数据库连接
DB_URL = "postgres://postgres:piglet@localhost/postgres"

def get_db():
    return psycopg.connect(DB_URL)

def hash_password(password):
    return hashlib.sha256(password.encode()).hexdigest()

# 首页
@app.route('/')
def index():
    user = session.get('user')
    return render_template('index.html', user=user)

# 注册
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        with get_db() as conn:
            with conn.cursor() as cur:
                # 检查用户名是否已存在
                cur.execute("SELECT id FROM users WHERE username = %s", (username,))
                if cur.fetchone():
                    flash('用户名已存在', 'error')
                    return redirect(url_for('register'))

                # 创建用户
                cur.execute(
                    "INSERT INTO users (username, password_hash) VALUES (%s, %s)",
                    (username, hash_password(password))
                )
                conn.commit()

        flash('注册成功,请登录', 'success')
        return redirect(url_for('login'))

    return render_template('register.html')

# 登录
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        with get_db() as conn:
            with conn.cursor() as cur:
                cur.execute(
                    "SELECT id, username FROM users WHERE username = %s AND password_hash = %s",
                    (username, hash_password(password))
                )
                user = cur.fetchone()

        if user:
            session['user'] = {'id': user[0], 'username': user[1]}
            flash(f'欢迎回来,{user[1]}!', 'success')
            return redirect(url_for('index'))
        else:
            flash('用户名或密码错误', 'error')

    return render_template('login.html')

# 注销
@app.route('/logout')
def logout():
    session.pop('user', None)
    flash('已退出登录', 'success')
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

第四步:创建模板

创建模板目录:

mkdir templates

创建 templates/base.html(基础模板):

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}我的应用{% endblock %}</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #f5f5f5;
            min-height: 100vh;
        }
        .navbar {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            padding: 1rem 2rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .navbar a { color: white; text-decoration: none; margin-left: 1rem; }
        .navbar a:hover { text-decoration: underline; }
        .logo { color: white; font-size: 1.5rem; font-weight: bold; }
        .container { max-width: 600px; margin: 2rem auto; padding: 0 1rem; }
        .card {
            background: white;
            border-radius: 8px;
            padding: 2rem;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .flash { padding: 1rem; border-radius: 4px; margin-bottom: 1rem; }
        .flash.success { background: #d4edda; color: #155724; }
        .flash.error { background: #f8d7da; color: #721c24; }
        input {
            width: 100%;
            padding: 0.75rem;
            margin: 0.5rem 0 1rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 1rem;
        }
        button {
            width: 100%;
            padding: 0.75rem;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 1rem;
            cursor: pointer;
        }
        button:hover { opacity: 0.9; }
        h1, h2 { margin-bottom: 1rem; }
        p { color: #666; line-height: 1.6; }
        a { color: #667eea; }
    </style>
</head>
<body>
    <nav class="navbar">
        <span class="logo">MyApp</span>
        <div>
            <a href="{{ url_for('index') }}">首页</a>
            {% if session.user %}
                <a href="{{ url_for('logout') }}">退出 ({{ session.user.username }})</a>
            {% else %}
                <a href="{{ url_for('login') }}">登录</a>
                <a href="{{ url_for('register') }}">注册</a>
            {% endif %}
        </div>
    </nav>
    <div class="container">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% for category, message in messages %}
                <div class="flash {{ category }}">{{ message }}</div>
            {% endfor %}
        {% endwith %}
        {% block content %}{% endblock %}
    </div>
</body>
</html>

创建 templates/index.html

{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<div class="card">
    {% if user %}
        <h1>欢迎,{{ user.username }}!</h1>
        <p>你已成功登录。这是一个由 Piglet 驱动的 Flask 应用。</p>
        <p style="margin-top: 1rem;">
            <a href="{{ url_for('logout') }}">退出登录</a>
        </p>
    {% else %}
        <h1>欢迎来到 MyApp</h1>
        <p>这是一个由 Piglet 驱动的 Flask 应用,使用 PostgreSQL 存储用户数据。</p>
        <p style="margin-top: 1rem;">
            <a href="{{ url_for('login') }}">登录</a>            <a href="{{ url_for('register') }}">注册</a> 开始使用
        </p>
    {% endif %}
</div>
{% endblock %}

创建 templates/login.html

{% extends "base.html" %}
{% block title %}登录{% endblock %}
{% block content %}
<div class="card">
    <h2>登录</h2>
    <form method="POST">
        <label>用户名</label>
        <input type="text" name="username" required>
        <label>密码</label>
        <input type="password" name="password" required>
        <button type="submit">登录</button>
    </form>
    <p style="margin-top: 1rem; text-align: center;">
        还没有账号?<a href="{{ url_for('register') }}">注册</a>
    </p>
</div>
{% endblock %}

创建 templates/register.html

{% extends "base.html" %}
{% block title %}注册{% endblock %}
{% block content %}
<div class="card">
    <h2>注册</h2>
    <form method="POST">
        <label>用户名</label>
        <input type="text" name="username" required>
        <label>密码</label>
        <input type="password" name="password" required>
        <button type="submit">注册</button>
    </form>
    <p style="margin-top: 1rem; text-align: center;">
        已有账号?<a href="{{ url_for('login') }}">登录</a>
    </p>
</div>
{% endblock %}

第五步:运行测试

python app.py

访问 http://你的服务器IP:5000,试试:

  1. 点击"注册",创建一个账号
  2. 用刚才的账号登录
  3. 看到欢迎页面
  4. 点击"退出"

第六步:部署上线

开发完成后,用 Gunicorn 部署到生产环境:

# 安装 Gunicorn
pip install gunicorn

# 创建 systemd 服务
sudo tee /etc/systemd/system/myapp.service << EOF
[Unit]
Description=My Flask App
After=network.target

[Service]
User=root
WorkingDirectory=/root/data/my-flask-app
Environment="PATH=/root/data/my-flask-app/venv/bin"
ExecStart=/root/data/my-flask-app/venv/bin/gunicorn -w 2 -b 127.0.0.1:5000 app:app
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

配置 Nginx 反向代理:

sudo tee /etc/nginx/conf.d/myapp.conf << EOF
server {
    listen 80;
    server_name myapp.你的域名.com;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
    }
}
EOF

sudo nginx -t && sudo systemctl reload nginx

让 Claude 帮你做

上面的步骤看起来很多?试试让 Claude Code 来做:

帮我在 ~/data/my-flask-app 创建一个 Flask 应用:
- 用户注册、登录、注销功能
- 使用 PostgreSQL 存储用户(连接串:postgres://postgres:piglet@localhost/postgres)
- 界面要好看
- 帮我创建数据库表
- 最后帮我部署到 Nginx

Claude 会自动完成所有步骤。


你学到了什么

  • ✅ 创建 Flask 应用
  • ✅ 连接 PostgreSQL 数据库
  • ✅ 实现用户认证(注册/登录/注销)
  • ✅ 使用 Jinja2 模板
  • ✅ 部署到生产环境

下一步