1. 为什么你需要一个自己的Joplin私有云如果你和我一样是个喜欢用笔记记录一切的人从一闪而过的灵感、项目规划到读书笔记、生活清单那你肯定听说过或者正在用Joplin。它开源、免费、全平台支持还能用Markdown简直是笔记爱好者的福音。但用久了官方同步服务心里总会有点不踏实我的笔记数据到底在哪长期使用成本如何更重要的是那种“数据掌握在别人手里”的感觉对于注重隐私和自主权的技术人来说总是个疙瘩。几年前我也在纠结这个问题。直到有一次我需要整理一个涉及大量内部资料的专题对数据隔离和安全的要求极高这才下定决心必须把Joplin服务器搬回自己的地盘。官方提供了服务器版本配合Docker搭建过程比想象中简单太多。尤其是用Docker Compose把数据库我选了更稳定可靠的PostgreSQL和Joplin服务器“打包”在一起基本上就是几条命令的事。自己搭建的好处太多了。首先数据完全私有你的所有笔记、附件、标签都安静地躺在你自己的服务器硬盘上没有第三方可以触及。其次同步速度飞快内网自不必说就算有公网IP速度也远非跨国同步服务可比。最后它给了你终极的定制自由从数据库选型、存储路径到邮件提醒样式你都可以按自己的心意来摆弄。这不仅仅是搭建一个服务更像是给自己打造一个专属的、永不丢失的“数字第二大脑”基地。所以无论你是开发者、学生还是任何希望将知识管理权收回己有的朋友跟着这篇指南用大概半小时到一小时的时间你就能拥有一个完全受控、高性能的Joplin私有云。我们避开复杂的理论直接上手实操我会把每一步的细节、我踩过的坑以及怎么绕过去都清清楚楚地告诉你。2. 搭建前你需要准备些什么动手之前我们先来清点一下“工具箱”。别担心不需要你已经是Linux大师或者Docker专家只要跟着步骤来小白也能轻松搞定。2.1 硬件与系统环境首先你得有一台服务器。这可以是一台你闲置的旧电脑或笔记本电脑。家里树莓派之类的开发板。更常见的是一台云服务器比如阿里云、腾讯云的轻量应用服务器。我个人的经验是选择1核2G内存以上的配置就完全足够了Joplin本身并不吃资源。操作系统我强烈推荐Ubuntu 22.04 LTS或Debian 11它们对Docker的支持非常友好社区资料也丰富出了问题容易找到解决方案。2.2 软件依赖Docker 和 Docker Compose这是我们整个搭建的核心工具。你可以把它们理解为一个超级高效的“软件集装箱”系统。Docker负责把应用和它需要的环境比如特定的Linux版本、库文件打包成一个独立的“镜像”而Docker Compose则是一个“编排工具”让你能用一份简单的配置文件定义并启动多个互相关联的Docker容器比如我们的数据库和Joplin服务器。在Ubuntu/Debian上安装它们非常简单打开服务器的终端SSH连接上就行依次执行下面这几条命令# 更新系统软件包列表这是个好习惯 sudo apt update # 安装一些让apt能通过HTTPS使用仓库的工具 sudo apt install -y apt-transport-https ca-certificates curl software-properties-common # 添加Docker的官方GPG密钥用于验证软件包 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加Docker的稳定版仓库到系统源 echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 再次更新这次就能看到Docker的仓库了 sudo apt update # 安装Docker引擎包含docker-ce, docker-ce-cli等 sudo apt install -y docker-ce docker-ce-cli containerd.io # 安装Docker Compose的独立版本v2 sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose安装完成后验证一下docker --version docker-compose --version如果都能正确输出版本号那么恭喜你最重要的基础已经打好了。为了不用每次都输入sudo来执行docker命令我们可以把当前用户加入docker组sudo usermod -aG docker $USER注意执行这条命令后你需要完全退出当前的SSH会话然后重新登录这个改动才会生效。2.3 一个属于你的域名可选但推荐如果你只想在家庭局域网内使用用IP地址直接访问也行。但如果你想在任何地方都能同步笔记绑定一个域名会方便很多。你可以去任何域名注册商那里买一个便宜的域名然后在云服务器的控制台把这个域名解析到你的服务器公网IP地址上。别担心后续在配置里我们会用到它。2.4 一个可用的邮箱用于账户注册和通知Joplin服务器在用户注册、忘记密码时会发送邮件。你需要准备一个支持SMTP服务的邮箱比如QQ邮箱、163邮箱、Gmail等并获取它的SMTP授权码不是登录密码。这个我们后面配置时会详细说。好了万事俱备只欠东风。接下来我们就进入最核心的环节——编写和调整那份神奇的docker-compose.yml配置文件。3. 核心实战编写你的 Docker Compose 配置文件现在我们来到最关键的一步。所有的魔法都藏在这个叫docker-compose.yml的文件里。我会带你逐行解析让你不仅知道怎么抄更明白为什么要这么写。首先在你的服务器上找一个你喜欢的位置创建一个专属的目录比如joplin-server然后进入它mkdir ~/joplin-server cd ~/joplin-server接着用你喜欢的文本编辑器如nano或vim创建这个文件nano docker-compose.yml然后将下面的配置内容粘贴进去。请先通读一遍不要急着运行后面我会告诉你哪些地方必须修改。version: 3.8 services: # 数据库服务我们选择PostgreSQL postgres: image: postgres:15-alpine container_name: joplin-db restart: unless-stopped volumes: - ./data/postgres:/var/lib/postgresql/data environment: - POSTGRES_USERjoplin - POSTGRES_PASSWORDYourStrongPassword123! - POSTGRES_DBjoplin networks: - joplin-network # 健康检查确保数据库完全启动后Joplin服务再启动 healthcheck: test: [CMD-SHELL, pg_isready -U joplin] interval: 10s timeout: 5s retries: 5 # Joplin 服务器本体 joplin: image: joplin/server:latest container_name: joplin-app depends_on: postgres: condition: service_healthy # 依赖数据库的健康状态 restart: unless-stopped ports: - 22300:22300 volumes: - ./data/joplin:/var/lib/joplin environment: # 应用基础配置 - APP_PORT22300 - APP_BASE_URLhttps://your-domain.com # 【必须修改】你的域名或IP - DB_CLIENTpg # 数据库连接配置与上面的postgres服务对应 - POSTGRES_HOSTpostgres - POSTGRES_PORT5432 - POSTGRES_USERjoplin - POSTGRES_PASSWORDYourStrongPassword123! - POSTGRES_DATABASEjoplin # 安全与区域配置 - ALLOW_ORIGINhttps://your-domain.com # 【必须修改】允许访问的源同上 - LANGzh_CN.UTF-8 # 邮件服务配置用于用户注册和密码重置 - MAILER_ENABLEDtrue - MAILER_HOSTsmtp.your-email-provider.com # 【必须修改】如 smtp.qq.com - MAILER_PORT465 - MAILER_SECURITYtls - MAILER_AUTH_USERyour-emailexample.com # 【必须修改】你的发件邮箱 - MAILER_AUTH_PASSWORDyour-smtp-authorization-code # 【必须修改】SMTP授权码 - MAILER_NOREPLY_NAMEJoplin Server - MAILER_NOREPLY_EMAILyour-emailexample.com - SUPPORT_EMAILyour-emailexample.com - SUPPORT_NAMEJoplin Support networks: - joplin-network # 定义一个内部网络让两个容器可以安全通信 networks: joplin-network: driver: bridge3.1 配置文件逐行精讲与个性化修改现在我们像拆解乐高一样看看这个配置的每一块是干什么的以及你必须修改的几个关键点。第一部分数据库服务 (postgres)image: postgres:15-alpine 我们使用了PostgreSQL 15的Alpine Linux版本镜像。Alpine版本非常轻量体积小安全性高是容器的最佳搭档。volumes: - ./data/postgres:/var/lib/postgresql/data 这一行是数据持久化的关键。它将容器内的数据库数据目录映射到了宿主机的./data/postgres目录下。这样即使你删除了容器你的笔记数据实际上存在数据库里也不会丢失。./表示当前目录即~/joplin-server所以所有数据都会保存在这里。environment 这里设置了数据库的初始参数。POSTGRES_PASSWORD务必修改成一个强密码其他如用户名和数据库名可以按喜好修改但要记住后面Joplin服务的配置要和这里对应上。第二部分Joplin服务 (joplin)depends_on 这里我们用了高级的condition: service_healthy意思是等数据库容器通过健康检查pg_isready命令返回成功后再启动Joplin容器。这避免了因数据库没准备好而导致的启动失败比简单的depends_on: - postgres更可靠。ports: - 22300:22300 将容器内部的22300端口映射到宿主机的22300端口。这意味着你通过服务器的IP:22300就能访问到Joplin服务。volumes: - ./data/joplin:/var/lib/joplin 同样是为了持久化这里映射的是Joplin服务器本身的一些运行时文件。environment 这里是配置的重中之重我们挑几个必须改的讲APP_BASE_URL和ALLOW_ORIGIN 这是最重要的修改项。如果你有域名例如notes.yourdomain.com就把它填在这里格式是https://notes.yourdomain.com。如果你暂时没有域名只能用IP访问那么这里就填http://你的服务器公网IP:22300。APP_BASE_URL是服务器告知客户端自己的地址ALLOW_ORIGIN是浏览器安全策略CORS的要求两者通常保持一致。实测中这里配置错误是导致客户端无法同步的最常见原因。邮件配置 (MAILER_*) 这是让用户能注册账号的关键。以QQ邮箱为例MAILER_HOST:smtp.qq.comMAILER_PORT:465MAILER_AUTH_USER: 你的QQ邮箱地址如12345678qq.comMAILER_AUTH_PASSWORD:这里不是QQ密码而是SMTP授权码。你需要登录QQ邮箱网页版在“设置”-“账户”里找到“POP3/IMAP/SMTP服务”开启后获取一个16位的授权码。MAILER_NOREPLY_EMAIL和SUPPORT_EMAIL: 可以都填你的邮箱。第三部分网络 (networks)我们创建了一个名为joplin-network的桥接网络。两个服务都加入这个网络后它们之间可以通过服务名postgresjoplin直接通信就像在同一个局域网内一样既安全又方便。把你的个性化信息全部修改无误后保存并退出编辑器在nano中是按CtrlX 然后按Y 最后回车。4. 一键启动与初始化验证配置文件准备好了启动服务就是一句话的事。在docker-compose.yml文件所在的目录下执行docker-compose up -d这个-d参数代表“后台运行”。执行后Docker Compose会做以下几件事自动去拉取Download我们配置文件中指定的postgres:15-alpine和joplin/server:latest镜像。根据配置创建并启动两个容器。按照depends_on的设定先确保数据库健康再启动Joplin应用。你可以用以下命令查看容器的运行状态和日志# 查看所有容器状态 docker-compose ps # 或者更详细的docker命令 docker ps # 查看Joplin容器的实时日志用于排查启动问题 docker-compose logs -f joplin如果看到日志最后有类似Joplin Server is running on port 22300的信息并且没有持续报错那就说明服务启动成功了接下来打开你的浏览器访问http://你的服务器IP:22300如果你配置了域名且解析生效就访问域名。你应该能看到Joplin服务器的登录/注册页面。这就证明Web服务已经正常工作了。4.1 创建你的管理员账户在登录页面点击“Sign up”注册第一个账户。这个第一个注册的账户会自动成为管理员账户。填写邮箱、密码等信息点击注册。如果邮件配置正确你的邮箱会收到一封验证邮件可能需要等一两分钟或者检查垃圾邮件。点击邮件中的链接完成验证即可登录。登录后你就能看到Joplin服务器的Web界面了。这里你可以管理用户如果你是管理员、查看服务器信息等。但我们的主要目的不是用网页版而是用更强大的桌面端或移动端来同步。5. 客户端配置与深度同步体验服务器跑起来了现在让我们在常用的设备上连接它。我以功能最全的Joplin桌面版Windows/Mac/Linux为例。安装并打开Joplin桌面客户端。在设置中找到“同步”选项。在“同步目标”中选择Joplin Server。在“服务器URL”中填入你之前配置的APP_BASE_URL例如https://notes.yourdomain.com或http://IP:22300。注意这里要填完整的URL包括http://或https://。在“电子邮件”和“密码”中填入你刚刚在网页端注册的账户信息。点击“检查同步配置”如果一切正常会显示成功。点击“应用”然后回到主界面点击左侧边栏的“同步”按钮就可以开始第一次同步了第一次同步可能会花点时间因为客户端需要从服务器拉取完整的配置和空的笔记结构。之后你在这台电脑上创建的任何笔记、笔记本、标签都会自动加密后同步到你的私有服务器上。5.1 移动端配置iOS/Android移动端的配置流程几乎一模一样。在App的设置中找到“同步”选择“Joplin Server”然后填入相同的服务器URL、邮箱和密码即可。从此你的手机、平板、电脑之间的笔记将实现无缝、实时的同步而且数据流完全经过你自己的服务器隐私性拉满。5.2 关于数据安全与加密这里有一个非常重要的点需要理解Joplin的端到端加密。当你设置同步时客户端会要求你输入一个“主密码”Master Password。这个密码不会发送给服务器它只存在于你的设备上用于在本地加密和解密你的笔记数据。也就是说同步到服务器上的数据是已经用你的主密码加密过的密文。即使有人能访问你的服务器数据库看到的也是一堆乱码。只有用你知道的主密码在客户端才能解密查看。这真正实现了“我的数据我做主”。6. 进阶调优与日常维护指南搭建完成只是开始要让这个服务稳定、安全、长久地跑下去我们还需要做一些优化和维护工作。6.1 配置反向代理与HTTPS安全性必备直接通过IP和端口号访问既不安全也不方便。我强烈建议你使用Nginx或Caddy作为反向代理并配置HTTPS证书。以Nginx为例假设你有一个域名notes.yourdomain.com已经解析到服务器IP。你可以在Nginx的配置文件中例如/etc/nginx/conf.d/joplin.conf添加如下配置server { listen 80; server_name notes.yourdomain.com; # 将HTTP请求重定向到HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name notes.yourdomain.com; # SSL证书路径可以使用Let‘s Encrypt免费证书 ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/privkey.pem; # 反向代理到Joplin容器 location / { proxy_pass http://127.0.0.1:22300; # 指向Docker映射的端口 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; # 以下两行对WebSocket支持很重要Joplin网页版可能用到 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }配置好后重启Nginx。同时别忘了将docker-compose.yml中的APP_BASE_URL和ALLOW_ORIGIN修改为https://notes.yourdomain.com并重启Joplin服务 (docker-compose restart joplin)。这样你就可以用安全的HTTPS方式访问了客户端同步配置里的URL也要相应更新。6.2 数据库的备份与恢复数据无价定期备份是必须的。由于我们使用了数据卷映射备份PostgreSQL数据目录是一个方法但更干净的方式是使用pg_dump命令。你可以写一个简单的备份脚本backup.sh#!/bin/bash BACKUP_DIR/path/to/your/backup/folder DATE$(date %Y%m%d_%H%M%S) docker exec joplin-db pg_dump -U joplin joplin $BACKUP_DIR/joplin_backup_$DATE.sql # 可选删除7天前的备份 find $BACKUP_DIR -name joplin_backup_*.sql -mtime 7 -delete然后通过crontab设置每天自动执行。恢复时用docker exec -i joplin-db psql -U joplin joplin /path/to/backup.sql即可。6.3 服务的更新与重启当Joplin发布新版本时更新非常简单# 进入项目目录 cd ~/joplin-server # 拉取最新的Joplin服务器镜像 docker-compose pull joplin # 重新启动服务会使用新镜像 docker-compose up -d数据库镜像PostgreSQL的更新需要更谨慎建议先备份数据再操作。6.4 监控与日志日常可以使用docker-compose logs --tail50 joplin查看近期日志。如果遇到问题比如客户端无法同步首先检查服务器日志最常见的错误就是APP_BASE_URL配置不对或者邮件服务配置错误导致注册失败。我自己在长期使用中还遇到过磁盘空间不足导致同步失败的情况。所以定期用df -h看看硬盘用docker system prune清理一下无用的Docker镜像和容器也是个好习惯。这个基于Docker Compose的Joplin私有云方案我已经稳定运行了超过两年服务了我和我的小团队的所有笔记需求。它就像一个沉默而可靠的数字基石让你可以完全专注于思考和记录而无需为数据的安全与归属担忧。