使用 docker-compose 启动 solo(一键式)

本贴最后更新于 1938 天前,其中的信息可能已经东海扬尘

使用 docker-compose 启动 solo

0. 前言

记:2019-08-01 我成功的将我 wordpress 的博客给搞坏了(其实主要是插件与主题不兼容的问题、插件 WP.editor 与主题 Asky,在开启 WP.editor 的兼容模式之后,markdown 代码区块显示出现问题、关闭兼容模式之后主题功能加载异常、emmmm 心塞了)、于是想起以前看到的 solo 这个平台、于是就尝试着迁移过来、多亏我有着保存 md 源文件的习惯、所以在稍加修饰之后就可以直接导入到 solo 内。

1. 启动 solo

因为了平时为了备份与迁移方便、所以我的博客大部分都是直接用 docker 启动的,所以就尝试着使用 docker 启动 solo、因为我对 java 一窍不通所以在看 GitHub 上提供的启动参数的时候、确实是一脸懵逼的。

0. 官方 docker 容器文档

  1. 使用 MySQL
# 先手动建库(库名 solo,字符集使用 utf8mb4,排序规则 utf8mb4_general_ci),然后启动容器:

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" \
    b3log/solo --listen_port=8080 --server_scheme=http --server_host=localhost --server_port=
为了简单,使用了主机网络模式来连接主机上的 MySQL。
  1. 使用 H2 Database
docker run --detach --name solo --volume ~/solo_h2/:/opt/solo/h2/ --publish 8080:8080 \
    --env RUNTIME_DB="H2" \
    --env JDBC_USERNAME="root" \
    --env JDBC_PASSWORD="123456" \
    --env JDBC_DRIVER="org.h2.Driver" \
    --env JDBC_URL="jdbc:h2:/opt/solo/h2/db;MODE=MYSQL" \
    b3log/solo --listen_port=8080 --server_scheme=http --server_host=localhost --server_port=

1. 分析官方文档

  1. 官方文档所说为先手动建库、那么如不建库那么会出现什么情况呢?

官方推荐 docker-compose.yaml 如下,可以看出其并没有在容器初始化的时候进行数据库初始化、符合我们的需求

version: "2"
services:
  mysql:
    container_name: mysql
    image: mysql:5.5.60
    restart: always
    ports:
      - "6603:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "adminadmin"
    command: --max_allowed_packet=32505856      
  solo:
    container_name: solo
    image: b3log/solo:latest
    restart: always
    ports:
      - "8080:8080"
    environment:
      RUNTIME_DB: "MYSQL"
      JDBC_USERNAME: "root"
      JDBC_PASSWORD: "adminadmin"
      JDBC_DRIVER: "com.mysql.jdbc.Driver"
      JDBC_URL: "jdbc:mysql://mysql:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC"
    command: --listen_port=8080 --server_scheme=http --server_host=(你的域名) --server_port=

  1. 启动测试:
docker-compose up
# 可以在日志中看到 solo 前端找不到 solo 这个数据库、所以我们需要事先新建好数据库

2. 改造官方 docker-compsoe 文件

  1. 查看 docker hub MySQL 镜像介绍 地址 🔗

从下面我们可以看到、官方提供的镜像是支持通过环境变量在启动的时候新建数据库、以及新建用户和设置密码的。

2019-08-02-solo-docker-compose-1.png

  1. 根据文档进行改造
version: "2"
services:
  mysql:
    container_name: mysql
    image: mysql:5.5.60
    restart: always
    ports:
      - "6603:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "adminadmin"
      MYSQL_USER: "solo"
      MYSQL_DATABASE: "solo"
      MYSQL_PASSWORD: "solo"
    command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
  solo:
    container_name: solo
    image: b3log/solo:latest
    restart: always
    ports:
      - "8080:8080"
    environment:
      RUNTIME_DB: "MYSQL"
      JDBC_USERNAME: "root"
      JDBC_PASSWORD: "adminadmin"
      JDBC_DRIVER: "com.mysql.jdbc.Driver"
      JDBC_URL: "jdbc:mysql://mysql:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC"
    command: --listen_port=8080 --server_scheme=http --server_host=(你的域名) --server_port=

  1. 启动测试
docker-compose up
# 可以在日志中看到 solo 正常运行等待初始化

solo     | [WARN ]-[2019-08-02 11:01:35]-[org.b3log.solo.service.InitService:161]: Solo has not been initialized, please open your browser to init Solo

2. 添加 nginx 反向代理

  1. docker-compsoe.yaml
version: "2"
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - "mysql"
    volumes:
      # 虚拟服务器配置文件路径
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      # nginx 主配置文件
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
      # 日志路径
      - ./nginx/log:/www/wwwlogs:rw
      # ssl 证书路径
      - ./nginx/ssl:/var/www/ssl:rw
    container_name: "solo-nginx"

  mysql:
    image: mysql:5.5.60
    restart: always
    expose:
      - "3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "adminadmin"
      MYSQL_USER: "solo"
      MYSQL_DATABASE: "solo"
      MYSQL_PASSWORD: "solo"
    command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    container_name: "solo-mysql"

  solo:
    image: b3log/solo:latest
    restart: always
    expose:
      - "8080"
    depends_on:
      - "mysql"
    links:
      - "mysql:mysql"
    environment:
      RUNTIME_DB: "MYSQL"
      JDBC_USERNAME: "solo"
      JDBC_PASSWORD: "solo"
      JDBC_DRIVER: "com.mysql.jdbc.Driver"
      JDBC_URL: "jdbc:mysql://mysql:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC"
    command: --listen_port=8080 --server_scheme=https --server_host=expoli.tech --server_port=
    container_name: solo

  1. nginx 主配置文件 nginx.conf

