从零开始安装 solo 博客

本贴最后更新于 1683 天前,其中的信息可能已经时过境迁

之前也写过类似的帖子,但是由于那时自己的各种原因写的不是特别好,所以今天写一个聚合帖,记录从购买服务器到安装 solo 然后通过 nginx 反向代理,最后升级 https 的全过程。此贴献给完全无基础的人,所以废话较多,见谅

1. 购买服务器

首先你得有自己的服务器,有的话就跳过。服务商可选的有很多,比如:阿里云腾讯云百度云、还有一些香港的服务商以及国外的(有特殊需求的可以考虑下)。腾讯和阿里对于新用户以及学生都有很大的优惠,配置的话如果只挂 solo,买最低配 1G1 核 1M 即可。国内的几家都可以关注下,不定时会有很好的优惠活动。我比较推荐阿里云,前段时间刚买了一台 3 年才 668 多,不知道活动结束没有。阿里云购买服务器时会要求你安装系统(不知道可不可以不选),推荐选择 centos。

2. 购买域名(可不买)

建议还是买一个域名,直接通过 IP 访问的话不是特别好。购买域名时不要盯着 .com.cn 这种比较热门的域名,往往很贵。还有尽量选择可备案的域名,否则就会像鼠鼠在碎觉一样只能挂载 444 端口上运行。可通过域名.信息查看可备案域名。如果你服务器买着国外的话似乎就不用备案。

3. 域名解析与备案

服务器和域名购买完后需要将域名解析到服务器,有些服务商可能不支持跨服务商解析,腾讯云域名可以解析阿里云服务器。解析过程大概需要 10 分钟。解析完成后如下图所示:
image.png
如果不备案的话,80 端口与 443 端口大概率会被封。所以备案还是需要的,备案的过程有点麻烦需要耐心。大致步骤如下:
image.png
image.png
接入备案很快,几天就完事了。

4. 为服务器安装系统

给服务器安装系统不用像你给自己装系统那样麻烦,很方便,由于我使用的 centos,所以推荐安装 centos,以免出现不必要的错误。后续操作嘘设置服务器安全组,开发如下端口:808080330644322。具体左右我会在下面一一说明,22用来远程连接服务器使用,windows 用户可下载 xshell 远程链接服务器。

5. 安装 docker

直接使用 yum 安装,简单快捷

#安装 Docker
yum -y install docker

#启动 Docker 后台服务
service docker start

#测试运行 hello-world
docker run hello-world

出现 hello world 就证明安装正常了
image.png

6.安装 Mysql

版本随意,我这里选择的 5.6,你可以选择更高版本的,这个没关系,不影响使用

# 安装mysql:5.6,直接docker run 他会自动去官方镜想下载
# MYSQL_ROOT_PASSWORD=你的数据库密码
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6

# docker安装的mysql默认允许远程连接,可以使用Navicat等软件连接数据库
# 进入容器mysql
docker exec -it mysql bash

# 进入数据库 p后面跟你的密码
mysql -uroot -pXXX

# 创建数据库(数据库名:solo;字符集utf8mb4;排序规则utf8mb4_general_ci)
create database solo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
# 出现Query OK, 1 row affected (0.00 sec)表示成功
#退出数据库
exit
#退出容器
exit

7. 安装 solo

直接运行以下命令

docker run --detach --name solo --network=host \
--env RUNTIME_DB="MYSQL" \
--env JDBC_USERNAME="root" \
--env JDBC_PASSWORD="123456" \
--env JDBC_DRIVER="com.mysql.cj.jdbc.Driver" \
--env JDBC_URL="jdbc:mysql://127.0.0.1:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC" \
--rm \
b3log/solo --listen_port=8080 --server_scheme=http --server_host=www.jinjianh.com

上面的命令建议手敲,免得出错,参数说明

  • --env JDBC_PASSWORD="123456" 将 123456 换成你的密码
  • --listen_port=8080 监听的端口
  • --server_scheme=http 请求方式,暂时使用 http,后面我们会换成 https
  • --server_host=www.jinjianh.com 你的域名,如果你没有域名可以写 ip 地址
  • --rm 因为这个容器后面要删掉,带上 rm 会省很多事。

