Compare commits
16 Commits
c09b23df6e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ef1ceb384 | ||
|
|
567fc2c180 | ||
|
|
042a377143 | ||
|
|
ed054da5d8 | ||
|
|
893839c7a8 | ||
|
|
fb80480a22 | ||
|
|
21e3e33da9 | ||
|
|
9159cdf83c | ||
|
|
df5c412c7b | ||
|
|
2ea8964b7c | ||
|
|
7f2a609914 | ||
|
|
a72b1faf11 | ||
|
|
3180fb0ee8 | ||
|
|
24905d501f | ||
|
|
961cc218f1 | ||
|
|
5cd3ecd5e5 |
@@ -74,4 +74,8 @@ A: 不需要。TEI 只做向量生成(文本→向量),不存储任何数
|
|||||||
A: 可能网络问题。可以尝试:
|
A: 可能网络问题。可以尝试:
|
||||||
- 使用断点续传:`curl -C - -L -o file.tar.gz URL`
|
- 使用断点续传:`curl -C - -L -o file.tar.gz URL`
|
||||||
- 使用国内镜像或代理
|
- 使用国内镜像或代理
|
||||||
- 通过 Gitea 等国内 Git 服务托管
|
- 通过 Gitea 等国内 Git 服务托管
|
||||||
|
|
||||||
|
## Q: Swagger UI 可以随意注册用户,生产环境安全吗?
|
||||||
|
|
||||||
|
A: Mem0 系统级别的单用户模式——注册第一个 admin 用户后,系统禁止再注册新用户。
|
||||||
405
AI/mem0/deploy.md
Normal file
405
AI/mem0/deploy.md
Normal file
@@ -0,0 +1,405 @@
|
|||||||
|
# mem0 自托管部署
|
||||||
|
|
||||||
|
## 镜像
|
||||||
|
|
||||||
|
```
|
||||||
|
ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## 依赖服务(tei namespace)
|
||||||
|
|
||||||
|
| 服务 | 地址 | 用途 |
|
||||||
|
|---|---|---|
|
||||||
|
| PostgreSQL | 192.168.3.49:5432 | 关系数据存储 |
|
||||||
|
| Qdrant | qdrant:6333 | 向量存储 |
|
||||||
|
| TEI (BGE-M3) | tei:8080 | Embedder(文本→向量) |
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
### ConfigMap (mem0-env)
|
||||||
|
|
||||||
|
| 变量 | 值 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| APP_DB_NAME | mem0 | 数据库名 |
|
||||||
|
| QDRANT_HOST | qdrant | Qdrant 服务地址 |
|
||||||
|
| QDRANT_PORT | 6333 | Qdrant 端口 |
|
||||||
|
| QDRANT_COLLECTION_NAME | mem0 | 集合名 |
|
||||||
|
| EMBEDDER_PROVIDER | tei | Embedder 使用 TEI |
|
||||||
|
| TEI_ENDPOINT | http://tei:8080 | TEI endpoint |
|
||||||
|
| LLM_PROVIDER | openai | LLM provider(MiniMax 兼容 OpenAI 格式) |
|
||||||
|
| OPENAI_API_KEY | YOUR_MINIMAX_KEY | MiniMax API key |
|
||||||
|
| OPENAI_BASE_URL | https://api.minimax.chat/v1 | MiniMax API 地址 |
|
||||||
|
| AUTH_DISABLED | false | 启用认证 |
|
||||||
|
| MEM0_TELEMETRY | false | 关闭遥测 |
|
||||||
|
| REQUEST_LOG_RETENTION_DAYS | 30 | 日志保留天数 |
|
||||||
|
| HISTORY_DB_PATH | /app/data/mem0_history.db | SQLite 历史数据库路径 |
|
||||||
|
|
||||||
|
### Secret (mem0-secrets)
|
||||||
|
|
||||||
|
| 变量 | 说明 |
|
||||||
|
|---|---|
|
||||||
|
| JWT_SECRET | JWT 签名密钥 |
|
||||||
|
| ADMIN_API_KEY | 管理后台 API key |
|
||||||
|
| POSTGRES_PASSWORD | PostgreSQL 密码 |
|
||||||
|
|
||||||
|
## 数据库迁移 (Alembic)
|
||||||
|
|
||||||
|
mem0 server 使用 Alembic 管理 PostgreSQL schema。**首次部署前必须先执行迁移**,创建 `request_logs` 等表。
|
||||||
|
|
||||||
|
### 迁移 Job
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: mem0-migrate
|
||||||
|
namespace: tei
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 300 # 完成后5分钟自动清理
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
containers:
|
||||||
|
- name: alembic
|
||||||
|
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||||
|
command: ["alembic", "upgrade", "head"]
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mem0-env
|
||||||
|
- secretRef:
|
||||||
|
name: mem0-secrets
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dify-prod-db-secret
|
||||||
|
key: password
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 迁移部署步骤
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 先跑迁移(只执行一次)
|
||||||
|
kubectl apply -f mem0-migrate-job.yaml
|
||||||
|
|
||||||
|
# 2. 确认迁移完成
|
||||||
|
kubectl get job mem0-migrate -n tei -w
|
||||||
|
|
||||||
|
# 3. 确认成功后再部署 mem0
|
||||||
|
kubectl apply -f mem0-deployment.yaml
|
||||||
|
|
||||||
|
# 4. 如果迁移失败,查看原因
|
||||||
|
kubectl logs job/mem0-migrate -n tei
|
||||||
|
```
|
||||||
|
|
||||||
|
**重要**:迁移 Job 只跑一次。Pod 重启时不需要重新迁移,PostgreSQL schema 不会天天变。
|
||||||
|
|
||||||
|
## 前置要求
|
||||||
|
|
||||||
|
1. **pgvector 扩展** — PostgreSQL 需要安装 pgvector
|
||||||
|
2. **mem0 数据库** — 需要提前创建
|
||||||
|
3. **mem0-migrate Job** — 首次部署前必须先执行迁移
|
||||||
|
4. **mem0-history PVC** — 必须提前创建
|
||||||
|
5. **Qdrant collection** — mem0 启动时自动创建(首次调用时)
|
||||||
|
|
||||||
|
## 部署清单
|
||||||
|
|
||||||
|
### PVC + ConfigMap + Secret + Deployment + Service
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: mem0-history
|
||||||
|
namespace: tei
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
|
storageClassName: standard # 根据你的 StorageClass 调整
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: mem0-env
|
||||||
|
namespace: tei
|
||||||
|
data:
|
||||||
|
APP_DB_NAME: "mem0"
|
||||||
|
QDRANT_HOST: "qdrant"
|
||||||
|
QDRANT_PORT: "6333"
|
||||||
|
QDRANT_COLLECTION_NAME: "mem0"
|
||||||
|
EMBEDDER_PROVIDER: "tei"
|
||||||
|
TEI_ENDPOINT: "http://tei:8080"
|
||||||
|
LLM_PROVIDER: "openai"
|
||||||
|
OPENAI_API_KEY: "YOUR_MINIMAX_KEY"
|
||||||
|
OPENAI_BASE_URL: "https://api.minimax.chat/v1"
|
||||||
|
AUTH_DISABLED: "false"
|
||||||
|
MEM0_TELEMETRY: "false"
|
||||||
|
REQUEST_LOG_RETENTION_DAYS: "30"
|
||||||
|
HISTORY_DB_PATH: "/app/data/mem0_history.db"
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: mem0-secrets
|
||||||
|
namespace: tei
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
JWT_SECRET: "your-jwt-secret-change-me"
|
||||||
|
ADMIN_API_KEY: "your-admin-key-change-me"
|
||||||
|
POSTGRES_PASSWORD: "gitlab"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mem0
|
||||||
|
namespace: tei
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mem0
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: mem0
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: mem0
|
||||||
|
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
name: http
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mem0-env
|
||||||
|
- secretRef:
|
||||||
|
name: mem0-secrets
|
||||||
|
volumeMounts:
|
||||||
|
- name: mem0-history
|
||||||
|
mountPath: /app/data
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "2"
|
||||||
|
memory: "4Gi"
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
volumes:
|
||||||
|
- name: mem0-history
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mem0-history
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mem0
|
||||||
|
namespace: tei
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 8000
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: mem0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查 PVC
|
||||||
|
kubectl get pvc -n tei mem0-history
|
||||||
|
|
||||||
|
# 检查 Pod
|
||||||
|
kubectl get pods -n tei -l app=mem0
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
kubectl logs -n tei -l app=mem0 --tail=50
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
curl http://mem0:8000/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## History SQLite 说明
|
||||||
|
|
||||||
|
mem0 的对话历史存储在 SQLite,位于 `/app/data/mem0_history.db`。**必须用 PVC 持久化**,emptyDir 挂载重启后数据丢失。
|
||||||
|
|
||||||
|
如果 PVC 空间不足或不需要历史功能,可以改用空目录(数据丢失但不影响核心记忆功能):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# 测试/轻量级环境用 emptyDir
|
||||||
|
volumes:
|
||||||
|
- name: mem0-history
|
||||||
|
emptyDir: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dashboard 部署
|
||||||
|
|
||||||
|
mem0 dashboard 是 Next.js 应用,需要单独部署。
|
||||||
|
|
||||||
|
### 环境变量
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
NEXT_PUBLIC_API_URL=http://mem0.tei.svc.cluster.local:8000 # 浏览器调用(通过 Ingress)
|
||||||
|
API_INTERNAL_URL=http://mem0.tei.svc.cluster.local:8000 # 服务端内部调用(K8s 内部直连)
|
||||||
|
NEXT_PUBLIC_INSTANCE_NAME=Mem0
|
||||||
|
```
|
||||||
|
|
||||||
|
**`API_INTERNAL_URL`**:K8s 内部服务间通信,直接使用 Service DNS,不需要暴露到外部。浏览器无法解析 `mem0.tei.svc.cluster.local`,所以前端用 `NEXT_PUBLIC_API_URL` 通过 Ingress 访问。
|
||||||
|
|
||||||
|
两者可以相同,但分离部署时:
|
||||||
|
- `NEXT_PUBLIC_API_URL` = 对外域名(Ingress)
|
||||||
|
- `API_INTERNAL_URL` = 集群内部 `mem0.tei.svc.cluster.local:8000`
|
||||||
|
|
||||||
|
### CORS 配置
|
||||||
|
|
||||||
|
mem0 server 使用 CORSMiddleware,需要通过环境变量配置允许的来源:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
DASHBOARD_URL=https://mem0.your-domain.com # dashboard 的外部访问地址
|
||||||
|
```
|
||||||
|
|
||||||
|
mem0 server 启动时读取 `DASHBOARD_URL`,设置 `allow_origins=[DASHBOARD_URL]`。
|
||||||
|
|
||||||
|
**常见问题**:
|
||||||
|
- 浏览器访问 dashboard 登录页时,返回 `400 Bad Request`
|
||||||
|
- OPTIONS 预检请求失败,因为 `allow_origins` 为空
|
||||||
|
- Swagger 能正常登录(同域请求,无 CORS 问题)
|
||||||
|
|
||||||
|
确保 `DASHBOARD_URL` 设为 dashboard 的外部访问地址(与 `NEXT_PUBLIC_API_URL` 的域名部分一致)。
|
||||||
|
|
||||||
|
## sentence_transformers 导入错误(永久修复)
|
||||||
|
|
||||||
|
mem0 的 `huggingface.py` 在文件顶部执行 `from sentence_transformers import SentenceTransformer`,即使走 `huggingface_base_url` 路径(用 OpenAI 客户端调用 TEI,不需要本地模型)也会尝试加载,造成 `ModuleNotFoundError`。
|
||||||
|
|
||||||
|
通过 init container + emptyDir 挂载实现持久修复,pod recreate 不丢失:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mem0
|
||||||
|
namespace: tei
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mem0
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: mem0
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: patch-mem0
|
||||||
|
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
cp -r /usr/local/lib/python3.12/site-packages/mem0 /tmp/mem0-patch/
|
||||||
|
sed -i 's/from sentence_transformers import SentenceTransformer/# from sentence_transformers import SentenceTransformer/' /tmp/mem0-patch/embeddings/huggingface.py
|
||||||
|
echo "patch done"
|
||||||
|
volumeMounts:
|
||||||
|
- name: mem0-code
|
||||||
|
mountPath: /tmp/mem0-patch
|
||||||
|
containers:
|
||||||
|
- name: mem0-ui
|
||||||
|
image: ccr.ccs.tencentyun.com/tei_agent/mem0-ui:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 3000
|
||||||
|
name: http
|
||||||
|
env:
|
||||||
|
- name: NEXT_PUBLIC_API_URL
|
||||||
|
value: "https://api.mem0.violin-work.online"
|
||||||
|
- name: API_INTERNAL_URL
|
||||||
|
value: "http://mem0.tei.svc.cluster.local:8000"
|
||||||
|
- name: NEXT_PUBLIC_INSTANCE_NAME
|
||||||
|
value: Mem0
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 500Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 250Mi
|
||||||
|
- name: mem0
|
||||||
|
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
name: http
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mem0-env
|
||||||
|
- secretRef:
|
||||||
|
name: mem0-secrets
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dify-prod-db-secret
|
||||||
|
key: password
|
||||||
|
volumeMounts:
|
||||||
|
- name: mem0-history
|
||||||
|
mountPath: /app/data
|
||||||
|
- name: mem0-code
|
||||||
|
mountPath: /usr/local/lib/python3.12/site-packages/mem0
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "2"
|
||||||
|
memory: 4Gi
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: 1Gi
|
||||||
|
volumes:
|
||||||
|
- name: mem0-history
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mem0-history
|
||||||
|
- name: mem0-code
|
||||||
|
emptyDir: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
**原理**:init container 先于主容器启动,把镜像里的 mem0 代码复制到 emptyDir,sed 补丁打在 emptyDir 里。主容器挂载 emptyDir 到 site-packages,覆盖镜像原有文件,实现补丁持久化(recreate 不丢)。
|
||||||
|
|
||||||
|
## 功能测试
|
||||||
|
|
||||||
|
mem0 未为 K8s 做适配,无健康检查端点。手动测试核心 API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > /tmp/test_mem0.py << 'TESTEOF'
|
||||||
|
import urllib.request, json, uuid
|
||||||
|
|
||||||
|
BASE = "http://mem0:8000"
|
||||||
|
|
||||||
|
def req(method, path, data=None):
|
||||||
|
url = BASE + path
|
||||||
|
body = json.dumps(data).encode() if data else None
|
||||||
|
headers = {"Content-Type": "application/json"}
|
||||||
|
try:
|
||||||
|
r = urllib.request.urlopen(urllib.request.Request(url, data=body, headers=headers, method=method), timeout=10)
|
||||||
|
return json.loads(r.read()), r.status
|
||||||
|
except urllib.error.HTTPError as e:
|
||||||
|
return json.loads(e.read()), e.code
|
||||||
|
except Exception as e:
|
||||||
|
return str(e), 0
|
||||||
|
|
||||||
|
uid = str(uuid.uuid4())
|
||||||
|
print("=== 1. 创建用户 ===")
|
||||||
|
print(req("POST", "/api/v1/users", {"user_id": uid, "email": f"{uid}@test.com"}))
|
||||||
|
|
||||||
|
print("=== 2. 添加记忆 ===")
|
||||||
|
print(req("POST", "/api/v1/memories", {"text": "我叫张三,我喜欢Python", "user_id": uid}))
|
||||||
|
|
||||||
|
print("=== 3. 搜索记忆 ===")
|
||||||
|
print(req("GET", f"/api/v1/memories?query=python&user_id={uid}"))
|
||||||
|
|
||||||
|
print("=== 4. 获取历史 ===")
|
||||||
|
print(req("GET", f"/api/v1/history?user_id={uid}"))
|
||||||
|
TESTEOF
|
||||||
|
kubectl exec -n tei deploy/mem0 -- python3 /tmp/test_mem0.py
|
||||||
|
```
|
||||||
11
AI/openviking/Dockerfile
Normal file
11
AI/openviking/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN pip install openviking --upgrade --force-reinstall
|
||||||
|
|
||||||
|
RUN openviking-server init
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["openviking-server", "run", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
@@ -60,6 +60,28 @@ git config --global http.proxy http://用户名:密码@东京服务器IP:3128
|
|||||||
git config --global https.proxy http://用户名:密码@东京服务器IP:3128
|
git config --global https.proxy http://用户名:密码@东京服务器IP:3128
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### K3s (containerd) 配置
|
||||||
|
K3s 默认使用 containerd,不走 systemd代理,需要在 k3s service 环境变量中配置。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 添加代理环境变量到 k3s service
|
||||||
|
mkdir -p /etc/systemd/system/k3s.service.d
|
||||||
|
cat > /etc/systemd/system/k3s.service.d/http-proxy.conf <<EOF
|
||||||
|
[Service]
|
||||||
|
Environment="HTTP_PROXY=http://用户名:密码@东京服务器IP:3128"
|
||||||
|
Environment="HTTPS_PROXY=http://用户名:密码@东京服务器IP:3128"
|
||||||
|
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.svc,.cluster.local"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload && systemctl restart k3s
|
||||||
|
```
|
||||||
|
|
||||||
|
验证:
|
||||||
|
```bash
|
||||||
|
crictl pull nginx
|
||||||
|
kubectl run nginx --image=nginx
|
||||||
|
```
|
||||||
|
|
||||||
### 取消代理(如需直连)
|
### 取消代理(如需直连)
|
||||||
```bash
|
```bash
|
||||||
git config --global --unset http.proxy
|
git config --global --unset http.proxy
|
||||||
@@ -77,6 +99,53 @@ git clone https://github.com/torvalds/linux
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 外部镜像同步到本地 Registry
|
||||||
|
|
||||||
|
### 场景
|
||||||
|
东京服务器能访问 `ghcr.io`/`docker.io`,需要同步到本地 `localhost:5000` registry,供国内 K8s 节点拉取。
|
||||||
|
|
||||||
|
### 拉取外部镜像
|
||||||
|
```bash
|
||||||
|
docker pull ghcr.io/volcengine/openviking:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 同步到本地 Registry(推荐保留原始路径)
|
||||||
|
```bash
|
||||||
|
# 打 tag,路径保留原始仓库路径
|
||||||
|
docker tag ghcr.io/volcengine/openviking:latest localhost:5000/ghcr.io/volcengine/openviking:latest
|
||||||
|
|
||||||
|
# 推送
|
||||||
|
docker push localhost:5000/ghcr.io/volcengine/openviking:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 国内 K8s 节点拉取
|
||||||
|
```bash
|
||||||
|
docker pull 43.130.228.226:5000/ghcr.io/volcengine/openviking:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 用 skopeo 跳过本地存储直接同步(多架构镜像推荐)
|
||||||
|
```bash
|
||||||
|
apt update && apt install -y skopeo
|
||||||
|
|
||||||
|
skopeo copy --dest-tls-verify=false \
|
||||||
|
docker://ghcr.io/volcengine/openviking:latest \
|
||||||
|
docker://localhost:5000/ghcr.io/volcengine/openviking:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看本地 Registry 内容
|
||||||
|
```bash
|
||||||
|
curl -s http://localhost:5000/v2/_catalog
|
||||||
|
curl -s http://localhost:5000/v2/ghcr.io/volcengine/openviking/tags/list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 路径说明
|
||||||
|
- `localhost:5000/library/alpine` = Docker 官方镜像路径
|
||||||
|
- `localhost:5000/ghcr.io/volcengine/openviking` = 保留原始来源路径(推荐)
|
||||||
|
|
||||||
|
保留原始路径好处:一目了然知道镜像来源。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
- 东京服务器带宽低(1-2Mbps),Docker 拉大镜像较慢
|
- 东京服务器带宽低(1-2Mbps),Docker 拉大镜像较慢
|
||||||
- Git 流量小,代理无压力
|
- Git 流量小,代理无压力
|
||||||
|
|||||||
36
Linux/linux-users.md
Normal file
36
Linux/linux-users.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Linux 用户基础操作
|
||||||
|
|
||||||
|
## 查看用户
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看所有用户
|
||||||
|
cat /etc/passwd
|
||||||
|
|
||||||
|
# 查看当前在线用户
|
||||||
|
who
|
||||||
|
|
||||||
|
# 显示谁在登录
|
||||||
|
w
|
||||||
|
```
|
||||||
|
|
||||||
|
## 切换用户
|
||||||
|
|
||||||
|
```bash
|
||||||
|
su - postgres # 切换到 postgres 用户(带登录 shell)
|
||||||
|
sudo su - postgres # 用 sudo 切换(需要 root 权限)
|
||||||
|
```
|
||||||
|
|
||||||
|
## PostgreSQL 进数据库
|
||||||
|
|
||||||
|
```bash
|
||||||
|
su - postgres # 先切到 postgres 用户
|
||||||
|
psql # 直接进数据库
|
||||||
|
```
|
||||||
|
|
||||||
|
或者不切换用户直接进:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -U postgres -h 192.168.3.49 -p 5432
|
||||||
|
```
|
||||||
|
|
||||||
|
输入密码后进入 SQL 操作界面,quit 用 `\q`。
|
||||||
Reference in New Issue
Block a user