一直用着 Microsoft 的 AppCenter.ms 服务都不错,功能强大,可是最近老是抽风,没办法,只能本身部署私有 Code Push Server了,若是直接搜索 Code Push Server
,通常获得的结果都是 https://github.com/lisong/code-push-server 这个,我安装过,不过并无实现去测试,由于发现它并无完美的实现 Code Push 的逻辑,在各类坛里面找了好几天以后,终于发现了 http://Electrode.io,Walmart Labs 的东西老是这么难发现, Hapijs
也是。java
什么是 Electrode
,你们能够直接上官方去了解,咱们只使用 Electrode OTA Server
功能,我自己就是一个长期的 HapiJS
用户,因此一看到这货,仍是很亲切的。node
nvm
是一个很不错的 Node 版本管理工具,使用下面任何一个命令安装便可,若是在安装过程当中有任何疑问,请直接自行解决 https://github.com/nvm-sh/nvm。mysql
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
或者react
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
nvm install node
这个不是必须的,可是若是只是在本地测试的话,建议安装,Electrode OTA Server
默认使用的是 Apache Cassandra
数据库,有了 Docker 以后,数据库的问题更好解决,不然须要在本机安装个 Cassandra
也是很烦人的一件事情,固然,若是不使用 Cassandra
的话,也能够直接使用 MariaDB
数据,这个下面都会说,由于个人机器配置不高,因此,最终仍是选择了 MariaDB
数据库。linux
若是你已经安装了 Docker 了,那么直接跳过这一步,若是感受没有安装过,那么继续,使用下面的命令删除全部过往的 docker
版本。android
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
安装安装 yum-utils
以提供 yum-config-manager
工具,同时,device-mapper-persistent-data
以及 lvm2
是 devicemapper
所必须的库:nginx
sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
使用下面的命令设置 stable
版本 dockergit
sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
使用下面命令安装 docker
github
sudo yum install docker-ce docker-ce-cli containerd.io
基于 docker
以后,咱们就直接安装 MariaDB
以及 Cassandra
数据库了。sql
Cassandra
docker pull cassandra
或者有一个加强版本的选择:
docker pull datastax/dse-server
两个任选一个便可
docker run --name parcmg-cassandra -p 9042:9042 -d cassandra docker container start parcmg-cassandra
MariaDB
docker pull mariadb docker run --name parcmg-mariadb -p 3306:3306 -d mariadb docker container start parcmg-mariadb
如今咱们已经有了可用的数据库服务了,接下来,部署 Electrode OTA Server
这一步就很少说了,直接在 Github 后台建立一个 App,拿到 ClientId
以及 ClientSecret
两个值,在下面会用。
Electrode OTA Server
parcmg-ota-server
项目mkdir parcmg-ota-server yarn init yarn add electrode-ota-server electrode-ota-server-dao-mariadb
config/default.json
配置文件在项目目录下面建立一个名为 config
的目录,在目录中,添加一个 default.json
的配置文件(这个是我最喜欢 HapiJS 的一点,全部东西都是配置优先。
{ "connection": { "host": "localhost", "port": 9001, "compression": false }, "server": { "app": { "electrode": true } }, "plugins": { "electrode-ota-server-dao-plugin": { "module": "electrode-ota-server-dao-mariadb", "priority": 4, "options": { "keyspace": "parcmg_ota", "contactPoints": ["localhost"], "clusterConfig": { "canRetry": true, "defaultSelector": "ORDER", "removeNodeErrorCount": 5, "restoreNodeTimeout": 0 }, "poolConfigs": [ { "host": "<%Database Host%>", "port": 3306, "dialect": "mysql", "database": "<%Database Name%>", "user": "<%Database Username%>", "password": "<%Database Password%>" } ] } }, "electrode-ota-server-fileservice-upload": { "options": { "downloadUrl": "https://<%ota.domain.com%>/storagev2/" } }, "electrode-ota-server-auth": { "options": { "strategy": { "github-oauth": { "options": { "password": "<%RandomKey%>", "isSecure": true, "location": "https://<%ota.domain.com%>", "clientId": "<%GithubClientId%>", "clientSecret": "<%GithubClientSecret%>" } }, "session": { "options": { "password": "LYG2AqpUK3L4rKQERbuyJWxCqMYh5nlF", "isSecure": true } } } } } } }
而后给 package.json
添加下面两个 script
:
{ "scripts": { "start": "NODE_ENV=production node node_modules/electrode-ota-server", "development": "NODE_ENV=development node node_modules/electrode-ota-server" } }
此时,能够直接使用 yarn development
或者 yarn start
运行了。
这里须要注意一点,若是使用 MariaDB,须要本身先创建好数据库以及数据表,
schema
保存在
https://github.com/electrode-io/electrode-ota-server/tree/master/electrode-ota-mariadb-schema/electrode-ota-db/tables 这里面,一个一个建立便可。
pm2
pm2
工具npm install -g pm2
ecosystem.config.js
文件内容以下:
module.exports = { apps: [ { name: "parcmg-ota", script: "node_modules/electrode-ota-server/index.js", env: { NODE_ENV: "production" } } ] };
在 package.json
中添加 serve
命令:
{ "scripts": { "serve": "yarn install && pm2 startOrRestart ecosystem.config.js --env production", "start": "NODE_ENV=production node node_modules/electrode-ota-server", "development": "NODE_ENV=development node node_modules/electrode-ota-server" } }
yarn serve
或者
pm2 start ecosystem.config.js --env production
vi /etc/yum.repos.d/nginx.repo
内容以下:
[nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1
而后执行下面命令安装:
yum install -y
在 /etc/nginx/conf.d
目录下新建一个虚拟主机配置文件:
vi /etc/nginx/conf.d/ota.domain.com.conf
内容以下:
upstream parcmg_ota { server 127.0.0.1:9001; keepalive 64; } server { listen 80; listen [::]:80; server_name ota.parcmg.com; return 301 https://$host$request_uri; } server { listen 443 ssl; ssl_certificate cert.d/YOUR_PEM.com.pem; ssl_certificate_key cert.d/YOUR_KEY.com.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; server_name ota.parcmg.com; charset utf-8; # Global restrictions configuration file. # Designed to be included in any server {} block. location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) location ~ /\. { deny all; } location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Nginx-Proxy true; proxy_set_header Connection ""; proxy_pass http://parcmg_ota; } }
启动 nginx
systemctl start nginx systemctl enable nginx
若是没有 SSL 证书,能够上Aliyun
或者QCloud
上面去申请免费的,固然,也能够直接使用http
协议。
牛逼的Walmart Labs 还提供了一个可视化的管理工具,咱如今就先用上,直接去 https://github.com/electrode-io/electrode-ota-desktop/releases 下载最新版本便可,打开以后,会看到登陆界面。暂时离开一下子,回到 Terminal
中去。
OTA Server
code-push
会话若是你之前已经使用了 Appcenter.ms
的服务,那么如今能够退出登陆了。
code-push logout
从新在私有 OTA
服务中注册账号:
code-push register https://ota.parcmg.com
此时会跳转到 https://ota.parcmg.com
的受权页面,在页面最下方点击 Github
完成 OAuth 受权以后,会获得一个 Access Token
,复制该 Token
,在 Terminal
中粘贴,按回车,便可登陆成功,同时,将该 Token
粘贴至 Electrode OTA Desktop
应用的登陆框的 Token
中,在服务地址中填写你的 OTA
服务地址便可完成会话登陆。
App
在 Electrode OTA Desktop
里面,建立两个新的应用,就跟使用 appcenter.ms
同样,好比:
MyApp-Android MyApp-IOS
建立成功以后,会分别生成对应的 Production
以及 Staging
Key,在接下面咱们会用到。
code push
服务迁移到本身的私有服务器打开 info.plist
文件,咱们须要修改之前的 Code Push
配置,找到:
<key>CodePushDeploymentKey</key> <string>SecrtKey-----------Here</string>
在此处,将 MyApp-IOS
的 Production
Key粘贴至此处,同时还须要添加一个配置项目:
<key>CodePushServerURL</key> <string>https://ota.parcmg.com</string>
完整配置以下:
<key>CodePushDeploymentKey</key> <string><%YourKeyHere%></string> <key>CodePushServerURL</key> <string>https://ota.parcmg.com</string>
若是你使用的不是 https
协议 ,那么还须要增长:
<dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSExceptionDomains</key> <dict> <key>ota.parcmg.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
在 MainApplication.java
文件中,找到下面这一行:
new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)
添加一个参数以下,表示我须要使用这个做为 code push
的服务。
new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG, "https://ota.parcmg.com")
大功告成了,须要测试的能够直接使用个人 ota
服务: https://ota.parcmg.com,但请不要在生产中使用,鬼知道我何时就会把这个停用了。