命令成功执行没有报错的话,通过 docker ps 查看执行的容器列表中是否存在 solo,存在这表示启动成功,直接访问你的域名加:8080 即可访问你的博客,金戋博客--http://www.jinjianh.com:8080
如果你尚在备案中,你可以收藏本帖,后面等备案通过了在研究后面的部分。
如果你不想使用 nginx 也不想升级 https,那么你可以先执行 docker stop solo,然后将上面 --listen_port=80808080 换成 80,然后去掉 --rm,再执行一次就 ok。

8. 安装 nginx

安装 nginx 前,我们现在本地建立几个文件,用于存放 nginx 的配置文件等

# 切换到服务器根目录
cd /
# 创建主目录
mkdir dockerData
# 创建文件
mkdir dockerData/nginx dockerData/nginx/conf dockerData/nginx/logs dockerData/nginx/www dockerData/nginx/ssl

上面的 dockerData 可以换成自己喜欢的名字

  • dockerData/nginx 用于存放 docker 下 nginx 自定义文件
  • dockerData/nginx/conf 存放 nginx 配置文件
  • dockerData/nginx/log 存放 nginx 日志文件
  • dockerData/nginx/www 存放 nginx 访问的资源文件
  • dockerData/nginx/ssl 存放 ssl 证书
    启动 nginx
docker run --name nginx -p 80:80 -d --rm nginx

如果你没有备案,可以将上面的 80:80 换成 8081:80,因为这个东西一会儿也要删掉,所以加上 --rm 参数,命令执行玩后通过 docker ps 查看 nginx 是否在运行,在运行的情况下访问你的域名加端口号查看是否正常安装,80 直接省略。如下表示访问成功
image.png
导出配置文件

  • docker cp nginx:/etc/nginx/nginx.conf /dockerData/nginx/conf/nginx.conf 导出配置文件 nginx.conf
  • docker cp nginx:/etc/nginx/conf.d /dockerData/nginx/conf/conf.d 导出配置为你 nginx.conf
    执行 docker stop nginx,会自动删除现在的 nginx 容器,然后执行如下命令重新启动一个 nginx 容器
docker run -d -p 80:80 --name nginx \
-v /dockerData/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /dockerData/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /dockerData/nginx/www:/usr/share/nginx/html \
-v /dockerData/nginx/logs:/var/log/nginx nginx
  • -v /dockerData/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ 挂载配置文件 nginx.conf
  • -v /dockerData/nginx/conf/conf.d:/etc/nginx/conf.d 挂载配置文件 default.conf
  • -v /dockerData/nginx/www:/usr/share/nginx/html 挂载项目文件
  • -v /dockerData/nginx/logs:/var/log/nginx 挂载配置文件

访问你的域名,你会发现报错了

image.png
这时我们可以前往 /dockerData/nginx/logs 下查看日志文件

2019/08/05 14:57:54 [error] 6#6: *3 directory index of "/usr/share/nginx/html/" is forbidden, client: 121.32.33.217, server: localhost, request: "GET / HTTP/1.1", host: "www.jinjianh.com"

因为 /usr/share/nginx/html/ 被挂载到了服务器上面的 /dockerData/nginx/www 目录下,原来的欢迎页面在 dockerData/nginx/www 是没有的,所有就报错了,这里我们随便建一个。

# 打开项目文件
cd /dockerData/nginx/www
# 使用vim 创建并编辑文件
vim index.html
# 此时我们会进入vim界面,按 i 插入,然后输入
<h1>Hello Docker-Nginx</h1>
# 输入完后,按 esc,然后输入 :wq

再次访问我们的域名就可以看到我们刚刚写的 h1 标签内容

image.png

9. 申请 ssl 证书,将 http 升级为 https(可跳过)

https 想比与 http 来说,最核心的内容就是多了一个 ssl 证书,证书是可以免费申请的。

腾讯云

访问 SSL 证书选购 申请

image.png

私钥可不填写
image.png

选择手动 DNS 验证

image.png

可直接前往 SSL 证书 域名验证指引 - 操作指南 - 文档中心 - 腾讯云查看

image.png
image.png

前往证书管理-控制台等待验证通过即可

image.png

nginx 下文件上传到 /dockerData/nginx/ssl 目录下即可

阿里云

访问云盾证书服务申请,访问后如果有无内容可复制 https://common-buy.aliyun.com/?spm=5176.10695662.958455.3.3f9140d55mPzFH&commodityCode=cas#/buy 打开
image.png

走一下支付流程,然后申请

image.png
image.png
image.png
操作流程基本与腾讯云一样,我就不详细说明了

