一直用着 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,但請不要在生產中使用,鬼知道我何時就會把這個停用了。