Browse Source

docker stack commands

production_deployment
voje 2 years ago
parent
commit
155c0b2c3d
  1. 9
      Makefile
  2. 42
      README.md
  3. 6
      dockerfiles/database/mongodb-stack.yml
  4. 19
      nginx.conf
  5. 36
      production.yaml
  6. 5
      src/backend_flask/conf_files/prod_conf.yaml
  7. 2
      src/backend_flask/db_config.py
  8. 2
      src/backend_flask/entrypoint.sh
  9. 2
      src/frontend_vue/config/config.json
  10. 2
      src/frontend_vue/config/config_prod.json
  11. 1
      src/frontend_vue/dist_bkp/index.html
  12. 10
      src/frontend_vue/dist_bkp/static/css/app.05a420a551b5bded5dfec6b370d3edca.css
  13. 1
      src/frontend_vue/dist_bkp/static/css/app.05a420a551b5bded5dfec6b370d3edca.css.map
  14. 2
      src/frontend_vue/dist_bkp/static/js/app.8538f7133303d3e391b2.js
  15. 1
      src/frontend_vue/dist_bkp/static/js/app.8538f7133303d3e391b2.js.map
  16. 2
      src/frontend_vue/dist_bkp/static/js/manifest.2ae2e69a05c33dfc65f8.js
  17. 1
      src/frontend_vue/dist_bkp/static/js/manifest.2ae2e69a05c33dfc65f8.js.map
  18. 55
      src/frontend_vue/dist_bkp/static/js/vendor.5d3d2fd333c62579d227.js
  19. 1
      src/frontend_vue/dist_bkp/static/js/vendor.5d3d2fd333c62579d227.js.map
  20. 2
      src/frontend_vue/ops_scripts/prod.sh

9
Makefile

@ -105,7 +105,7 @@ frontend-dev:
frontend-prod:
cd src/frontend_vue/; $(MAKE) prod
frontend-build-prod:
build-frontend-prod:
cd src/frontend_vue/; $(MAKE) build-prod
@ -133,8 +133,8 @@ backend-prod-old:
--dbuser $(DB_USR_USER) --dbpass $(DB_USR_PASS) --dbaddr $(DBADDR) \
--appindex-json $(APPINDEX_PATH)
backend-prod:
cd ./src/backend_flask; $(MAKE) run
build-backend-flask:
cd ./src/backend_flask; $(MAKE) build
## add sskj senses to db (generated with pkg/seqparser)
sskj-senses:
@ -144,3 +144,6 @@ sskj-senses:
--dbaddr $(DBADDR) \
--dbuser $(DB_USR_USER) \
--dbpass $(DB_USR_PASS)
deploy-prod-stack:
docker stack deploy -c production.yaml val

42
README.md

@ -102,3 +102,45 @@ $ make frontend-prod
```
App available on: `http://0.0.0.0:8080`.
## Production deployment
Prerequisite: machine with free ports 80 and 8084.
### Database
Either build the database from scratch (lenghty process) using above instructions or just migrate the database from the faculty server (recommended).
TODO: build my-mongo
### Backend
Set database connection details in `/src/backend_flask/db_config.py`.
```
mongodb://valuser:valuserpass@127.0.0.1:27017/valdb
```
In the above line, replace `valuser` with the username and `valuserpass` with the password that was used to create the database tables (the values were set in the root Makefile).
You can also set the number of workers in `/src/backend_flask/entrypoint.sh`.
In line with `gunicorn -t 4 -b 127.0.0.1:8084 app:app`, edit the `-t` parameter.
Rule of thumb is 2x number of available CPU cores.
Build the backend container:
```bash
# From git root
$ make build-backend-flask
```
### Frontend
Set the server address (where backend will be runnig) in `src/frontend_vue/config/config_prod.json`.
Build the `/dist` folder that contains the static app (we will be using Nginx to serve it).
```bash
# From git root
$ make build-frontend-prod
```
All set, now run the stack.
```bash
# From git root
$ make deploy-prod-stack
```

6
dockerfiles/database/mongodb-stack.yml

@ -2,7 +2,7 @@ version: '3.1'
services:
my-mongo:
my_mongo:
image: my-mongo
restart: always
ports:
@ -13,7 +13,7 @@ services:
volumes:
- ${HOME}/mongo_container/data/:/data/db
mongo-express:
mongo_express:
image: mongo-express
restart: always
ports:
@ -23,4 +23,4 @@ services:
ME_CONFIG_BASICAUTH_PASSWORD: ${MONGOEXPRESS_PASS}
ME_CONFIG_MONGODB_ADMINUSERNAME: ${DB_ADM_USER}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${DB_ADM_PASS}
ME_CONFIG_MONGODB_SERVER: my-mongo
ME_CONFIG_MONGODB_SERVER: my_mongo

19
nginx.conf

@ -1,9 +1,22 @@
# frontend
server {
listen 80;
listen 80;
server_name _;
location / {
root /frontend_fue/dist;
index index.html index.htm;
root /srv/dist;
index index.html index.htm;
}
}
# backend
server {
listen 8084;
server_name _;
location / {
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://backend_flask:8084;
}
}

36
production.yaml