参考我的这篇文档:nginx 主配置文件 nginx.conf 学习

user www-data;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 100000;

events {
    worker_connections 2048;
    multi_accept on;
    use epoll;
}

http {
    server_tokens off;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    access_log off;
    error_log /var/log/nginx/error.log crit;

    keepalive_timeout 10;
    client_header_timeout 10;
    client_body_timeout 10;
    reset_timedout_connection on;
    send_timeout 10;

    limit_conn_zone $binary_remote_addr zone=addr:5m;
    limit_conn addr 100;

    include /etc/nginx/mime.types;
    default_type text/html;
    charset UTF-8;

    gzip on;
    gzip_disable "msie6";
    gzip_proxied any;
    gzip_min_length 1000;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    open_file_cache max=100000 inactive=20s; 
    open_file_cache_valid 30s; 
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
  1. nginx 反向代理配置

参考我的这篇文档:nginx+wordpress-docker 镜像获取真实 IP

server
{
    listen 80;
    listen 443 ssl http2;
    server_name expoli.tech;
    
    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #HTTP_TO_HTTPS_START
    # if ($server_port !~ 443){
    #     rewrite ^(/.*)$ https://$host$1 permanent;
    # }

    #HTTP_TO_HTTPS_END
    ssl_certificate         /var/www/ssl/www.expoli.tech_nginx/www.expoli.tech.pem;
    ssl_certificate_key     /var/www/ssl/www.expoli.tech_nginx/www.expoli.tech.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497  https://$host$request_uri;

    #SSL-END

    location / {
        # 保证获取到真实IP
        proxy_set_header X-Real-IP $remote_addr;
        # 真实端口号
        proxy_set_header X-Real-Port $remote_port;
        # X-Forwarded-For 是一个 HTTP 扩展头部。
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 在多级代理的情况下,记录每次代理之前的客户端真实ip 
        proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
        # 获取到真实协议
        proxy_set_header X-Forwarded-Proto $scheme;
        # 真实主机名
        proxy_set_header Host $host;
        # 设置变量
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://solo:8080;
        proxy_redirect default;

        # Socket.IO Support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    
    access_log on;
    access_log  /www/wwwlogs/expoli.tech.log compression;
    error_log  /www/wwwlogs/expoli.tech.error.log;
}

3. 优化 docker-compose 配置文件

  1. 将环境变量由 docker-compose 中转移到隐藏文件中
  2. 为其指定现有 docker-network
  3. 挂载出 markdowns 方便进行数据导入与迁移(博客初始化之后、将包含 markdown 文件的文件夹放入即可、只有存有 md 文件、删库什么的也不怕了)

docker-compose.yaml

version: "2"
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - "mysql"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf/proxy.conf:/etc/nginx/proxy.conf:ro
      - ./nginx/log:/www/wwwlogs:rw
      - ./nginx/ssl:/var/www/ssl:rw
    container_name: "solo-nginx"

  mysql:
    image: mysql:5.5.60
    restart: always
    expose:
      - "3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
    env_file:
      - ./.mysql.env
    command: --max_allowed_packet=32505856 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    container_name: "solo-mysql"

  solo:
    image: b3log/solo:latest
    restart: always
    expose:
      - "8080"
    depends_on:
      - "mysql"
    links:
      - "mysql:mysql"
    volumes:
      - ./web/markdowns:/opt/solo/markdowns:rw
    env_file:
      - ./.solo.env
    command: --listen_port=8080 --server_scheme=https --server_host=注释:(改为你自己的域名) --server_port=
    container_name: solo

networks: 
  default:
    external:
      name: expoli_default_net

.mysql.env

MYSQL_ROOT_PASSWORD=adminadmin
MYSQL_USER=solo
MYSQL_DATABASE=solo
MYSQL_PASSWORD=solo

.solo.env

RUNTIME_DB=MYSQL
JDBC_USERNAME=solo
JDBC_PASSWORD=solo
JDBC_DRIVER=com.mysql.jdbc.Driver
JDBC_URL=jdbc:mysql://mysql:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC

🆗 配置完成、尽情享受 docker 的便利把!

  • Solo

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

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

    1434 引用 • 10054 回帖 • 490 关注
  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • ethan12871

    image.png
    大佬这个报错了啥情况

    1 回复
  • expoli
    作者

    不好意思刚看到、看报错信息的话是因为你把一个目录当成一个文件夹向容器内挂载了

    .../conf/nginx.conf it's not a dir

  • expoli
    作者

    报错信息挺详细的:are you mount a dir on to a file😄 ,你检查一下你的 docker-compose.yaml,相应的文件挂载的地方的写法这相应的宿主机有没有相应的文件。

    如果宿主机是个目录,不要忘了建立相互的文件,比如 Nginx.conf 是给 Nginx 容器使用的,提供相应的 solo 容器的反向代理访问,文章里都有写,可以自己再仔细看一下。

    1 回复
  • ethan12871

    恩那就是这个配置教程哪里错了,我原模原样复制的,谢谢你

  • someone
    作者

    我看了一下、应该是在你对应的目录下面没有相应的文件、于是 docker 就按照相应的路径生成了对应的一个文件夹。你可以将前面的 nginx 配置文件在相应的文件夹中创建好再启用就没问题了。👍 加油!祝好哈!