其他平台

免费的证书平台有很多,也可以去别的地方申请

上传证书

一下示例为腾讯云证书,阿里云
image.png

验证完后,我们下载证书,解压后得到

image.png

最后把 Nginx 下的两个文件上传至服务器 /dockerDat/nginx/ssl 目录下,别的服务商申请的证书也一样,将最后的 ssl 证书放到 /dockerDat/nginx/ssl 下即可

配置 nginx 配置文件

cd /dockerData/nginx/conf/conf.d
vim default.conf

# 参考我的配置,配置自己的default.conf文件
server {
    listen       443;
    server_name  localhost;
    ssl on;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    ssl_certificate /ssl/1_www.jinjianh.com_bundle.crt;  # ssl 证书目录
    ssl_certificate_key /ssl/2_www.jinjianh.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
# ......
}
server{
  listen 80;
  server_name localhost;
  rewrite ^(.*) https://$host$1 permanent;
}
# 按esc,然后输入:wq保持退出

不重要的部分我省略了,可根据自己服务器配置做出相应调整
由于我们现在用的 nginx 容器并未监听 443 端口,所以需要删除现在的容器,重新启动一个新的 nginx 容器

docker stop nginx  # 停止容器
docker rm nginx # 删除容器
# 启动新的
docker run -d -p 80:80 -p 443:443 --name nginx \
-v /dockerData/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /dockerData/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /dockerData/nginx/ssl:/ssl/ \
-v /dockerData/nginx/www:/usr/share/nginx/html \
-v /dockerData/nginx/logs:/var/log/nginx nginx
  • -p 443:443 监听 443 端口
  • -v /dockerData/nginx/ssl:/ssl/ 挂载 ssl 证书目录

访问查看,一切正常
image.png

10. 将 solo 通过 nginx 方向代理实现 https 访问

让 solo 还是跑在 8080 端口上,通过 nginx 代理到 443 端口即可,由于我们上面启动 solo 时添加了 --rm 参数,只需要 docker stop solo 即可自动删除 solo 容器,然后我们重新启动一个 solo 容器

docker run --detach --name solo --network=host \
--env RUNTIME_DB="MYSQL" \
--env JDBC_USERNAME="root" \
--env JDBC_PASSWORD="123123" \
--env JDBC_DRIVER="com.mysql.cj.jdbc.Driver" \
--env JDBC_URL="jdbc:mysql://127.0.0.1:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC" \
b3log/solo --listen_port=8080 --server_scheme=https --server_host=www.jinjianh.com --server_port=
  • --server_scheme=http 换成 --server_scheme=https 即可
  • --server_port:最终访问端口,使用浏览器默认的 80 或者 443 的话值留空即可

然后我们去配置 nginx 配置文件,实现 nginx 反向代理

cd /dockerData/nginx/conf/conf.d
vim default.conf
 location / {
        proxy_pass http://backend$request_uri;
        proxy_set_header  Host $http_host;
        proxy_set_header  X-Real-IP $remote_addr;
        #root   /usr/share/nginx/html;
        #index  index.html index.htm;
    }
# 替换上面部分即可
# 按esc,然后输入:wq保持退出

注意!!!Nginx 反代理上面的方式可能出现问题参考 Nginx 反代

注意!!!Nginx 反代理上面的方式可能出现问题参考 Nginx 反代

注意!!!Nginx 反代理上面的方式可能出现问题参考 Nginx 反代

重启 nginx,docker restart nginx

image.png

完美

11. 后记

皮肤挂载

  • 在你的服务器上创建一个目录用于存放皮肤,比如我的 /dockerData/solo/skins/
  • 然后将你要挂载的皮肤放到上面那个目录下
  • 最后删除当前容器 重新启动一个容器,添加参数 --v /dockerData/solo/skins/:/opt/solo/skins/,这个添加时要注意位置,要添加到 b3log/solo --listen... 的上面一排
  • 使用挂载皮肤时,默认会使用 Pingsu,

皮肤推荐

我开源了两款皮肤 solo-nexmoe,因为我很懒的原因,solo-star 没有手机端,所以你可以多挂载一款皮肤们比如官方皮肤 Pinghsu,如果你没有这款皮肤就会报错,没有请前往 solo-skins 下载

数据库占用内存过大优化