@ -7,31 +7,31 @@ services:
restart: always
# ports:
# - 27017:27017
expose: 27017
expose:
- 27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${DB_ADM_USER}
MONGO_INITDB_ROOT_PASSWORD: ${DB_ADM_PASS}
MONGO_INITDB_ROOT_USERNAME: valuser
MONGO_INITDB_ROOT_PASSWORD: valuserpass
volumes:
- ${HOME}/mongo_container/data/:/data/db
network: backend
mongo_express:
image: mongo-express
restart: always
# ports:
# - 8087:8081
# TODO comment this out
ports:
- 8087:8081
environment:
ME_CONFIG_BASICAUTH_USERNAME: ${MONGOEXPRESS_USER}
ME_CONFIG_BASICAUTH_PASSWORD: ${MONGOEXPRESS_PASS}
ME_CONFIG_MONGODB_ADMINUSERNAME: ${DB_ADM_USER}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${DB_ADM_PASS}
ME_CONFIG_MONGODB_SERVER: my-mongo
network: backend
ME_CONFIG_BASICAUTH_USERNAME: test
ME_CONFIG_BASICAUTH_PASSWORD: test
ME_CONFIG_MONGODB_ADMINUSERNAME: valadmin
ME_CONFIG_MONGODB_ADMINPASSWORD: rolercoaster
ME_CONFIG_MONGODB_SERVER: my_mongo
# backend_flask:
# image: backend-flask
# network: backend
# expose: 8084
backend_flask:
image: backend-flask
expose:
- 8084
proxy:
image: nginx
@ -39,5 +39,5 @@ services:
- 80:80
- 8084:8084
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./src/frontend_vue/dist:/frontend_vue/dist
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./src/frontend_vue/dist:/srv/dist

5
src/backend_flask/conf_files/prod_conf.yaml

@ -3,8 +3,3 @@ port: 8084
host: 0.0.0.0
logfile: "/var/log/valency_backend.log"
appindex: /project/data/appindex.json
# Same as in root Makefile
dbaddr: 0.0.0.0:27017
dbuser: valuser
dbpass: valuserpass

2
src/backend_flask/db_config.py

@ -1,2 +1,2 @@
MONGO_URI = "mongodb://valuser:valuserpass@127.0.0.1:27017/valdb"
MONGO_URI = "mongodb://valuser:valuserpass@my_mongo:27017/valdb"
MONGO_AUTH_SOURCE = 'admin'

2
src/backend_flask/entrypoint.sh

@ -5,4 +5,4 @@ pip3 install -e /project/src/pkg/valency/.
pip3 install -e /project/src/pkg/seqparser/.
cd /project/src/backend_flask
gunicorn -t 2 -b 127.0.0.1:8084 app:app
gunicorn -t 4 -b 0.0.0.0:8084 app:app

2
src/frontend_vue/config/config.json

@ -1,3 +1,3 @@
{
"api_addr": "http://193.2.76.103:8084"
"api_addr": "http://192.168.1.117:8084"
}

2
src/frontend_vue/config/config_prod.json

@ -1,3 +1,3 @@
{
"api_addr": "http://193.2.76.103:8084"
"api_addr": "http://192.168.1.117:8084"
}

1
src/frontend_vue/dist_bkp/index.html

@ -0,0 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>vue_frontend</title><link href=/static/css/app.05a420a551b5bded5dfec6b370d3edca.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.5d3d2fd333c62579d227.js></script><script type=text/javascript src=/static/js/app.8538f7133303d3e391b2.js></script></body></html>

10
src/frontend_vue/dist_bkp/static/css/app.05a420a551b5bded5dfec6b370d3edca.css
File diff suppressed because it is too large
View File

1
src/frontend_vue/dist_bkp/static/css/app.05a420a551b5bded5dfec6b370d3edca.css.map
File diff suppressed because it is too large
View File

2
src/frontend_vue/dist_bkp/static/js/app.8538f7133303d3e391b2.js
File diff suppressed because it is too large
View File

1
src/frontend_vue/dist_bkp/static/js/app.8538f7133303d3e391b2.js.map
File diff suppressed because it is too large
View File

2
src/frontend_vue/dist_bkp/static/js/manifest.2ae2e69a05c33dfc65f8.js

@ -0,0 +1,2 @@
!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a<e.length;a++)i=e[a],o[i]&&l.push(o[i][0]),o[i]=0;for(f in u)Object.prototype.hasOwnProperty.call(u,f)&&(r[f]=u[f]);for(n&&n(e,u,c);l.length;)l.shift()();if(c)for(a=0;a<c.length;a++)p=t(t.s=c[a]);return p};var e={},o={2:0};function t(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return r[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=r,t.c=e,t.d=function(r,n,e){t.o(r,n)||Object.defineProperty(r,n,{configurable:!1,enumerable:!0,get:e})},t.n=function(r){var n=r&&r.__esModule?function(){return r.default}:function(){return r};return t.d(n,"a",n),n},t.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},t.p="/",t.oe=function(r){throw console.error(r),r}}([]);
//# sourceMappingURL=manifest.2ae2e69a05c33dfc65f8.js.map

1
src/frontend_vue/dist_bkp/static/js/manifest.2ae2e69a05c33dfc65f8.js.map

@ -0,0 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap d176f5affa434246605f"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,IAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.2ae2e69a05c33dfc65f8.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap d176f5affa434246605f"],"sourceRoot":""}

55
src/frontend_vue/dist_bkp/static/js/vendor.5d3d2fd333c62579d227.js
File diff suppressed because it is too large
View File

1
src/frontend_vue/dist_bkp/static/js/vendor.5d3d2fd333c62579d227.js.map
File diff suppressed because it is too large
View File

2
src/frontend_vue/ops_scripts/prod.sh

@ -4,4 +4,4 @@ cp ./config/config_prod.json ./config/config.json
npm install
npm run build
http-server /src/dist
# http-server /src/dist
Loading…
Cancel
Save