前置条件:首先你需要一台安装好Docker的Linux服务器,云服务器或者实机都可以,x86\arm不限,这部分不再赘述。

配置Docker Compose环境

Docker Compose是Docker公司推出的用于本机容器编排的工具。Docker Compose可以定义及运行多个Docker容器,非常适合组合使用多个容器进行开发的场景。

Docker Compose有两个版本,v1和v2,使用时命令形式有区别,笔者推荐采用v2版本,这里将介绍的也是v2版本的安装。但容器编排文件在两个版本使用并无差别,读者若熟悉v1版本,也可跳过本部分直接阅读编排文件。

安装Compose v2

先去此页面找到你的服务器对应系统和架构的包,右键点击它选择复制链接。以docker-compose-linux-aarch64为例,复制的链接为

https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-aarch64

登陆你的服务器,在服务器的shell中输入如下命令,命令中示例链接部分替换为前一步复制的链接:

DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-aarch64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

赋予可执行权限:

chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

// 2022.8.28更新:Compose v2已提供主流支持,现有更简便的正式安装方法,故以上标记删除线的部分已过时。安装方法以下述为准。

Docker官方已将Compose v2添加至包存储库,现在可以使用各linux发行版的包管理命令直接安装Compose v2。官方文档参考此处。以Debian系为例子,你可以使用以下命令安装:

sudo apt update
sudo apt install docker-compose-plugin

Docker Compose基本使用格式:

docker compose [options] [COMMAND] [ARGS...]

常用COMMAND:

描述字段
重新构建服务build
列出容器ps
创建和启动容器up
在容器里执行命令exec
指定一个服务容器启动数量scale
显示正在运行的容器进程top
查看服务容器的输出logs
删除容器、网络、数据卷和镜像down
停止/启动/重启服务stop/start/restart

### 加入docker用户组

虽然Compose已经安装完毕了,但还不可以直接使用。涉及unix sock操作时,docker需要使用root权限运行,如果直接:

sudo docker compose xxx

由于Compose是安装在用户目录下的CLI组件,sudo无法识别到命令。

所以为了避免使用sudo,我们需要把运行docker的用户加入docker用户组:

sudo usermod -aG docker $USER

退出终端,重新登陆后即可不使用sudo运行docker。

// 2022.8.28更新:使用Docker存储库方式安装Compose后,sudo可以正常在docker compose命令中使用,此节内容已过时。

部署Renew X

Docker Compose是按照特定yaml文件中规定的方式拉起、运行容器和服务的。

compose.yaml:

我们先在~下创建一个目录作为Renew X服务的工作空间并创建compose.yaml

mkdir ~/ms365e5renewx
cd ~/ms365e5renewx
touch compose.yaml

使用你喜欢的编辑器打开compose.yaml,按下面的示例写入(无需修改):

version: '3'
services:  
  nginx:
    image: nginx:alpine
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:rw
      - ./nginx/conf.d/:/etc/nginx/conf.d/:rw
      - ./nginx/log/:/var/log/nginx/:rw
      - ./nginx/cert/:/etc/nginx/cert/:rw
      - ./nginx/html/:/usr/share/nginx/html/:rw
    network_mode: host
  e5renewx:
    image: gladtbam/ms365_e5_renewx:latest
    restart: always
    volumes:
      - ./e5renewx/Deploy/:/renewx/Deploy/:rw
      - ./e5renewx/appdata/:/renewx/appdata/:rw
      - ./e5renewx/static/:/renewx/wwwroot/static/:rw
    ports:
      - 1066:1066

示例中使用Nginx反代Renew X,这样做的好处有很多。比如省去用户在浏览器输入端口,比如方便实现强制https访问,比如避免暴露更多端口,以及可以和同一台服务器上的其他web服务共用80\443端口等等。

文件准备

接下来我们对工作目录做一些准备:

cd ~/ms365e5renewx
mkdir -p nginx/conf.d
touch e5renewx.conf
mkdir nginx/cert
mkdir -p e5renewx/Deploy

假如我们不创建这些目录,Docker运行后也会自动创建,但自动创建的目录归属是root用户,修改和上传相应文件时麻烦一些,所以可以事先创建好。

把所用域名的pem格式证书和key上传至服务器的~/nginx/cert/目录下,再把域名的pfx证书上传到~/e5renewx/Deploy/目录下。注意,本文是共享站的部署方式,共享站必须使用全链路HTTPS部署,所以一定要有证书。免费证书的获取方式参考你的域名注册商文档。

