方案一:基础Docker部署
1. 使用官方镜像快速启动
# 创建数据目录
mkdir -p ~/memos
# 运行Memos容器
docker run -d \
--name memos \
-p 5230:5230 \
-v ~/memos/.memos/:/var/opt/memos \
ghcr.io/usememos/memos:latest
2. 使用Docker Compose(推荐)
创建 docker-compose.yml 文件:
version: '3.8'
services:
memos:
image: ghcr.io/usememos/memos:latest
container_name: memos
restart: unless-stopped
ports:
- "5230:5230"
volumes:
- ./data:/var/opt/memos
environment:
- TZ=Asia/Shanghai # 设置时区
启动服务:
docker-compose up -d
方案二:高级配置
1. 包含环境变量的完整配置
version: '3.8'
services:
memos:
image: ghcr.io/usememos/memos:latest
container_name: memos
restart: unless-stopped
ports:
- "5230:5230"
volumes:
- memos_data:/var/opt/memos
environment:
- TZ=Asia/Shanghai
- MEMOS_MODE=prod # 生产模式
- MEMOS_PORT=5230
# 可选:使用外部数据库(默认为SQLite)
# - MEMOS_DRIVER=postgres
# - MEMOS_DSN="postgres://user:password@postgres:5432/memos?sslmode=disable"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5230/api/v1/status"]
interval: 30s
timeout: 10s
retries: 3
volumes:
memos_data:
2. 使用外部PostgreSQL数据库
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: memos_postgres
restart: unless-stopped
environment:
POSTGRES_USER: memos
POSTGRES_PASSWORD: your_password_here
POSTGRES_DB: memos
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U memos"]
interval: 10s
timeout: 5s
retries: 5
memos:
image: ghcr.io/usememos/memos:latest
container_name: memos
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "5230:5230"
environment:
- MEMOS_MODE=prod
- MEMOS_DRIVER=postgres
- MEMOS_DSN=postgres://memos:your_password_here@postgres:5432/memos?sslmode=disable
volumes:
- ./resources:/var/opt/memos/resources # 只存储资源文件
volumes:
postgres_data:
方案三:使用Nginx反向代理
1. Docker Compose + Nginx配置
version: '3.8'
services:
memos:
image: ghcr.io/usememos/memos:latest
container_name: memos
restart: unless-stopped
expose:
- "5230"
environment:
- MEMOS_MODE=prod
volumes:
- ./data:/var/opt/memos
nginx:
image: nginx:alpine
container_name: memos_nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl # SSL证书目录
depends_on:
- memos
2. Nginx配置文件 (nginx.conf)
events {
worker_connections 1024;
}
http {
upstream memos {
server memos:5230;
}
server {
listen 80;
server_name your-domain.com;
# 重定向到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL证书路径
ssl_certificate /etc/nginx/ssl/your-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/your-domain.com.key;
# SSL优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
# 反向代理配置
location / {
proxy_pass http://memos;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_pass http://memos;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 1m;
}
}
}
方案四:使用Traefik反向代理(推荐用于生产环境)
version: '3.8'
services:
memos:
image: ghcr.io/usememos/memos:latest
container_name: memos
restart: unless-stopped
expose:
- "5230"
environment:
- MEMOS_MODE=prod
volumes:
- ./data:/var/opt/memos
labels:
- "traefik.enable=true"
- "traefik.http.routers.memos.rule=Host(`memos.your-domain.com`)"
- "traefik.http.routers.memos.entrypoints=websecure"
- "traefik.http.routers.memos.tls.certresolver=myresolver"
- "traefik.http.services.memos.loadbalancer.server.port=5230"
traefik:
image: traefik:v2.10
container_name: traefik
restart: unless-stopped
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=your-email@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
常用管理命令
# 查看容器状态
docker ps
# 查看日志
docker logs memos
docker logs -f memos # 实时查看
# 进入容器
docker exec -it memos sh
# 重启服务
docker restart memos
# 停止服务
docker stop memos
# 启动服务
docker start memos
# 删除容器(数据会保留在卷中)
docker rm memos
# 更新Memos
docker pull ghcr.io/usememos/memos:latest
docker stop memos
docker rm memos
# 然后重新运行部署命令
备份和恢复
备份数据
# 如果使用默认SQLite
docker cp memos:/var/opt/memos/memos_prod.db ./backup/
# 如果使用卷
docker run --rm -v memos_data:/data -v $(pwd):/backup alpine \
tar czf /backup/memos_backup_$(date +%Y%m%d).tar.gz -C /data .
恢复数据
# 停止Memos容器
docker stop memos
# 恢复数据
docker run --rm -v memos_data:/data -v $(pwd):/backup alpine \
tar xzf /backup/memos_backup.tar.gz -C /data
# 启动Memos
docker start memos
故障排除
-
端口冲突:如果5230端口被占用,可以修改映射端口
ports: - "8080:5230" # 外部端口:内部端口 -
权限问题:如果容器无法写入数据,可以设置正确的权限
chmod 755 ./data -
内存限制:可以设置容器资源限制
memos: # ... deploy: resources: limits: memory: 512M cpus: '1.0'