由于我们购买的服务器是内存只有 1G,然后 docker 安装的 mysql 虽然很快,但是实际上占用内存非常大,之前服务器在腾讯云的时候就经常挂掉,排查了很久才发现是 docker 下 mysql 的问题,迁移到阿里云后倒是没出先挂掉的问题,但是服务器内存占用也一直在 90% 以上,所以我们对 mysql 容器进行一些优化。
由于容器内不能 vim,所以我们将 mysql 的配置文件复制到服务器上改了之后再复制回去,也可以将配置文件挂载到服务器上,过程我不多讲,只讲核心部分。

这里注意,如果你要删除容器重新挂载的话,请提前备份 mysql 数据,不然你就属于删库了
这里注意,如果你要删除容器重新挂载的话,请提前备份 mysql 数据,不然你就属于删库了
这里注意,如果你要删除容器重新挂载的话,请提前备份 mysql 数据,不然你就属于删库了
重要的话说三遍

在配置文件 /etc/mysql/mysql.conf.d/mysqld.cnf 中添加

performance_schema_max_table_instances=400
table_definition_cache=400
table_open_cache=256
# 从容器中复制到服务器
docker cp mysql:/etc/mysql/mysql.conf.d/mysqld.cnf /dockerData/mysql
# 从服务器复制到容器
docker cp /dockerData/mysql/mysqld.cnf mysql:/etc/mysql/mysql.conf.d/mysqld.cnf

改完之后记得重启 mysql,docker restart mysql

启用 lute

此内容适用于 solo3.6.5+

  • 启动 Lute 参考 Lute HTTP 使用指南
  • 在 solo 启动参数末尾追加 --lute_http=http://127.0.0.1:8249/--lute_http=http://localhost:8249/--lute_http=
    solo 成功启动后在终端输入 docker logs solo,日志显示有 luteAvailable=true 即表示启用 lute 成功
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1434 引用 • 10054 回帖 • 489 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    491 引用 • 917 回帖 • 4 关注
38 引用
Solo 用户指南 重启后报错:Please upgrade to v3.0.0 first 使用 docker+nginx+mysql+solo 搭建个人博客 solo 用 docker 安装,并用 nginx 配置 https 教程 基于 Solo 通过阿里云服务器搭建个人博客 solo 搭建后访问域名报错 404,怎么搞? Nginx 入门学习记录(一) [markdown-http] is not available docker 启动 solo 并用 nginx 反向代理 从零开始搭建 solo 个人博客系统 2019 年 11 月 17 日深夜有感 总算搞定了 SOLO! 个人 solo 博客搭建 华为云搭建个人博客案例 请问 docker exec -it 执行报错怎么搞 如何导入旧 solo 博客的数据到新 solo 博客中呢? docker-compose 部署 Solo 博客的详细介绍 怎么从 tomcat 部署升级到 docker-compose 部署 Solo docker 安装 solo 博客后报 Latke 配置错误 Docker 重启 MySQL 数据丢失怎么解决? solo 刚装完可以正常访问,过几个小时样式突然全变了 关于 Solo 安装后的问题 新手请教一下,安装完 solo 切换了几次皮肤后就出问题了 寻找学习博客 Lute HTTP 使用指南 大神们有人知道怎么建立博客系统的吗 [markdown-http] is not available 云服务器搭建完成 输入网址 网页出现这样是怎么回事? Solo 挂载皮肤后 docker 启动 网站 503 Solo 挂载皮肤后 docker 启动 网站 503 请浏览 Latke 配置剖析 以解决该问题。 怎么使用 docker 部署 solo? Solo 用户指南 solo 搭建出现一个小问题 docker 部署 solo 失败
3 操作
InkDP 在 2020-04-17 11:32:47 更新了该帖
InkDP 在 2020-03-27 17:43:06 更新了该帖
InkDP 在 2019-11-21 10:03:23 更新了该帖

相关帖子