反向代理

使用你喜爱的编辑器打开上面创建的e5renewx.conf文件,照我的示例编写(按汉字说明改):

upstream e5renewx {
    server localhost:1066;
}
server {
    listen 80;
    listen [::]:80;
    server_name 你的域名如e5renewx.curious.host;
    return 301 https://${server_name}$request_uri;
}
server {
    listen               443 ssl;
    listen               [::]:443 ssl;
    server_name          你的域名如e5renewx.curious.host;
    keepalive_timeout    1800;
    client_max_body_size 100M;
    sendfile             on;
    ssl_certificate      /etc/nginx/cert/你的pem文件名;
    ssl_certificate_key  /etc/nginx/cert/对应的key文件名;


    location /
    {
        proxy_pass https://e5renewx;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

注意,共享站要求全链路HTTPS,因此本示例中proxy_pass模块后必须对应包含https://的地址。proxy_set_header为请求头传递,以便被代理的服务器获得用户真实IP,利于站点安全审计。

Renew X配置

首先在你的PC上下载服务程序源文件。

解压后找到Deploy文件夹下的Config.xml文件进行修改。也可自行创建此文件,向其中粘贴初始内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
 <!--站点服务器基本配置-->
 <Serivce>
  <!--服务访问端口-->
  <Port>1066</Port>
  <!--管理员密码(管理员登录路由/Admin/Login) 重要:首次启动前必须更改-->
  <LoginPassword>12345678</LoginPassword>
  <!--是否启用内核多线程支持-->
  <CoreMultiThread>true</CoreMultiThread>
  <!--网站备案(选填)-->
  <ICP>
   <!--备案显示文本-->
   <Text></Text>
   <!--备案管理查询机构跳转链接-->
   <Link>https://beian.miit.gov.cn</Link>
  </ICP>
  <!--Bootstrap CDN 若要更改请务必使用[email protected]版本(选填)-->
  <CDN>
   <!--Bootstrap CSS文件CDN bootstrap.min.css-->
   <CSS>https://cdn.staticfile.org/bootstrap/5.1.3/css/bootstrap.min.css</CSS>
   <!--Bootstrap JS文件CDN bootstrap.bundle.min.js-->
   <JS>https://cdn.staticfile.org/bootstrap/5.1.3/js/bootstrap.bundle.min.js</JS>
  </CDN>
 </Serivce>
 <!--站点Kestrel服务器HTTPS配置 (只支持IIS证书类型 即PFX格式的证书)-->
 <HTTPS>
  <!--Kestrel是否启用HTTPS(SSL加密传输)-->
  <Enable>false</Enable>
  <!--SSL证书文件名 (需要将PFX格式的SSL证书放置于该配置文件的同级目录Deploy文件夹下) 如e5.sundayrx.net.pfx-->
  <!--不填则默认使用Dev localhost 本地证书-->
  <Certificate></Certificate>
  <!--SSL证书密钥(PFX证书的访问密钥)-->
  <Password></Password>
 </HTTPS>
 <!--共享站点配置,不共享可无视以下内容 (若要共享站点 请自备以下所需的配置信息 且配置中HTTPS必须启用)-->
 <ShareSite>
  <!--是否启用站点共享-->
  <Enable>false</Enable>
  <!--SMTP邮件发送支持-->
  <SMTP>
   <!--发件邮箱-->
   <Email></Email>
   <!--邮箱密钥-->
   <Password></Password>
   <!--SMTP服务器地址-->
   <Host></Host>
   <!--SMTP服务器端口-->
   <Port>587</Port>
   <!--SMTP服务器是否使用SSL传输-->
   <EnableSSL>true</EnableSSL>
  </SMTP>
  <!--第三方OAuth登录支持(至少启用以下一种OAuth否则其他用户无法注册)-->
  <OAuth>
   <!--微软登录授权-->
   <Microsoft>
    <!--是否启用该OAuth-->
    <Enable>true</Enable>
    <!--应用程序Id-->
    <ClientId></ClientId>
    <!--应用程序访问机密-->
    <ClientSecret></ClientSecret>
   </Microsoft>
   <!--GitHub登录授权-->
   <Github>
    <!--是否启用该OAuth-->
    <Enable>true</Enable>
    <!--应用程序Id-->
    <ClientId></ClientId>
    <!--应用程序访问机密-->
    <ClientSecret></ClientSecret>
   </Github>
  </OAuth>
  <!--站点系统设置-->
  <System>
   <!--站点启动后默认是否允许用户注册 建议为false-->
   <AllowRegister>false</AllowRegister>
   <!--站点启动后默认公告(换行符请使用 &#x000D;&#x000A; 进行换行)-->
   <Notice></Notice>
   <!--站点运营者-->
   <Master></Master>
   <!--站点运营者推广链接-->
   <MasterLink></MasterLink>
   <!--站点新用户默认配额数-->
   <DefaultQuota>1</DefaultQuota>
   <!--站点自动特赦时间间隔 (单位:天 至少30天)-->
   <AutoSpecialPardonInterval>30</AutoSpecialPardonInterval>
  </System>
 </ShareSite>
</Configuration>

其中管理员密码务必更改为仅你自己知道的强密码。

开放站点必须开启HTTPS:

  • Configuration.HTTPS.Enable设置为true
  • Configuration.HTTPS.Certificate设置为我们上传到~/ms365e5renewx/e5renewx/Deploy/下的PFX文件的名称(包括后缀名),
  • Configuration.HTTPS.Password设置为PFX文件的密码。
  • SMTP部分,建议准备一个空闲的Outlook个人邮箱,将邮箱、密码依次填好,SMTP服务器地址填smtp.office365.com,端口无需改动(默认587)。也可以通过远程PowerShell模块启用组织邮箱的smtp权限,使用组织邮箱发送通知,参考此教程

开放站点若要支持某种第三方注册方式(微软账户或GitHub账户),则必须在Config.xml正确配置了相应的OAuth选项。

  • Github OAuth 获取方式
    • 进入你的GitHub Profile
    • 左侧栏底部Developer Settings
    • OAuth Apps -> New Oauth App
    • 填写任意Application Name
    • Homepage URL 填写https://你的域名
    • Authorization callback URL 填写https://你的域名/signin-github
    • Register application
    • Generate a new client secret
    • Client ID填入上述Config.xml相应ClientId
    • Secret填入上述Config.xml相应ClientSecret
  • Microsoft OAuth 获取方式
    • 进入你的Azure应用注册页面
    • 新注册
    • 受支持的账户类型->任何组织目录(任何 Azure AD 目录 – 多租户)中的帐户和个人 Microsoft 帐户(例如,Skype、Xbox)
    • 重定向 URI :选择平台->Web,填入https://你的域名/signin-microsoft
    • 注册后进入应用
    • 应用->概述中的“应用程序(客户端) ID”填入Config.xml相应ClientId
    • 应用->证书和密码->新客户端密码,生成的密码记录的“值”填入Config.xml相应ClientSecret
    • 其余自定义参数释义参考服务程序作者的说明

全部填写完成后将Config.xml上传至你的服务器~/ms365e5renewx/e5renewx/Deploy/目录下。

【可选】将服务程序源文件中解压出的wwwroot文件夹,完整地上传至服务器~/ms365e5renewx/目录下,其中/wwwroot/static/Donate.html为站点捐助页面的静态网页,可由站长自行编写。

运行Renew X

compose.yaml所在目录下执行命令:

sudo docker compose up -d

首次运行要拉取镜像,可能较慢,如果网络实在不佳,请考虑使用Docker Hub的镜像源。

待服务启动后,尝试登陆自己的站点测试。如果日后需要迁移服务器,只需完整打包~/ms365e5renewx即可保证站点数据的完整性。比如笔者经常因为打折而在各家云服务商之间反复横跳,每次切换时仅仅需要把目录带到新服务器上,一个命令就可以快速重建站点。站点数据不大的情况下,甚至可以托管在GitHub仓库里进行管理同步(需要hook解决文件权限问题),这部分内容有空笔者会补充在文章里。

下线站点时,在compose.yaml所在目录使用:

sudo docker compose down

本教程示例站点,开放注册:https://e5renewx.curious.host

到此Renew X的部署教程完毕,感谢耐心阅读,祝折腾愉快。

写这篇教程是出于强迫症,如果为其他玩家提供了一点经验就再好不过了。部署站点时参考了官方教程Skyler的部署文档Gladtbam的部署文档,一并感谢。