ubuntu without root
$ sudo apt -y update
$ sudo apt-get -y upgrade
$ sudo apt -y install postgresql postgresql-contrib
$ /usr/lib/postgresql/10/bin/postgres -V
postgres (PostgreSQL) 10.8 (Ubuntu 10.8-0ubuntu0.18.04.1)
psql -h HOSTABC -U USERABC -d DATABASE_NAME -a -f schema.sql
$ sudo apt -y install nginx
$ nginx -v
nginx version: nginx/1.14.0 (Ubuntu)
$ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt-get -y install nodejs
$ node -v
v12.3.1
$ npm -v
6.9.0
$ sudo mkdir -p /data/tmp
$ cd /data/tmp
$ sudo wget https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
$ sudo tar -zxvf go1.12.5.linux-amd64.tar.gz
$ sudo mv go /usr/local
$ sudo vim /etc/profile
copy follow content into the file
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
then load the profile
$ source /etc/profile
now check golang
$ go version
go version go1.12.5 linux/amd64
$ go get github.com/MixinNetwork/supergroup.mixin.one
package github.com/MixinNetwork/supergroup.mixin.one/config: cannot find package "github.com/MixinNetwork/supergroup.mixin.one/config" in any of:
/usr/local/go/src/github.com/MixinNetwork/supergroup.mixin.one/config (from $GOROOT)
/home/ubuntu/go/src/github.com/MixinNetwork/supergroup.mixin.one/config (from $GOPATH)
you need to cancel the operation because some folder is missing. now need to create config folder and prepare a config.go file
$ cd $GOPATH/src/github.com/MixinNetwork/supergroup.mixin.one
$ mkdir config
$ cp config.gocfg config/config.go
now need to edit config.go file
package config
const (
Name = "YOUR-GROUP-NAME"
Environment = "Your Environment like production, development or test"
BuildVersion = "BUILD_VERSION"
HTTPListenPort = 7001 // HTTP Port
HTTPResourceHost = "https://group.test.com" // 大群的网址
DetectImageEnabled = false
DetectLinkEnabled = false
)
const (
DatebaseUser = "Your-Database-User"
DatabasePassword = "Your-Database-Password"
DatabaseHost = "Your-Database-Host"
DatabasePort = "Your-Database-Port"
DatabaseName = "Your-Database-Name"
)
const (
// 用什么 token 支付入群费,默认 XIN, 其它的资产可以在这里找到 https://mixin.one/snapshots
PaymentAssetId = "c94ac88f-4671-3976-b60a-09064f1811e8"
// 设置成 "0", 所有人都可以加入
PaymentAmount = "0"
)
const (
MessageShardModifier = "SHARD"
MessageShardSize = 8 // 多少个 Goroutine 发送消息,开始可以小一些,比如 8
)
const (
WelcomeMessage = "欢迎加入 XXX 中文群"
GroupRedPacket = "中文群红包"
GroupRedPacketShortDesc = "来自无名氏的红包"
GroupRedPacketDesc = "来自 %s 的红包"
GroupOpenedRedPacket = "%s 打开了你的红包"
MessageTipsGuest = "您需要先点击机器图标授权。"
MessageTipsJoin = "%s 加入了群组"
MessageTipsHelp = "您需要先加入群组才能发消息。"
MessageTipsHelpBtn = "点击加入群组"
MessageTipsUnsubscribe = "您已经取消了本群的消息订阅, 无法发送或者接收消息。"
// commands
MessageCommandsInfo = "/INFO"
MessageCommandsInfoResp = "当前订阅人数: %d"
)
// 管理员列表,可以踢人,拉入黑名单
var Operators = map[string]bool{
"xxxxxxxx": true,
"xxxxxxxx": true,
}
// 参考 https://steemit.com/cn/@over140/45sh3k-mixin-messenger
const (
ClientId = "xxxxxxxx"
ClientSecret = "xxxxxxxx"
SessionAssetPIN = "xxxxxxxx"
PinToken = "xxxxxxxx"
SessionId = "xxxxxxxx"
SessionKey = `-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----`
)
Now we can compile again
$ cd ~
$ go get github.com/MixinNetwork/supergroup.mixin.one
$ cd $GOPATH/src/github.com/MixinNetwork/supergroup.mixin.one
$ go build
$ ls supergroup.mixin.one
supergroup.mixin.one
Now you can see the compiled program.
$ cd web
$ vim web/webpack.config.js
fill content
const webRoot = function (env) {
if (env === 'production') {
return 'https://group.test.com';
} else {
return 'https://group.test.com';
}
};
const apiRoot = function (env) {
if (env === 'production') {
return 'https://api.test.com';
} else {
return 'http://127.0.0.1:7001';
}
};
const clientId = function (env) {
if (env === 'production') {
return 'xxxxxxxx';
} else {
return 'xxxxxxxx';
}
};
plugins: [
new webpack.DefinePlugin({
PRODUCTION: (process.env.NODE_ENV === 'production'),
WEB_ROOT: JSON.stringify(webRoot(process.env.NODE_ENV)),
API_ROOT: JSON.stringify(apiRoot(process.env.NODE_ENV)),
CLIENT_ID: JSON.stringify(clientId(process.env.NODE_ENV)),
//将「Mixin 中文群」替换为您的群名称
APP_NAME: JSON.stringify('Mixin 中文群'),
LOCALE: JSON.stringify('zh-CN')
}),
$ cd $GOPATH/src/github.com/MixinNetwork/supergroup.mixin.one/web
$ npm install
...........
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
added 2059 packages from 1262 contributors and audited 30549 packages in 41.938s
found 24 vulnerabilities (12 low, 12 high)
run `npm audit fix` to fix them, or `npm audit` for details
$ npm run dist
......
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/lib/loader.js!src/packet/index.scss:
Entrypoint undefined = extract-text-webpack-plugin-output-filename
[0] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./src/packet/index.scss 7.14 KiB {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/lib/loader.js!src/user/index.scss:
Entrypoint undefined = extract-text-webpack-plugin-output-filename
[0] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./src/user/index.scss 2.39 KiB {0} [built]
+ 1 hidden module
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[3] ./node_modules/html-webpack-plugin/lib/loader.js!./src/layout.html 986 bytes {0} [built]
[20] (webpack)/buildin/global.js 472 bytes {0} [built]
+ 19 hidden modules
Child webapp-webpack-plugin:
1 asset
Entrypoint launcher.png = 54b20edabb93d5f45cf9
[0] ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"/home/ubuntu/go/src/github.com/MixinNetwork/supergroup.mixin.one/web/node_modules/.cache/webapp-webpack-plugin"}!./node_modules/webapp-webpack-plugin/src/loader.js?{"prefix":"icons-[hash]-","options":{"appName":"Mixin","appDescription":"","version":"0.0.1","developerName":"Cedric Fung"},"path":"/assets/"}!./src/launcher.png 4.7 MiB {0} [built]
mode the compile folder www folder
$ sudo mkdir /var/www/test
$ sudo mv dist /var/www/test
$ sudo chown www-data:www-data -R /var/www/
$ sudo vim tron.msgspg.mixin.dev.conf
server {
listen 80;
server_name tron.msgspg.mixin.dev;
root /var/www/test/dist;
index index.html index.htm;
charset utf-8;
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_types
application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
location ~* ^/assets(.*)$ {
try_files $1 =404;
}
location / {
try_files /index.html =404;
}
$ sudo vim tronapi.msgspg.mixin.dev.conf
upstream test {
server 127.0.0.1:7001 fail_timeout=0;
}
server {
listen 80;
server_name tronapi.msgspg.mixin.dev;
index index.html index.htm;
charset utf-8;
gzip on;
gzip_comp_level 5;
gzip_proxied any;
gzip_types *;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X_FORWARDED_PROTO $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
client_max_body_size 1M;
proxy_pass http://test;
}
}
verify ngix config
$ sudo /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
restart ngix service
$ sudo systemctl restart nginx
$ cd /etc/systemd/system
$ touch test.api.service
$ touch test.message.service
the content is of test.api.service is
[Unit]
Description=Group API Daemon
After=network.target
[Service]
User=ubuntu
Type=simple
ExecStart=/home/ubuntu/go/src/github.com/MixinNetwork/supergroup.mixin.one/supergroup.mixin.one
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
the content of test.message.service is
[Unit]
Description=Group Message Daemon
After=network.target
[Service]
User=ubuntu
Type=simple
ExecStart=/home/ubuntu/go/src/github.com/MixinNetwork/supergroup.mixin.one/supergroup.mixin.one -service message
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Now start the two service
$ sudo systemctl restart test.api.service
$ sudo systemctl restart test.message.service
Now let's test the system
$ curl -i 127.0.0.1:7001/_hc
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type,Authorization,Mixin-Conversation-ID
Access-Control-Allow-Methods: OPTIONS,GET,POST,DELETE
Access-Control-Allow-Origin:
Access-Control-Max-Age: 600
Content-Type: application/json; charset=UTF-8
X-Build-Info: BUILD_VERSION-go1.12.5
X-Request-Id: 3C7F1104-2180-47A9-8F48-8C871D88CF92
X-Runtime: 0.000078
Date: Sun, 26 May 2019 15:06:32 GMT
Content-Length: 2
The bot worked.
To install SSL, you need to change url from http to https in config.go and web/webpack.config.js and compile them again.
remove the file in www folder
cd /www/test/
sudo rm -rf *
and deploy again
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot python-certbot-nginx
$ sudo certbot --nginx certonly
put two conf file in /etc/nginx/conf.d folder tron.msgspb.dev.conf
server {
listen 80;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/tron.msgspg.mixin.dev/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tron.msgspg.mixin.dev/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name tron.msgspg.mixin.dev;
root /var/www/test/dist;
index index.html index.htm;
charset utf-8;
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_types
application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
location ~* ^/assets(.*)$ {
try_files $1 =404;
}
location / {
try_files /index.html =404;
}
}
tronapi.msgspb.dev.conf
upstream test {
server 127.0.0.1:7001 fail_timeout=0;
}
server {
listen 80;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/tronapi.msgspg.mixin.dev/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tronapi.msgspg.mixin.dev/privkey.pem;
server_name tronapi.msgspg.mixin.dev;
index index.html index.htm;
charset utf-8;
gzip on;
gzip_comp_level 5;
gzip_proxied any;
gzip_types *;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X_FORWARDED_PROTO $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
client_max_body_size 1M;
proxy_pass http://test;
}
}
check nginx