优质回帖
  • csfwff 2

    😒 我这是躺着也中枪,反面教材
    另外,步骤 7 中 http 那里有别字,步骤 8 随便建一个 也是别字

  • csfwff 1

    😂 正好看到了而已

  • MoonlightSurfing 1

    安装 mysql 后:使用

    docker exec -
    

    无法进入 mysql
    我用的是

    docker exec -it mysql bash
    

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • hubowestlife 14 评论

    大佬,我有疑问:
    1.nginx 这里你开始写的所有的 HTTP 请求都转到 HTTPS(80--->443),然后你用的主页文件是自定义的测试页面,这没问题。
    问题来了,然后又加了 nginx 反向代理到 solo 的 8080 端口,然后就莫名其妙的可以 8080 转到 443 了?
    请问 8080 端口的 http 请求怎么转到 443 端口的?

    1 回复
    8080 到 443 是重定向,就相当于你访问 https://www.jinjianh.com 实际上访问的是 http://www.jinjianh.com:8080,然后访问 80 会转到 443
    InkDP
    @InkDP 8080 重定向到 443?那不应该是 在 https 的 server 内容里下的 lacation 里面加 proxy_pass http://XXXX:8080,所以这是 https 有转到 http,这个 https 有何意义呢
    hubowestlife
    @InkDP 你访问 https://www.jinjianh.com 实际上访问的是 http://www.jinjianh.com:8080,那不应该是 在 https 的 server 内容里下的 location 里面加 proxy_pass http://XXXX:8080 吗
    hubowestlife
    https 是为保证客户端与服务端之间通信的安全而设计的。内部的两个端口的无加密访问并不会被窃取,除非服务器里有木马。
    adlered
    大部分通过 Nginx 进行反向代理的服务器,内部的几个 WEB 服务都是直接走 http 的,端口对外访问通过防护墙关闭就可以了。
    adlered
    不过是包装的层数不一样,最后实现客户端 https 访问,这个是最终目的。
    adlered
    nginx 支持直接反向代理 http 服务器,再转发为 https 接口,请问这有什么不妥吗?
    adlered
    @AdlerED 没有说 80 到 443 重定向有什么问题,所以最终的是,客户端--> 服务端 80 端口---》服务端 443---》服务端 8080 这个一个逻辑是吗
    hubowestlife
    另外,看到你也发了同类型的帖子,请不要忘记初心,本质是为了帮助各位新手解决问题。通过 Nginx 可以在未来有更好的扩展性,我站也采用了 Nginx 进行反代 https。
    adlered
    你的理解有误,nginx 同时有 80 和 443 端口,所以应该是 用户->Nginx(443/80)->Docker(8080)
    adlered
    @AdlerED 是的,我的是自己搭建的是时候给自己做的一个笔记
    hubowestlife
    当然了,只开启 Nginx 的 443 端口更好,强制 https。这样的话访问步骤就变成了 用户->Nginx(443)->Docker(8080)
    adlered
    @AdlerED 谢谢大佬
    hubowestlife
  • 其他回帖
  • RookieLee

    执行以下命令:

    docker run -d -p 80:80 --name nginx

    -v /dockerData/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
    -v /dockerData/nginx/conf/conf.d:/etc/nginx/conf.d
    -v /dockerData/nginx/www:/usr/share/nginx/html
    -v /dockerData/nginx/logs:/var/log/nginx nginx

    报错:

    /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "container init exited prematurely".

    尝试更新了 yu update,但是没用,求教

  • yangkun19921001
    [root@iZm5ednzb8iuguajg62vwzZ ~]# sudo docker logs -f -t --tail 30 solo
    2019-11-08T15:55:22.301347000Z [INFO ]-[2019-11-08 23:55:22]-[org.b3log.solo.SoloServletListener:99]: Solo is booting [ver=3.6.6, servletContainer=jetty/9.4.12.v20180830, os=Linux, isDocker=true, luteAvailable=false, pid=1, runtimeDatabase=MYSQL, runtimeMode=PRODUCTION, jdbc.username=root, jdbc.URL=jdbc:mysql://127.0.0.1:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC]
    2019-11-08T15:55:22.323325000Z [INFO ]-[2019-11-08 23:55:22]-[com.zaxxer.hikari.HikariDataSource:110]: HikariPool-1 - Starting...
    2019-11-08T15:55:22.692596000Z [INFO ]-[2019-11-08 23:55:22]-[com.zaxxer.hikari.HikariDataSource:123]: HikariPool-1 - Start completed.
    2019-11-08T15:55:22.746529000Z [INFO ]-[2019-11-08 23:55:22]-[org.b3log.solo.service.InitService:191]: It's your first time setup Solo, initialize tables in database [MYSQL]
    2019-11-08T15:55:23.202384000Z [WARN ]-[2019-11-08 23:55:23]-[org.b3log.solo.service.InitService:161]: Solo has not been initialized, please open your browser to init Solo
    
    
    

    报错了

    1 回复
  • 查看全部回帖