├── etc ├── systemd │ ├── .gitkeep │ └── system │ │ ├── eve.service │ │ ├── admin-mongo.service │ │ ├── mongo-express.service │ │ └── mongoclient.service └── nginx │ └── sites-enabled │ └── backend ├── opt ├── adminMongo │ └── config │ │ └── app.json ├── eve │ ├── app.py │ └── config.py └── mongo-express │ └── node_modules │ └── mongo-express │ └── config.default.js ├── .gitignore └── README.md /etc/systemd/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /opt/adminMongo/config/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "host": "127.0.0.1", 4 | "port": 18080, 5 | "password": "admin", 6 | "locale": "en", 7 | "context": "mongo", 8 | "monitoring": true 9 | } 10 | } -------------------------------------------------------------------------------- /etc/systemd/system/eve.service: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart=/opt/eve/venv/bin/python /opt/eve/app.py 3 | Restart=always 4 | StandardOutput=syslog 5 | StandardError=syslog 6 | SyslogIdentifier=eve 7 | User=nobody 8 | Group=nogroup 9 | #Environment= 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /etc/systemd/system/admin-mongo.service: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart=/usr/bin/node /opt/adminMongo/app.js 3 | Restart=always 4 | StandardOutput=syslog 5 | StandardError=syslog 6 | SyslogIdentifier=admin-mongo 7 | User=nobody 8 | Group=nogroup 9 | Environment=NODE_ENV=production 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /etc/systemd/system/mongo-express.service: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart=/usr/bin/node /opt/mongo-express/node_modules/mongo-express/app.js 3 | Restart=always 4 | StandardOutput=syslog 5 | StandardError=syslog 6 | SyslogIdentifier=mongo-express 7 | User=nobody 8 | Group=nogroup 9 | #Environment= 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /etc/systemd/system/mongoclient.service: -------------------------------------------------------------------------------- 1 | [Service] 2 | Restart=always 3 | StandardOutput=syslog 4 | StandardError=syslog 5 | SyslogIdentifier=mongoclient 6 | User=ty 7 | Group=ty 8 | Environment=ROOT_URL=http://localhost:3000/mongoclient 9 | WorkingDirectory=/opt/mongoclient 10 | ExecStart=/usr/local/bin/meteor --port 3000 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /opt/eve/app.py: -------------------------------------------------------------------------------- 1 | from eve import Eve 2 | from eve.auth import HMACAuth 3 | from flask import current_app as app 4 | from hashlib import sha1 5 | import hmac 6 | 7 | from config import config 8 | 9 | 10 | class HMACAuth(HMACAuth): 11 | def check_auth(self, userid, hmac_hash, headers, data, allowed_roles, 12 | resource, method): 13 | # use Eve's own db driver; no additional connections/resources are 14 | # used 15 | accounts = app.data.driver.db['accounts'] 16 | user = accounts.find_one({'userid': userid}) 17 | if user: 18 | secret_key = user['secret_key'] 19 | # in this implementation we only hash request data, ignoring the 20 | # headers. 21 | return user and \ 22 | hmac.new(str(secret_key).encode(), data, sha1).hexdigest() == \ 23 | hmac_hash 24 | 25 | 26 | app = Eve(settings=config, auth=HMACAuth) 27 | #app = Eve(settings=config) 28 | app.run() -------------------------------------------------------------------------------- /opt/eve/config.py: -------------------------------------------------------------------------------- 1 | schema = { 2 | 'uid': { 3 | 'type': 'string', 4 | 'minlength': 8, 5 | 'maxlength': 30, 6 | }, 7 | 'number': { 8 | 'type': 'string', 9 | 'minlength': 1, 10 | 'maxlength': 20, 11 | }, 12 | 'name': { 13 | 'type': 'string', 14 | 'minlength': 1, 15 | 'maxlength': 30, 16 | }, 17 | 'city': { 18 | 'type': 'string', 19 | 'minlength': 0, 20 | 'maxlength': 20, 21 | }, 22 | 'provider': { 23 | 'type': 'string', 24 | 'minlength': 0, 25 | 'maxlength': 20, 26 | }, 27 | 'province': { 28 | 'type': 'string', 29 | 'minlength': 0, 30 | 'maxlength': 20, 31 | }, 32 | 'type': { 33 | 'type': 'integer', 34 | }, 35 | 'from': { 36 | 'type': 'integer', 37 | }, 38 | 'count': { 39 | 'type': 'integer', 40 | }, 41 | } 42 | 43 | 44 | caller = { 45 | 'allow_unknown': False, 46 | 'resource_methods': ['GET', 'POST'], 47 | 'schema': schema 48 | } 49 | 50 | 51 | config = { 52 | 'MONGO_HOST': 'localhost', 53 | 'MONGO_PORT': 27017, 54 | 'MONGO_DBNAME': 'caller', 55 | 'URL_PREFIX': 'api', 56 | 'API_VERSION': 'v1', 57 | 'DEBUG': True, 58 | 'DOMAIN': {'caller': caller} 59 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # Jupyter Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | .venv/ 83 | venv/ 84 | ENV/ 85 | 86 | # Spyder project settings 87 | .spyderproject 88 | 89 | # Rope project settings 90 | .ropeproject 91 | -------------------------------------------------------------------------------- /etc/nginx/sites-enabled/backend: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen 443 ssl http2; 4 | listen 10443 ssl http2; 5 | server_name backend.example.org; 6 | 7 | ssl_certificate le/certs/backend.example.org/fullchain.pem; 8 | ssl_certificate_key le/certs/backend.example.org/privkey.pem; 9 | 10 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 11 | ssl_ciphers HIGH:!aNULL:!MD5; 12 | 13 | charset utf-8; 14 | 15 | access_log /var/log/nginx/$host.access.log; 16 | 17 | client_max_body_size 20M; 18 | 19 | root /var/www/; 20 | index index.html index.htm; 21 | 22 | if ($ssl_protocol = "") { 23 | return 301 https://$http_host$request_uri; 24 | } 25 | 26 | 27 | location / { 28 | try_files $uri $uri/ =404; 29 | } 30 | 31 | location /express { 32 | auth_basic "Authentication required"; 33 | auth_basic_user_file /etc/nginx/.dlpasswd; 34 | proxy_pass http://localhost:8081; 35 | proxy_http_version 1.1; 36 | proxy_set_header Upgrade $http_upgrade; 37 | proxy_set_header Connection 'upgrade'; 38 | proxy_set_header Host $host; 39 | proxy_cache_bypass $http_upgrade; 40 | } 41 | 42 | #error_page 404 /404.html; 43 | 44 | # redirect server error pages to the static page /50x.html 45 | # 46 | error_page 500 502 503 504 /50x.html; 47 | location = /50x.html { 48 | root /usr/share/nginx/html; 49 | } 50 | 51 | 52 | location /api/v1/ { 53 | proxy_set_header X-Real-IP $remote_addr; 54 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 55 | proxy_set_header X-NginX-Proxy true; 56 | proxy_pass http://localhost:5000/api/v1/; 57 | proxy_ssl_session_reuse off; 58 | proxy_set_header Host $http_host; 59 | proxy_redirect off; 60 | } 61 | 62 | location /mongo { 63 | auth_basic "Authentication required"; 64 | auth_basic_user_file /etc/nginx/.dlpasswd; 65 | proxy_pass http://localhost:18080/mongo; 66 | proxy_http_version 1.1; 67 | proxy_set_header Upgrade $http_upgrade; 68 | proxy_set_header Connection 'upgrade'; 69 | proxy_set_header Host $host; 70 | proxy_cache_bypass $http_upgrade; 71 | } 72 | 73 | location /mongoclient { 74 | auth_basic "Authentication required"; 75 | auth_basic_user_file /etc/nginx/.dlpasswd; 76 | proxy_pass http://localhost:3000/mongoclient; 77 | proxy_http_version 1.1; 78 | proxy_set_header Upgrade $http_upgrade; 79 | proxy_set_header Connection 'upgrade'; 80 | proxy_set_header Host $host; 81 | proxy_cache_bypass $http_upgrade; 82 | } 83 | 84 | } -------------------------------------------------------------------------------- /opt/mongo-express/node_modules/mongo-express/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongo; 4 | var url = require('url'); 5 | 6 | if (typeof process.env.MONGODB_PORT === 'string') { 7 | var mongoConnection = url.parse(process.env.MONGODB_PORT); 8 | process.env.ME_CONFIG_MONGODB_SERVER = mongoConnection.hostname; 9 | process.env.ME_CONFIG_MONGODB_PORT = mongoConnection.port; 10 | } 11 | 12 | // Accesing Bluemix variable to get MongoDB info 13 | if (process.env.VCAP_SERVICES) { 14 | var dbLabel = 'mongodb-2.4'; 15 | var env = JSON.parse(process.env.VCAP_SERVICES); 16 | if (env[dbLabel]) { 17 | mongo = env[dbLabel][0].credentials; 18 | } 19 | } else { 20 | mongo = { 21 | db: 'caller', 22 | host: 'localhost', 23 | password: '', 24 | port: 27017, 25 | ssl: false, 26 | url: 'mongodb://localhost:27017', 27 | username: '', 28 | }; 29 | } 30 | 31 | var meConfigMongodbServer = process.env.ME_CONFIG_MONGODB_SERVER ? process.env.ME_CONFIG_MONGODB_SERVER.split(',') : false; 32 | 33 | module.exports = { 34 | mongodb: { 35 | //server: mongodb hostname or IP address 36 | //for replica set, use array of string instead 37 | server: (meConfigMongodbServer.length > 1 ? meConfigMongodbServer : meConfigMongodbServer[0]) || mongo.host, 38 | port: process.env.ME_CONFIG_MONGODB_PORT || mongo.port, 39 | 40 | //ssl: connect to the server using secure SSL 41 | ssl: process.env.ME_CONFIG_MONGODB_SSL || mongo.ssl, 42 | 43 | //sslValidate: validate mongod server certificate against CA 44 | sslValidate: process.env.ME_CONFIG_MONGODB_SSLVALIDATE || true, 45 | 46 | //sslCA: array of valid CA certificates 47 | sslCA: [], 48 | 49 | //autoReconnect: automatically reconnect if connection is lost 50 | autoReconnect: true, 51 | 52 | //poolSize: size of connection pool (number of connections to use) 53 | poolSize: 4, 54 | 55 | //set admin to true if you want to turn on admin features 56 | //if admin is true, the auth list below will be ignored 57 | //if admin is true, you will need to enter an admin username/password below (if it is needed) 58 | admin: process.env.ME_CONFIG_MONGODB_ENABLE_ADMIN ? process.env.ME_CONFIG_MONGODB_ENABLE_ADMIN.toLowerCase() === 'true' : false, 59 | 60 | // >>>> If you are using regular accounts, fill out auth details in the section below 61 | // >>>> If you have admin auth, leave this section empty and skip to the next section 62 | auth: [ 63 | /* 64 | * Add the name, username, and password of the databases you want to connect to 65 | * Add as many databases as you want! 66 | */ 67 | { 68 | database: process.env.ME_CONFIG_MONGODB_AUTH_DATABASE || mongo.db, 69 | username: process.env.ME_CONFIG_MONGODB_AUTH_USERNAME || mongo.username, 70 | password: process.env.ME_CONFIG_MONGODB_AUTH_PASSWORD || mongo.password, 71 | }, 72 | ], 73 | 74 | // >>>> If you are using an admin mongodb account, or no admin account exists, fill out section below 75 | // >>>> Using an admin account allows you to view and edit all databases, and view stats 76 | 77 | //leave username and password empty if no admin account exists 78 | adminUsername: process.env.ME_CONFIG_MONGODB_ADMINUSERNAME || '', 79 | adminPassword: process.env.ME_CONFIG_MONGODB_ADMINPASSWORD || '', 80 | 81 | //whitelist: hide all databases except the ones in this list (empty list for no whitelist) 82 | whitelist: [], 83 | 84 | //blacklist: hide databases listed in the blacklist (empty list for no blacklist) 85 | blacklist: [], 86 | }, 87 | 88 | site: { 89 | // baseUrl: the URL that mongo express will be located at - Remember to add the forward slash at the start and end! 90 | // baseUrl: process.env.ME_CONFIG_SITE_BASEURL || '/', 91 | baseUrl: '/express/', 92 | cookieKeyName: 'mongo-express', 93 | cookieSecret: process.env.ME_CONFIG_SITE_COOKIESECRET || 'cookiesecret', 94 | host: process.env.VCAP_APP_HOST || 'localhost', 95 | port: process.env.VCAP_APP_PORT || 8081, 96 | requestSizeLimit: process.env.ME_CONFIG_REQUEST_SIZE || '50mb', 97 | sessionSecret: process.env.ME_CONFIG_SITE_SESSIONSECRET || 'sessionsecret', 98 | sslCert: process.env.ME_CONFIG_SITE_SSL_CRT_PATH || '', 99 | sslEnabled: process.env.ME_CONFIG_SITE_SSL_ENABLED || false, 100 | sslKey: process.env.ME_CONFIG_SITE_SSL_KEY_PATH || '', 101 | }, 102 | 103 | //set useBasicAuth to true if you want to authenticate mongo-express loggins 104 | //if admin is false, the basicAuthInfo list below will be ignored 105 | //this will be true unless ME_CONFIG_BASICAUTH_USERNAME is set and is the empty string 106 | //useBasicAuth: process.env.ME_CONFIG_BASICAUTH_USERNAME !== '', 107 | useBasicAuth: false, 108 | 109 | basicAuth: { 110 | username: process.env.ME_CONFIG_BASICAUTH_USERNAME || '', 111 | password: process.env.ME_CONFIG_BASICAUTH_PASSWORD || '', 112 | }, 113 | 114 | options: { 115 | // Display startup text on console 116 | console: true, 117 | 118 | //documentsPerPage: how many documents you want to see at once in collection view 119 | documentsPerPage: 10, 120 | 121 | //editorTheme: Name of the theme you want to use for displaying documents 122 | //See http://codemirror.net/demo/theme.html for all examples 123 | editorTheme: process.env.ME_CONFIG_OPTIONS_EDITORTHEME || 'rubyblue', 124 | 125 | // Maximum size of a single property & single row 126 | // Reduces the risk of sending a huge amount of data when viewing collections 127 | maxPropSize: (100 * 1000), // default 100KB 128 | maxRowSize: (1000 * 1000), // default 1MB 129 | 130 | //The options below aren't being used yet 131 | 132 | //cmdType: the type of command line you want mongo express to run 133 | //values: eval, subprocess 134 | // eval - uses db.eval. commands block, so only use this if you have to 135 | // subprocess - spawns a mongo command line as a subprocess and pipes output to mongo express 136 | cmdType: 'eval', 137 | 138 | //subprocessTimeout: number of seconds of non-interaction before a subprocess is shut down 139 | subprocessTimeout: 300, 140 | 141 | //readOnly: if readOnly is true, components of writing are not visible. 142 | readOnly: false, 143 | 144 | //collapsibleJSON: if set to true, jsons will be displayed collapsible 145 | collapsibleJSON: true, 146 | 147 | //collapsibleJSONDefaultUnfold: if collapsibleJSON is set to `true`, this defines default level 148 | // to which JSONs are displayed unfolded; use number or "all" to unfold all levels 149 | collapsibleJSONDefaultUnfold: 1, 150 | 151 | //gridFSEnabled: if gridFSEnabled is set to 'true', you will be able to manage uploaded files ( ak. grids, gridFS ) 152 | gridFSEnabled: false, 153 | 154 | // logger: this object will be used to initialize router logger (morgan) 155 | logger: {}, 156 | }, 157 | 158 | // Specify the default keyname that should be picked from a document to display in collections list. 159 | // Keynames can be specified for every database and collection. 160 | // If no keyname is specified, it defaults to '_id', which is a mandatory field. 161 | // For Example : 162 | // defaultKeyNames{ 163 | // "world_db":{ //Database Name 164 | // "continent":"cont_name", // collection:field 165 | // "country":"country_name", 166 | // "city":"name" 167 | // } 168 | // } 169 | defaultKeyNames: { 170 | 171 | }, 172 | }; 173 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 使用 mongodb python-eve 搭建类似 leancloud 的后端数据存储服务 2 | 3 | 4 | ## 系统环境 5 | 6 | ubuntu 16.04 64 bit 7 | 8 | 安装一些基础包 9 | 10 | ```shell 11 | apt-get update 12 | apt-get upgrade -y 13 | apt-get install -y sudo curl wget zip unzip vim virtualenv apache2-utils 14 | ``` 15 | 16 | ## 安装 mongodb 17 | 18 | 参考 [https://docs.mongodb.com/manual/administration/install-on-linux/](https://docs.mongodb.com/manual/administration/install-on-linux/) 19 | 20 | 21 | ```shell 22 | sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 23 | echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list 24 | sudo apt-get update 25 | sudo apt-get install -y mongodb-org 26 | 27 | systemctl start mongod 28 | systemctl enable mongod 29 | ``` 30 | 31 | ## 安装 python-eve 32 | 33 | 将 python-eve 安装在 `/opt/eve` 目录下 34 | 35 | ```shell 36 | mkdir -p /opt/eve && cd /opt/eve 37 | virtualenv -p python3 venv 38 | source venv/bin/activate 39 | pip install eve 40 | deactivate 41 | ``` 42 | 43 | 新建 `eve app`,也可以参考这里 [http://python-eve.org/quickstart.html](http://python-eve.org/quickstart.html) 44 | 45 | ```shell 46 | cd /opt/eve 47 | 48 | vi app.py 49 | ``` 50 | 51 | ```python 52 | from eve import Eve 53 | from flask import current_app as app 54 | 55 | 56 | test = { 57 | 'allow_unknown': True, 58 | 'resource_methods': ['GET', 'POST'] 59 | } 60 | 61 | config = { 62 | 'MONGO_HOST': 'localhost', 63 | 'MONGO_PORT': 27017, 64 | 'MONGO_DBNAME': 'test', 65 | 'URL_PREFIX': 'api', 66 | 'API_VERSION': 'v1', 67 | 'DEBUG': False, 68 | 'DOMAIN': {'test': test} 69 | } 70 | 71 | 72 | app = Eve(settings=config) 73 | app.run() 74 | ``` 75 | 76 | 另附一份我启用了 `HMAC-SHA1` 鉴权的配置, 真实环境运行时可以参考使用 [/opt/eve](https://github.com/xdtianyu/CallerBackend/tree/master/opt/eve) 77 | 78 | 79 | 运行测试 80 | 81 | ```shell 82 | /opt/eve/venv/bin/python app.py 83 | ``` 84 | 85 | 出现如下内容说明运行成功 86 | 87 | 88 | ``` 89 | * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 90 | ``` 91 | 92 | 添加 `systemd` 服务 93 | 94 | ```shell 95 | vi /etc/systemd/system/eve.service 96 | ``` 97 | 98 | ```shell 99 | [Service] 100 | ExecStart=/opt/eve/venv/bin/python /opt/eve/app.py 101 | Restart=always 102 | StandardOutput=syslog 103 | StandardError=syslog 104 | SyslogIdentifier=eve 105 | User=nobody 106 | Group=nogroup 107 | #Environment= 108 | [Install] 109 | WantedBy=multi-user.target 110 | ``` 111 | 112 | 启用 eve 服务 113 | 114 | 115 | ``` 116 | systemctl start eve 117 | systemctl enable eve 118 | ``` 119 | 120 | 可以使用 `journalctl -u eve` 命令查看服务状态 121 | 122 | 123 | ## 安装 adminMongo web 管理服务 124 | 125 | 安装 nodejs,参考 [https://nodejs.org/en/download/package-manager/](https://nodejs.org/en/download/package-manager/) 126 | 127 | ```shell 128 | curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - 129 | sudo apt-get install -y nodejs 130 | ``` 131 | 安装 `adminMongo`, 参考 [https://github.com/mrvautin/adminMongo](https://github.com/mrvautin/adminMongo) 132 | 133 | ```shell 134 | mkdir -p /opt/adminMongo && cd /opt/adminMongo 135 | npm i admin-mongo@0.0.20 136 | ``` 137 | 138 | 修改 `config/app.json` 配置文件内容为 139 | 140 | ```shell 141 | mkdir -p /opt/adminMongo/config 142 | vi /opt/adminMongo/config/app.json 143 | ``` 144 | 145 | ```json 146 | { 147 | "app": { 148 | "host": "127.0.0.1", 149 | "port": 18080, 150 | "password": "admin", 151 | "locale": "en", 152 | "context": "mongo", 153 | "monitoring": true 154 | } 155 | } 156 | ``` 157 | 158 | 启动 `adminMongo` 159 | 160 | ```shell 161 | /usr/bin/node /opt/adminMongo/app.js 162 | ``` 163 | 164 | 出现如下内容说明启动成功 165 | 166 | ``` 167 | adminMongo listening on host: http://127.0.0.1:18080/mongo 168 | ``` 169 | 170 | 添加 `systemd` 服务 171 | 172 | ``` 173 | vi /etc/systemd/system/admin-mongo.service 174 | ``` 175 | 176 | ``` 177 | [Service] 178 | ExecStart=/usr/bin/node /opt/adminMongo/app.js 179 | Restart=always 180 | StandardOutput=syslog 181 | StandardError=syslog 182 | SyslogIdentifier=admin-mongo 183 | User=nobody 184 | Group=nogroup 185 | Environment=NODE_ENV=production 186 | [Install] 187 | WantedBy=multi-user.target 188 | ``` 189 | 190 | 启用服务 191 | 192 | ``` 193 | chown -R nobody:nogroup /opt/adminMongo 194 | systemctl start admin-mongo 195 | systemctl enable admin-mongo 196 | ``` 197 | 198 | 可以使用 `journalctl -u admin-mongo` 命令查看服务状态 199 | 200 | 201 | ## 安装 mongo-express web 管理服务 202 | 203 | 参考 [https://github.com/mongo-express/mongo-express](https://github.com/mongo-express/mongo-express) 204 | 205 | ```shell 206 | mkdir -p /opt/mongo-express && cd /opt/mongo-express 207 | npm install mongo-express 208 | ``` 209 | 210 | 修改配置文件 211 | 212 | ``` 213 | vi /opt/mongo-express/node_modules/mongo-express/config.default.js 214 | ``` 215 | 216 | 查找并修改如下内容 217 | 218 | ```js 219 | mongo = { 220 | db: 'test', 221 | host: 'localhost', 222 | password: '', 223 | port: 27017, 224 | ssl: false, 225 | url: 'mongodb://localhost:27017', 226 | username: '', 227 | }; 228 | ``` 229 | 230 | ``` 231 | //baseUrl: process.env.ME_CONFIG_SITE_BASEURL || '/', 232 | baseUrl: '/express/', 233 | ``` 234 | 235 | ``` 236 | //useBasicAuth: process.env.ME_CONFIG_BASICAUTH_USERNAME !== '', 237 | useBasicAuth: false, 238 | 239 | basicAuth: { 240 | username: process.env.ME_CONFIG_BASICAUTH_USERNAME || '', 241 | password: process.env.ME_CONFIG_BASICAUTH_PASSWORD || '', 242 | }, 243 | ``` 244 | 245 | 启动 `mongo-express` 246 | 247 | ``` 248 | /usr/bin/node /opt/mongo-express/node_modules/mongo-express/app.js 249 | ``` 250 | 251 | 出现如下内容说明启动成功 252 | 253 | ``` 254 | No custom config.js found, loading config.default.js 255 | Welcome to mongo-express 256 | ------------------------ 257 | 258 | 259 | Mongo Express server listening at http://localhost:8081 260 | Database connected 261 | Connecting to test... 262 | Database test connected 263 | ``` 264 | 265 | 添加 `systemd` 服务 266 | 267 | ``` 268 | vi /etc/systemd/system/mongo-express.service 269 | ``` 270 | 271 | ``` 272 | [Service] 273 | ExecStart=/usr/bin/node /opt/mongo-express/node_modules/mongo-express/app.js 274 | Restart=always 275 | StandardOutput=syslog 276 | StandardError=syslog 277 | SyslogIdentifier=mongo-express 278 | User=nobody 279 | Group=nogroup 280 | #Environment= 281 | [Install] 282 | WantedBy=multi-user.target 283 | ``` 284 | 285 | 启动服务 286 | 287 | ``` 288 | chown -R nobody:nogroup /opt/mongo-express 289 | systemctl start mongo-express 290 | systemctl enable mongo-express 291 | ``` 292 | 293 | 可以使用 `journalctl -u mongo-express` 命令查看服务状态 294 | 295 | ## 安装 nginx 并配置 https 和代理 296 | 297 | ```shell 298 | apt install nginx-extras 299 | ``` 300 | 301 | 添加配置 302 | 303 | ``` 304 | vi /etc/nginx/sites-available/backend 305 | ``` 306 | 307 | 注意修改 `backend.example.org` 为你的域名,证书路径修改为你的路径 308 | 309 | ``` 310 | server { 311 | listen 80; 312 | listen 443 ssl http2; 313 | server_name backend.example.org; 314 | 315 | ssl_certificate le/certs/backend.example.org/fullchain.pem; 316 | ssl_certificate_key le/certs/backend.example.org/privkey.pem; 317 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 318 | ssl_ciphers HIGH:!aNULL:!MD5; 319 | charset utf-8; 320 | access_log /var/log/nginx/$host.access.log; 321 | client_max_body_size 20M; 322 | root /var/www/; 323 | index index.html index.htm; 324 | if ($ssl_protocol = "") { 325 | return 301 https://$http_host$request_uri; 326 | } 327 | location / { 328 | try_files $uri $uri/ =404; 329 | } 330 | location /express { 331 | auth_basic "Authentication required"; 332 | auth_basic_user_file /etc/nginx/.htpasswd; 333 | proxy_pass http://localhost:8081; 334 | proxy_http_version 1.1; 335 | proxy_set_header Upgrade $http_upgrade; 336 | proxy_set_header Connection 'upgrade'; 337 | proxy_set_header Host $host; 338 | proxy_cache_bypass $http_upgrade; 339 | } 340 | #error_page 404 /404.html; 341 | # redirect server error pages to the static page /50x.html 342 | # 343 | error_page 500 502 503 504 /50x.html; 344 | location = /50x.html { 345 | root /usr/share/nginx/html; 346 | } 347 | location /api/v1/ { 348 | proxy_set_header X-Real-IP $remote_addr; 349 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 350 | proxy_set_header X-NginX-Proxy true; 351 | proxy_pass http://localhost:5000/api/v1/; 352 | proxy_ssl_session_reuse off; 353 | proxy_set_header Host $http_host; 354 | proxy_redirect off; 355 | } 356 | location /mongo { 357 | auth_basic "Authentication required"; 358 | auth_basic_user_file /etc/nginx/.htpasswd; 359 | proxy_pass http://localhost:18080/mongo; 360 | proxy_http_version 1.1; 361 | proxy_set_header Upgrade $http_upgrade; 362 | proxy_set_header Connection 'upgrade'; 363 | proxy_set_header Host $host; 364 | proxy_cache_bypass $http_upgrade; 365 | } 366 | } 367 | ``` 368 | 369 | ``` 370 | cd /etc/nginx/sites-enabled/ 371 | ln -s ../sites-available/backend 372 | 373 | ``` 374 | 375 | 创建 `.htpasswd` 文件,通过 `http basic auth` 保护 web 管理终端,因为配合了 `HTTPS` 使用,所以已经足够安全。 376 | 377 | ``` 378 | cd /etc/nginx/ 379 | htpasswd -c .htpasswd YOUR_HTTP_USER 380 | ``` 381 | 382 | 使用 `nginx -t` 测试,如果出现错误,请按照提示修改 383 | 384 | 385 | 启动 nginx 服务 386 | 387 | 388 | ``` 389 | systemctl start nginx 390 | systemctl enable nginx 391 | ``` 392 | 393 | ## 安装完成 394 | 395 | 可以在浏览器打开测试 396 | 397 | `https://backend.example.org/api/v1` 是 `eve api` 路径 398 | 399 | `https://backend.example.org/mongo` 是 `adminMongo` web 管理面板 400 | 401 | `https://backend.example.org/express` 是 `mongo-express` web 管理面板 402 | 403 | 404 | `eve api` 具有较高的定制性,灵活且方便使用,可以非常轻松的实现手机终端上报数据存储功能。浏览器打开时会使用 `xml` 格式展示,可以使用 [postman](https://www.getpostman.com/) 来调试接口。 405 | 406 | 另附一个我启用 `HMAC-SHA1` 鉴权后, Android 客户端 `okhttp hmac post` 的实现 407 | 408 | [phone-number/src/main/java/org/xdty/phone/number/net/cloud/CloudHandler.java#L95](https://github.com/xdtianyu/PhoneNumber/blob/0f95cda40940055cae284498dcaf99c29bee61a6/phone-number/src/main/java/org/xdty/phone/number/net/cloud/CloudHandler.java#L95) 409 | 410 | **注意** 411 | 412 | 如果启用了 api 认证,例如 [app.py#L15](https://github.com/xdtianyu/CallerBackend/tree/master/opt/eve/app.py#L15) 请一定要在数据库中增加类似 `accounts` 这样的 `collection`,具体字段由你的配置决定。内容参考如下 413 | 414 | ``` 415 | { 416 | "userid": "6Yd5MtkpdSZcJrtEtk", 417 | "secret_key": "7dBvS2Ow3RSIr9gdAmLDCRD8EI1dbMecGTOJ" 418 | } 419 | ``` 420 | 421 | 更多关于 `python-eve` 的配置请阅读官方文档 [http://python-eve.org/quickstart.html](http://python-eve.org/quickstart.html) 422 | 423 | 安装完成后,整个系统内存仅使用 200m 左右,cpu 几乎无负载。 424 | --------------------------------------------------------------------------------