@ -0,0 +1 @@ | |||
README CHANGE |
@ -0,0 +1,19 @@ | |||
FROM python:3.6 | |||
RUN apt-get update | |||
RUN apt install -y nginx | |||
WORKDIR /Project/demo | |||
COPY requirements.txt ./ | |||
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple | |||
COPY . . | |||
RUN rm /etc/nginx/sites-enabled/default | |||
COPY nginx_flask.conf /etc/nginx/sites-available/ | |||
RUN ln -s /etc/nginx/sites-available/nginx_flask.conf /etc/nginx/sites-enabled/nginx_flask.conf | |||
RUN echo "daemon off;" >> /etc/nginx/nginx.conf | |||
CMD ["nginx","-c","/etc/nginx/nginx.conf"] | |||
CMD ["nginx","-t"] | |||
CMD ["nginx","-s","reload"] | |||
CMD ["gunicorn", "run:app", "-c", "./gconfig.py"] |
@ -0,0 +1,3 @@ | |||
941b27bc0531c5401948df3564c5b5da371ee9e4 branch 'develop' of 106.75.225.141:guoteng/albumy | |||
42295b43602cb2dd7896c365a821f6d6afba4672 not-for-merge branch 'feature' of 106.75.225.141:guoteng/albumy | |||
549e8bab6eb6120bd84ff14324503868ec124b4e not-for-merge branch 'master' of 106.75.225.141:guoteng/albumy |
@ -0,0 +1 @@ | |||
ref: refs/heads/develop |
@ -0,0 +1,21 @@ | |||
MIT License | |||
Copyright (c) 2017 Grey Li | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to deal | |||
in the Software without restriction, including without limitation the rights | |||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
copies of the Software, and to permit persons to whom the Software is | |||
furnished to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice shall be included in all | |||
copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
SOFTWARE. |
@ -0,0 +1 @@ | |||
c4729ee28f6cff91fd35196a61d75723434b9c5a |
@ -0,0 +1,22 @@ | |||
[[source]] | |||
url = "https://pypi.python.org/simple" | |||
verify_ssl = true | |||
name = "pypi" | |||
[dev-packages] | |||
faker = "*" | |||
watchdog = "*" | |||
[packages] | |||
flask-sqlalchemy = "*" | |||
flask-login = "*" | |||
flask-dropzone = "*" | |||
flask-mail = "*" | |||
flask-moment = "*" | |||
flask-wtf = "*" | |||
python-dotenv = "*" | |||
pillow = "*" | |||
bootstrap-flask = "*" | |||
flask = "*" | |||
flask-whooshee = "*" | |||
flask-avatars = "*" |
@ -0,0 +1,269 @@ | |||
{ | |||
"_meta": { | |||
"hash": { | |||
"sha256": "8f77fa130f0a03afa0d2967bb6b7811e356ad34aef7a0aa88199fc29de15e1b5" | |||
}, | |||
"pipfile-spec": 6, | |||
"requires": {}, | |||
"sources": [ | |||
{ | |||
"name": "pypi", | |||
"url": "https://pypi.python.org/simple", | |||
"verify_ssl": true | |||
} | |||
] | |||
}, | |||
"default": { | |||
"blinker": { | |||
"hashes": [ | |||
"sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6" | |||
], | |||
"version": "==1.4" | |||
}, | |||
"bootstrap-flask": { | |||
"hashes": [ | |||
"sha256:d03c738f5377dbe7ecce010e28afcc0fb8373c4c9d01f8590af7657b53342c1d", | |||
"sha256:ed817e82acadac4c8b3fc2d1a310325b6ed395d13b0f6ca9d14e1742f880e685" | |||
], | |||
"index": "pypi", | |||
"version": "==1.2.0" | |||
}, | |||
"click": { | |||
"hashes": [ | |||
"sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", | |||
"sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" | |||
], | |||
"version": "==7.1.1" | |||
}, | |||
"flask": { | |||
"hashes": [ | |||
"sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060", | |||
"sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557" | |||
], | |||
"index": "pypi", | |||
"version": "==1.1.2" | |||
}, | |||
"flask-avatars": { | |||
"hashes": [ | |||
"sha256:c83081641ee834063416d9437be7d947cdebac51125c5f561d75e7e60f14b21b", | |||
"sha256:e49e9a333b76fb131f4b66c1221b505ab9b3dd0e47a27d6a23e5d24dd2fcb7b2" | |||
], | |||
"index": "pypi", | |||
"version": "==0.2.2" | |||
}, | |||
"flask-dropzone": { | |||
"hashes": [ | |||
"sha256:e5e3d4740d407807aa99d7b6438aad812a1ce01e1b07b0f409462ff078386709", | |||
"sha256:fddeb963aef31da81e7bc39cad740e8778a8c59d96ef76c7d5ed362fc626a73a" | |||
], | |||
"index": "pypi", | |||
"version": "==1.5.4" | |||
}, | |||
"flask-login": { | |||
"hashes": [ | |||
"sha256:6d33aef15b5bcead780acc339464aae8a6e28f13c90d8b1cf9de8b549d1c0b4b", | |||
"sha256:7451b5001e17837ba58945aead261ba425fdf7b4f0448777e597ddab39f4fba0" | |||
], | |||
"index": "pypi", | |||
"version": "==0.5.0" | |||
}, | |||
"flask-mail": { | |||
"hashes": [ | |||
"sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41" | |||
], | |||
"index": "pypi", | |||
"version": "==0.9.1" | |||
}, | |||
"flask-moment": { | |||
"hashes": [ | |||
"sha256:3c509afa25fd77459c9d799f292dcea384b1cd588ed1fd68f97f6fda6131299e", | |||
"sha256:3e8b88f99af7cf75f2f29ef9d8c158eb92ca6f3c1ba6456ad70f715efa6eb7f7" | |||
], | |||
"index": "pypi", | |||
"version": "==0.9.0" | |||
}, | |||
"flask-sqlalchemy": { | |||
"hashes": [ | |||
"sha256:0078d8663330dc05a74bc72b3b6ddc441b9a744e2f56fe60af1a5bfc81334327", | |||
"sha256:6974785d913666587949f7c2946f7001e4fa2cb2d19f4e69ead02e4b8f50b33d" | |||
], | |||
"index": "pypi", | |||
"version": "==2.4.1" | |||
}, | |||
"flask-whooshee": { | |||
"hashes": [ | |||
"sha256:9ee837503eaead2a81554f0e01c2647f0240f247b0b5b01b431c8cb67617ff31" | |||
], | |||
"index": "pypi", | |||
"version": "==0.7.0" | |||
}, | |||
"flask-wtf": { | |||
"hashes": [ | |||
"sha256:57b3faf6fe5d6168bda0c36b0df1d05770f8e205e18332d0376ddb954d17aef2", | |||
"sha256:d417e3a0008b5ba583da1763e4db0f55a1269d9dd91dcc3eb3c026d3c5dbd720" | |||
], | |||
"index": "pypi", | |||
"version": "==0.14.3" | |||
}, | |||
"itsdangerous": { | |||
"hashes": [ | |||
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", | |||
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" | |||
], | |||
"version": "==1.1.0" | |||
}, | |||
"jinja2": { | |||
"hashes": [ | |||
"sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250", | |||
"sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49" | |||
], | |||
"version": "==2.11.1" | |||
}, | |||
"markupsafe": { | |||
"hashes": [ | |||
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", | |||
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", | |||
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", | |||
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", | |||
"sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", | |||
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", | |||
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", | |||
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", | |||
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", | |||
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", | |||
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", | |||
"sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", | |||
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", | |||
"sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", | |||
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", | |||
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", | |||
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", | |||
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", | |||
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", | |||
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", | |||
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", | |||
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", | |||
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", | |||
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", | |||
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", | |||
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", | |||
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", | |||
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", | |||
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", | |||
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", | |||
"sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", | |||
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", | |||
"sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" | |||
], | |||
"version": "==1.1.1" | |||
}, | |||
"pillow": { | |||
"hashes": [ | |||
"sha256:04a10558320eba9137d6a78ca6fc8f4a5801f1b971152938851dc4629d903579", | |||
"sha256:0f89ddc77cf421b8cd34ae852309501458942bf370831b4a9b406156b599a14e", | |||
"sha256:251e5618125ec12ac800265d7048f5857a8f8f1979db9ea3e11382e159d17f68", | |||
"sha256:291bad7097b06d648222b769bbfcd61e40d0abdfe10df686d20ede36eb8162b6", | |||
"sha256:2f0b52a08d175f10c8ea36685115681a484c55d24d0933f9fd911e4111c04144", | |||
"sha256:3713386d1e9e79cea1c5e6aaac042841d7eef838cc577a3ca153c8bedf570287", | |||
"sha256:433bbc2469a2351bea53666d97bb1eb30f0d56461735be02ea6b27654569f80f", | |||
"sha256:4510c6b33277970b1af83c987277f9a08ec2b02cc20ac0f9234e4026136bb137", | |||
"sha256:50a10b048f4dd81c092adad99fa5f7ba941edaf2f9590510109ac2a15e706695", | |||
"sha256:670e58d3643971f4afd79191abd21623761c2ebe61db1c2cb4797d817c4ba1a7", | |||
"sha256:6c1924ed7dbc6ad0636907693bbbdd3fdae1d73072963e71f5644b864bb10b4d", | |||
"sha256:721c04d3c77c38086f1f95d1cd8df87f2f9a505a780acf8575912b3206479da1", | |||
"sha256:8d5799243050c2833c2662b824dfb16aa98e408d2092805edea4300a408490e7", | |||
"sha256:90cd441a1638ae176eab4d8b6b94ab4ec24b212ed4c3fbee2a6e74672481d4f8", | |||
"sha256:a5dc9f28c0239ec2742d4273bd85b2aa84655be2564db7ad1eb8f64b1efcdc4c", | |||
"sha256:b2f3e8cc52ecd259b94ca880fea0d15f4ebc6da2cd3db515389bb878d800270f", | |||
"sha256:b7453750cf911785009423789d2e4e5393aae9cbb8b3f471dab854b85a26cb89", | |||
"sha256:b99b2607b6cd58396f363b448cbe71d3c35e28f03e442ab00806463439629c2c", | |||
"sha256:cd47793f7bc9285a88c2b5551d3f16a2ddd005789614a34c5f4a598c2a162383", | |||
"sha256:d6bf085f6f9ec6a1724c187083b37b58a8048f86036d42d21802ed5d1fae4853", | |||
"sha256:da737ab273f4d60ae552f82ad83f7cbd0e173ca30ca20b160f708c92742ee212", | |||
"sha256:eb84e7e5b07ff3725ab05977ac56d5eeb0c510795aeb48e8b691491be3c5745b" | |||
], | |||
"index": "pypi", | |||
"version": "==7.1.1" | |||
}, | |||
"python-dotenv": { | |||
"hashes": [ | |||
"sha256:81822227f771e0cab235a2939f0f265954ac4763cafd806d845801c863bf372f", | |||
"sha256:92b3123fb2d58a284f76cc92bfe4ee6c502c32ded73e8b051c4f6afc8b6751ed" | |||
], | |||
"index": "pypi", | |||
"version": "==0.12.0" | |||
}, | |||
"sqlalchemy": { | |||
"hashes": [ | |||
"sha256:c4cca4aed606297afbe90d4306b49ad3a4cd36feb3f87e4bfd655c57fd9ef445" | |||
], | |||
"version": "==1.3.15" | |||
}, | |||
"werkzeug": { | |||
"hashes": [ | |||
"sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", | |||
"sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" | |||
], | |||
"version": "==1.0.1" | |||
}, | |||
"whoosh": { | |||
"hashes": [ | |||
"sha256:7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83", | |||
"sha256:aa39c3c3426e3fd107dcb4bde64ca1e276a65a889d9085a6e4b54ba82420a852", | |||
"sha256:e0857375f63e9041e03fedd5b7541f97cf78917ac1b6b06c1fcc9b45375dda69" | |||
], | |||
"version": "==2.7.4" | |||
}, | |||
"wtforms": { | |||
"hashes": [ | |||
"sha256:0cdbac3e7f6878086c334aa25dc5a33869a3954e9d1e015130d65a69309b3b61", | |||
"sha256:e3ee092c827582c50877cdbd49e9ce6d2c5c1f6561f849b3b068c1b8029626f1" | |||
], | |||
"version": "==2.2.1" | |||
} | |||
}, | |||
"develop": { | |||
"faker": { | |||
"hashes": [ | |||
"sha256:2d3f866ef25e1a5af80e7b0ceeacc3c92dec5d0fdbad3e2cb6adf6e60b22188f", | |||
"sha256:b89aa33837498498e15c709eb40c31386408a901a53c7a5e12a425737a767976" | |||
], | |||
"index": "pypi", | |||
"version": "==4.0.2" | |||
}, | |||
"pathtools": { | |||
"hashes": [ | |||
"sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0" | |||
], | |||
"version": "==0.1.2" | |||
}, | |||
"python-dateutil": { | |||
"hashes": [ | |||
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", | |||
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" | |||
], | |||
"version": "==2.8.1" | |||
}, | |||
"six": { | |||
"hashes": [ | |||
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", | |||
"sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" | |||
], | |||
"version": "==1.14.0" | |||
}, | |||
"text-unidecode": { | |||
"hashes": [ | |||
"sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", | |||
"sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93" | |||
], | |||
"version": "==1.3" | |||
}, | |||
"watchdog": { | |||
"hashes": [ | |||
"sha256:c560efb643faed5ef28784b2245cf8874f939569717a4a12826a173ac644456b" | |||
], | |||
"index": "pypi", | |||
"version": "==0.10.2" | |||
} | |||
} | |||
} |
@ -1,2 +1,609 @@ | |||
# cloud_computing_1 | |||
本次实验源代码来自:https://github.com/greyli/albumy | |||
demo网站:http://59.110.70.81:5000 | |||
(主机的带宽最好大一点,我的1M小水管打开网站测试极慢) | |||
tomcat需要8080端口,nginx需要5000,80端口。 | |||
不必要的端口不要开,提前提示,谨慎reboot,update,upgrade,高并发优化不是必要的,谨慎使用。 | |||
系统:Centos 8 | |||
先创建一个有root权限的用户(这里用Rivenatte) | |||
切换到Rivenatte: | |||
su Rivenatte | |||
更新: | |||
sudo yum update | |||
sudo yum upgrade | |||
检查有没有gcc: | |||
gcc -v | |||
没有就: | |||
sudo yum install gcc | |||
有时需安装git: | |||
sudo yum install git | |||
拉取项目(这里用原项目的): | |||
git clone https://github.com/greyli/albumy.git | |||
cd albumy | |||
配置虚拟环境: | |||
python -m venv env(or python3 -m venv env) | |||
source env/bin/activate | |||
pip install -r requirements.txt | |||
python -m pip install --upgrade pip | |||
生成测试数据并测试: | |||
flask forge | |||
flask run --host 0.0.0.0 --port 5000 | |||
用浏览器打开http://云主机ip:5000 | |||
测试的用户账号: | |||
username:admin@helloflask.com | |||
password:helloflask | |||
下面的pip可以换成pip3,如果你在创建虚拟环境时用python3的话 | |||
然而flask自带的wsgi容器性能较差,我采用另一个服务器,gunicorn。 | |||
先将我git上的python文件放在albumy中, | |||
同时还需在项目目录下: | |||
mkdir log | |||
cd log | |||
touch debug.log | |||
touch gunicorn.pid | |||
cd .. | |||
这里的albumy指项目目录,不是albumy模块。 | |||
gunicorn需要在虚拟环境下安装: | |||
(没进虚拟环境的先: | |||
source env/bin/activate) | |||
pip install gunicorn | |||
同时还需安装gevent: | |||
pip install gevent | |||
推荐参考这个格式,指定源: | |||
pip install 包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com | |||
可以解决大多问题。 | |||
然后: | |||
cd albumy | |||
修改__init__.py的create_app中的 | |||
app = Flask('albumy') | |||
改为 | |||
app = Flask(__name__) | |||
输入 | |||
gunicorn -c albumy项目的绝对路径/gconfig.py run:app | |||
像上面一样,打开浏览器测试 | |||
继续用nginx来做反向代理。 | |||
先安装nginx: | |||
sudo yum install nginx | |||
接下来的配置,不同的linux发行版修改的文件可能不同,但大体类似。 | |||
实在不行就用whereis nginx找。 | |||
centos就先: | |||
cd /etc/nginx | |||
ls -a | |||
发现conf.d这个文件夹,这个是放配置文件的 | |||
先对nginx.conf修改。 | |||
一般第二个https的设置是被注释的,不用管。 | |||
看http的设置,在http部分的最下面加入: | |||
include conf.d/*.conf;(;不能少了) | |||
这样我们就可以通过在conf.d文件夹里修改文件来进行配置 | |||
配置文件必须是.conf格式 | |||
比如 albumy.conf | |||
server { | |||
listen 80; | |||
root albumy项目的绝对路径; | |||
server_name 公网ip; | |||
location / { | |||
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_pass http://localhost:5000/; # gunicorn绑定的端口号 | |||
} | |||
# 配置static的静态文件: | |||
location ~ ^\/static\/.*$ { | |||
root 项目的绝对路径; | |||
} | |||
} | |||
添加后 | |||
sudo nginx -c /etc/nginx/nginx.conf | |||
sudo nginx -t | |||
sudo nginx -s reload | |||
用浏览器打开80,5000端口,看下有没有成功。 | |||
80端口的仅仅是静态页面,比较简陋。 | |||
接着我们需要用nohup守护进程: | |||
进入项目文件夹的虚拟环境: | |||
cd xxx/albumy/ | |||
source env/bin/activate | |||
nohup gunicorn -c gconfig.py run:app & | |||
然后看下有没有成功: | |||
ps -e | grep gunicorn | |||
nohub不能让主机重启后自动运行进程,我们需要设置开机启动: | |||
sudo vim /etc/rc.local | |||
在最下面添加命令行,这样就可以在重启后自动执行命令行了。 | |||
最后别忘了加: | |||
chmod +x /etc/rc.d/rc.local | |||
然后可以重启检查下。 | |||
接下来进行高并发优化 | |||
我们需要安装ab压测工具 | |||
这个在任何服务器上部署都可以,只要在最后把ip改下就行。 | |||
这里申请一台centos8主机,部署ab。 | |||
同样不使用root用户。 | |||
先提醒下,deb系的安装与以下有点区别。 | |||
先更新: | |||
sudo yum update | |||
sudo yum upgrade | |||
安装依赖: | |||
sudo yum install apr-util | |||
sudo yum install yum-utils | |||
sudo mkdir -p /appdata/apache/ab && cd /appdata/apache/ab | |||
安装ab: | |||
sudo yum install yum-utils.noarch | |||
sudo yumdownloader httpd-tools* | |||
下一步需要root用户: | |||
su root | |||
rpm2cpio httpd-tools*.rpm | cpio -idmv | |||
su Rivenatte | |||
sudo cp /appdata/apache/ab/usr/bin/ab /usr/bin | |||
执行ab: | |||
ab -n 1000 -c 200 http://ip:5000/ | |||
如果不与项目在同一主机,写公网ip | |||
在就localhost | |||
1000指共访问了1000次,200指同时200并发 | |||
进行了5次 | |||
出现apr_pollset_poll: The timeout specified has expired (70007) | |||
就改为ab -n 1000 -c 200 -k http://ip:5000/ | |||
看主机配置,量力而行。 | |||
先测试下,与优化后比较。 | |||
回到部署nginx的主机。 | |||
先获取cpu核心数: | |||
grep processor /proc/cpuinfo | wc -l | |||
一般在申请时就知道了 | |||
修改配置文件中的http模块: | |||
sudo vim /etc/nginx/nginx.conf | |||
具体参数参考以下文章: | |||
https://www.jianshu.com/p/0fa77899913a | |||
单核2g的主机可以参考以下配置: | |||
worker_rlimit_nofile 10000; | |||
events { | |||
worker_connections 10000; | |||
} | |||
keepalive_timeout 0;(高并发的网站需要设置的参数) | |||
su root | |||
(不用root用户无法进行下列命令) | |||
对系统配置: | |||
ulimit -n 一个较大的数字 | |||
echo 50000 > /proc/sys/net/core/somaxconn | |||
more /proc/sys/net/core/somaxconn | |||
有50000则正常 | |||
下列同理: | |||
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle(注意,现在的centos取消了这个参数,没有可以不管) | |||
cat /proc/sys/net/ipv4/tcp_tw_recycle | |||
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse | |||
cat /proc/sys/net/ipv4/tcp_tw_reuse | |||
echo 0 > /proc/sys/net/ipv4/tcp_syncookies | |||
cat /proc/sys/net/ipv4/tcp_syncookies | |||
dmesg|tail | |||
(可能需vim /etc/sysctl.conf | |||
设置: | |||
net.ipv4.tcp_syncookies = 0) | |||
对测试主机也需: | |||
echo 50000 > /proc/sys/net/core/somaxconn | |||
ulimit -n 一个较大的数字 | |||
(可能需设置net.ipv4.tcp_syncookies = 0,同上) | |||
 | |||
不重启主机,对测试主机配置后开始测试: | |||
sudo vim /etc/sysctl.conf | |||
加入: | |||
net.nf_conntrack_max = 655360 | |||
net.netfilter.nf_conntrack_tcp_timeout_established = 1200) | |||
ab -c 100000 -n 100000 -r http://主机ip:5000/ | |||
(可以适当改下,但还是要看主机配置,我这台是2gRam 1核) | |||
之后可以将以上系统设置加入自启动项(服务器重启可能会回到修改前设置) | |||
下面添加邮箱: | |||
先去注册个邮箱,并以stmp服务器发送。(这个需要网上查下如何开放邮箱stmp,不同邮箱的可能不同) | |||
像之前一样,修改启动项: | |||
source env/bin/activate | |||
export MAIL_SERVER='smtp.163.com' //示例 | |||
export MAIL_USERNAME='XXXXXX@163.com' //填邮箱XXXXXX | |||
export MAIL_PASSWORD='XXXXXX' //密码,注意是邮箱开启第三方smtp的认证码 | |||
别忘了chmod +x /etc/rc.d/rc.local | |||
最后reboot。 | |||
(注:这里需要邮箱发送验证邮件,才可以输入验证码注册) | |||
## 采用docker部署与k8s集群负载均衡 | |||
### 一、docker部署上传镜像 | |||
配置docker容器并push到远端,重新在别的服务器上部署时只需将镜像pull下来即可。 | |||
写好Dockerfile,在本地build好镜像后,将容器push到远端。 | |||
在服务器上部署时只需将远端的容器pull到服务器上,再run即可 | |||
```python | |||
我们首先要将上面的run.py中的 | |||
app.run()改为app.run(host='0.0.0.0',port=3389) | |||
``` | |||
部署时先下载docker | |||
```bash | |||
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun | |||
``` | |||
若报错则先执行 | |||
```bash | |||
yum install -y https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm | |||
``` | |||
接着启动docker服务 | |||
```bash | |||
service docker start | |||
``` | |||
写入我们的Dockerfile | |||
```bash | |||
vim Dockerfile | |||
``` | |||
``` | |||
FROM python:3.6 | |||
RUN apt-get update | |||
RUN apt install -y nginx | |||
WORKDIR /Project/demo | |||
COPY requirements.txt ./ | |||
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple | |||
COPY . . | |||
RUN rm /etc/nginx/sites-enabled/default | |||
COPY nginx_flask.conf /etc/nginx/sites-available/ | |||
RUN ln -s /etc/nginx/sites-available/nginx_flask.conf /etc/nginx/sites-enabled/nginx_flask.conf | |||
RUN echo "daemon off;" >> /etc/nginx/nginx.conf | |||
CMD ["nginx","-c","/etc/nginx/nginx.conf"] | |||
CMD ["nginx","-t"] | |||
CMD ["nginx","-s","reload"] | |||
CMD ["gunicorn", "run:app", "-c", "./gconfig.py"] | |||
``` | |||
其中需要我们之前部署时写的gconfig.py文件和我们的nginx配置文件 | |||
除此以外我们需要在根目录创建一个新文件**nginx_flask.conf** | |||
``` | |||
server { | |||
listen 80; | |||
location / { | |||
proxy_pass http://localhost:5000/; | |||
proxy_set_header Host $host; | |||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
} | |||
location ^~ /static/ { | |||
root /Project/demo; | |||
} | |||
} | |||
``` | |||
之后在本地建立镜像 | |||
```bash | |||
docker build -t image1 . | |||
``` | |||
建立成功后可以尝试启动docker容器 | |||
``` | |||
docker run -d -p 3389:3389 --name test1 image1 | |||
``` | |||
打开http://云主机ip:3389查看是否显示界面 | |||
之后将我们的镜像push到远端 | |||
没有注册docker账号的话先注册一个docker账号 | |||
https://registry.hub.docker.com/ | |||
接着登录docker账号 | |||
``` | |||
docker login | |||
输入账号 | |||
输入密码 | |||
``` | |||
显示login successful就成功了,之后push到远端 | |||
首先对镜像打标签 | |||
```bash | |||
docker tag image1 lh123/albumy_nginx_mysql_image:v2 | |||
``` | |||
之后将镜像推送到仓库 | |||
```bash | |||
docker push lh123/albumy_nginx_mysql_image:v2 | |||
``` | |||
以后需要创建应用时只需要从docker中拉取镜像运行即可。 | |||
 | |||
新建云主机,安装docker之后将上述镜像pull到本地,之后执行 | |||
``` | |||
docker run -d -p 3389:3389 --name test1 lh123/albumy_nginx_mysql_image:v2 | |||
``` | |||
打开http:云主机ip:3389即可访问网页。 | |||
### 二、采用负载均衡 | |||
之后在ucloud中使用负载均衡ULB,创建负载均衡ULB。 | |||
接着在建立三台云主机,使用原来申请的有外网的云主机,分别通过内网连接三台新建的云主机。 | |||
在云主机上pull下来刚才上传的docker镜像 | |||
```bash | |||
docker pull lh123/albumy_nginx_mysql_image:v2 | |||
``` | |||
在云主机上启动镜像 | |||
```bash | |||
docker run -d -p 3389:3389 --name test1 albumy_nginx_mysql_image:v2 | |||
``` | |||
将我们启动好的三台云主机啊加到我们的负载均衡当中 | |||
 | |||
使用负载均衡之后的压测效果更好 | |||
 | |||
### 三、连接云数据库 | |||
为了保证负载均衡的服务器的数据一致性,我们将数据库挂在到云数据库mysql上 | |||
我们将项目的.flask.env文件中的设置改为 | |||
```bash | |||
FLASK_APP=albumy | |||
FLASK_ENV=development | |||
``` | |||
再将setting.py中的设置改为 | |||
```bash | |||
class ProductionConfig(BaseConfig): | |||
SQLALCHEMY_DATABASE_URI = 'mysql://root:lianghui123@10.23.56.255:3306/flask_test' | |||
``` | |||
再打包到docker并运行我们的项目 | |||
发现报错No module named MYSQLdb发现是因为 | |||
```bash | |||
按照 Flask-SQLAlchemy 文档的说明,配置好 SQLALCHEMY_DATABASE_URI = 'mysql://username:password@server/db' 后操作 MySQL 报错 ImportError: No module named 'MySQLdb'。既然缺少 MySQLdb 这个模块,按照常规方法缺啥补啥吧,执行 pip install MySQL-python 却报错 ImportError: No module named 'ConfigParser'。查了一下,这是由于 MySQL-python 不支持 Python 3(MySQL-3.23 through 5.5 and Python-2.4 through 2.7 are currently supported)。 | |||
``` | |||
将MySQLdb换为pymsql,安装pymsql(记得先启动虚拟环境) | |||
```absh | |||
pip install pymsql | |||
``` | |||
并在__init__.py中加入 | |||
```python | |||
import pymysql | |||
pymysql.install_as_MySQLdb() | |||
``` | |||
再将setting.py中的设置改为 | |||
```bash | |||
class ProductionConfig(BaseConfig): | |||
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:lianghui123@10.23.56.255:3306/flask_test' | |||
``` | |||
即可访问我们的云主机数据库。 | |||
最后将完成的项目打包好镜像push到远端仓库。 | |||
### 四、k8s集群部署(有点问题) | |||
建立好docker容器之后就可以使用k8s集群部署网页,采用k8s部署可以实现容器集群的自动化部署、自动扩缩容、维护等功能。 | |||
首先在ucloud中创建一个UK8S,之后申请一个云主机, | |||
登录云主机安装docker拉取镜像 | |||
``` | |||
docker pull lh123/albumy_nginx_mysql_image:v2 | |||
``` | |||
安装k8s | |||
```bash | |||
wget https://storage.googleapis.com/kubernetes-release/release/v1.19.0/bin/linux/amd64/kubectl | |||
chmod +x kubectl | |||
sudo mv kubectl /usr/local/bin/ (root用户:mv kubectl /usr/bin/) | |||
kubectl version -o json | |||
``` | |||
将K8S的集群凭证添加到kubectl配置文件中,从而能够操控集群。 | |||
打开K8S的外网集凭证复制,在云主机中创建~/.kube文件夹,并在其中创建config文件,将外网集凭证复制到config文件中。 | |||
为了能在k8s上部署我们的docker镜像,我们还需要在项目文件中添加两个文件**Deployment.yaml** 和 **service.yaml**, | |||
**deployment.yaml**中: | |||
```bash | |||
apiVersion: extensions/v1beta1 | |||
kind: Deployment | |||
metadata: | |||
name: albumy-node-deployment | |||
spec: | |||
replicas: 1 | |||
selector: | |||
matchLabels: | |||
app: albumynode | |||
template: | |||
metadata: | |||
labels: | |||
app: albumynode | |||
spec: | |||
containers: | |||
- name: albumynode | |||
image: lh123/albumy_nginx_mysql_image:v2 | |||
imagePullPolicy: Always | |||
ports: | |||
- containerPort: 3389 | |||
``` | |||
**service.yaml**中: | |||
``` | |||
apiVersion: v1 | |||
kind: Service | |||
metadata: | |||
name: albumy-node-deployment | |||
spec: | |||
ports: | |||
- port: 3389 | |||
targetPort: 3389 | |||
selector: | |||
app: albumynode | |||
``` | |||
之后运行一下命令部署项目 | |||
```bash | |||
kubectl create -f deployment.yaml | |||
kubectl create -f service.yaml | |||
``` | |||
查看pod是否处于ready状态,若pod不处于ready状态且一直是containercreating状态则 | |||
 | |||
查看创建日志,发现是容器创建失败,谷歌不能访问,uhub-edu.service.ucloud.cn/google_containers/pause-amd64:3.0"镜像无法获取,这应该是ucloud端的问题。(我们采用平时实验作业第八次的部署方法部署实验2里的静态网页也还是报这个错误,真的是很无语)。 | |||
(即使用 | |||
```bash | |||
kubectl create deployment webapp --image=lh123/albumy_nginx_mysql_image:v2 | |||
``` | |||
我们发现这样子pod的状态还是一直处于containercreating的状态,而且也是报下图的错误,我觉得者应该是ucloud端的问题,被墙了。我怀疑是ucloud的教育云出问题了之前第八次实验的时候还可以用,现在就不可以用了。 | |||
) | |||
 | |||
解决方法如下,从docker.io把pause-amd64镜像取下来,然后做个标签。这样就可以解决问题。 | |||
``` | |||
docker pull googlecontainer/pause-amd64:3.0 | |||
docker tag googlecontainer/pause-amd64:3.0 uhub-edu.service.ucloud.cn/google_containers/pause-amd64:3.0 | |||
``` | |||
之后新建连接,登录云主机执行 | |||
```bash | |||
echo -e "\n\e[92mStarting Proxy. After starting it will not output a response. Please click the first Terminal Tab\n"; kubectl proxy | |||
``` | |||
之后访问我们的应用 | |||
``` | |||
kubectl get pods#获取我们pod的名称 | |||
export POD_NAME=$刚才得到的pod名称 | |||
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/ | |||
``` | |||
查看我们创建的POD的详细信息 | |||
``` | |||
kubectl get pods -o wide | |||
``` | |||
之后将副本scale到10个 | |||
```bash | |||
kubectl scale deployments/albumy-node-deployment --replicas=10 | |||
``` | |||
将我们的网页暴露给公网,并加上负载均衡 | |||
创建一个负载均衡 | |||
```bash | |||
kubectl expose deployment albumy-node-deployment --type=LoadBalancer --port=80 | |||
``` | |||
查看service,可以看到负载均衡服务的外网ip地址 | |||
```bash | |||
kubectl get services | |||
``` | |||
之后访问http:localhost:负载均衡ip就可以看到网页 | |||
本次作业镜像: | |||
账号:1491337293@qq.com | |||
密码:18830095812zxc | |||
docker账户 | |||
账号:lh123 | |||
密码:18830095812zxc | |||
docker镜像:lh123/albumy_nginx_mysql_image:v2 | |||
 | |||
ucloud上docker部署镜像名:docker_nginx_mysql | |||
 | |||
集群部署有点问题被墙了。 | |||
@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module type="PYTHON_MODULE" version="4"> | |||
<component name="NewModuleRootManager"> | |||
<content url="file:// |
|||
<orderEntry type="inheritedJdk" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
</component> | |||
<component name="TemplatesService"> | |||
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" /> | |||
<option name="TEMPLATE_FOLDERS"> | |||
<list> | |||
<option value=" |
|||
</list> | |||
</option> | |||
</component> | |||
</module> |
@ -0,0 +1,21 @@ | |||
[core] | |||
repositoryformatversion = 0 | |||
filemode = false | |||
bare = false | |||
logallrefupdates = true | |||
symlinks = false | |||
ignorecase = true | |||
[remote "origin"] | |||
url = git@106.75.225.141:guoteng/albumy.git | |||
fetch = +refs/heads/*:refs/remotes/origin/* | |||
[branch "master"] | |||
remote = origin | |||
merge = refs/heads/master | |||
rebase = true | |||
[branch "develop"] | |||
remote = origin | |||
merge = refs/heads/develop | |||
rebase = true | |||
[gui] | |||
wmstate = normal | |||
geometry = 1061x563+160+160 233 255 |
@ -0,0 +1 @@ | |||
Unnamed repository; edit this file 'description' to name the repository. |
@ -0,0 +1,11 @@ | |||
from gevent import monkey | |||
monkey.patch_all() | |||
import multiprocessing | |||
debug = True | |||
loglevel = 'debug' | |||
bind = '0.0.0.0:3389' | |||
pidfile = 'log/gunicorn.pid' | |||
logfile = 'log/debug.log' | |||
workers = multiprocessing.cpu_count() * 2 + 1 | |||
worker_class = 'gevent' | |||
@ -0,0 +1,16 @@ | |||
# This is a sample Python script. | |||
# Press Shift+F10 to execute it or replace it with your code. | |||
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. | |||
def print_hi(name): | |||
# Use a breakpoint in the code line below to debug your script. | |||
print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. | |||
# Press the green button in the gutter to run the script. | |||
if __name__ == '__main__': | |||
print_hi('PyCharm') | |||
# See PyCharm help at https://www.jetbrains.com/help/pycharm/ |
@ -0,0 +1,15 @@ | |||
server { | |||
listen 80; | |||
location / { | |||
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_pass http://localhost:3389/; # gunicorn绑定的端口号 | |||
} | |||
# 配置static的静态文件: | |||
location ~ ^\/static\/.*$ { | |||
root /Project/demo; | |||
} | |||
} | |||
@ -0,0 +1,198 @@ | |||
[2021-01-14 08:37:45 +0800] [14269] [DEBUG] Current configuration: | |||
config: gconfig.py | |||
bind: ['0.0.0.0:3389'] | |||
backlog: 2048 | |||
workers: 5 | |||
worker_class: gevent | |||
threads: 1 | |||
worker_connections: 1000 | |||
max_requests: 0 | |||
max_requests_jitter: 0 | |||
timeout: 30 | |||
graceful_timeout: 30 | |||
keepalive: 2 | |||
limit_request_line: 4094 | |||
limit_request_fields: 100 | |||
limit_request_field_size: 8190 | |||
reload: False | |||
reload_engine: auto | |||
reload_extra_files: [] | |||
spew: False | |||
check_config: False | |||
preload_app: False | |||
sendfile: None | |||
reuse_port: False | |||
chdir: /root/albumy | |||
daemon: False | |||
raw_env: [] | |||
pidfile: log/gunicorn.pid | |||
worker_tmp_dir: None | |||
user: 0 | |||
group: 0 | |||
umask: 0 | |||
initgroups: False | |||
tmp_upload_dir: None | |||
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'} | |||
forwarded_allow_ips: ['127.0.0.1'] | |||
accesslog: None | |||
disable_redirect_access_to_syslog: False | |||
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" | |||
errorlog: - | |||
loglevel: debug | |||
capture_output: False | |||
logger_class: gunicorn.glogging.Logger | |||
logconfig: None | |||
logconfig_dict: {} | |||
syslog_addr: udp://localhost:514 | |||
syslog: False | |||
syslog_prefix: None | |||
syslog_facility: user | |||
enable_stdio_inheritance: False | |||
statsd_host: None | |||
dogstatsd_tags: | |||
statsd_prefix: | |||
proc_name: None | |||
default_proc_name: run:app | |||
pythonpath: None | |||
paste: None | |||
on_starting: <function OnStarting.on_starting at 0x7f4348074a60> | |||
on_reload: <function OnReload.on_reload at 0x7f4348074b70> | |||
when_ready: <function WhenReady.when_ready at 0x7f4348074c80> | |||
pre_fork: <function Prefork.pre_fork at 0x7f4348074d90> | |||
post_fork: <function Postfork.post_fork at 0x7f4348074ea0> | |||
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f4348094048> | |||
worker_int: <function WorkerInt.worker_int at 0x7f4348094158> | |||
worker_abort: <function WorkerAbort.worker_abort at 0x7f4348094268> | |||
pre_exec: <function PreExec.pre_exec at 0x7f4348094378> | |||
pre_request: <function PreRequest.pre_request at 0x7f4348094488> | |||
post_request: <function PostRequest.post_request at 0x7f4348094510> | |||
child_exit: <function ChildExit.child_exit at 0x7f4348094620> | |||
worker_exit: <function WorkerExit.worker_exit at 0x7f4348094730> | |||
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f4348094840> | |||
on_exit: <function OnExit.on_exit at 0x7f4348094950> | |||
proxy_protocol: False | |||
proxy_allow_ips: ['127.0.0.1'] | |||
keyfile: None | |||
certfile: None | |||
ssl_version: 2 | |||
cert_reqs: 0 | |||
ca_certs: None | |||
suppress_ragged_eofs: True | |||
do_handshake_on_connect: False | |||
ciphers: None | |||
raw_paste_global_conf: [] | |||
strip_header_spaces: False | |||
[2021-01-14 08:37:45 +0800] [14269] [INFO] Starting gunicorn 20.0.4 | |||
[2021-01-14 08:37:45 +0800] [14269] [DEBUG] Arbiter booted | |||
[2021-01-14 08:37:45 +0800] [14269] [INFO] Listening at: http://0.0.0.0:3389 (14269) | |||
[2021-01-14 08:37:45 +0800] [14269] [INFO] Using worker: gevent | |||
[2021-01-14 08:37:45 +0800] [14272] [INFO] Booting worker with pid: 14272 | |||
[2021-01-14 08:37:45 +0800] [14273] [INFO] Booting worker with pid: 14273 | |||
[2021-01-14 08:37:45 +0800] [14274] [INFO] Booting worker with pid: 14274 | |||
[2021-01-14 08:37:45 +0800] [14276] [INFO] Booting worker with pid: 14276 | |||
[2021-01-14 08:37:45 +0800] [14269] [DEBUG] 5 workers | |||
[2021-01-14 08:37:45 +0800] [14277] [INFO] Booting worker with pid: 14277 | |||
[2021-01-14 09:06:33 +0800] [17476] [INFO] Booting worker with pid: 17476 | |||
[2021-01-14 09:06:33 +0800] [17481] [INFO] Booting worker with pid: 17481 | |||
[2021-01-14 09:06:33 +0800] [14269] [DEBUG] 2 workers | |||
[2021-01-14 09:06:33 +0800] [14269] [INFO] Handling signal: hup | |||
[2021-01-14 09:06:33 +0800] [14269] [INFO] Hang up: Master | |||
[2021-01-14 09:06:33 +0800] [14269] [DEBUG] Current configuration: | |||
config: gconfig.py | |||
bind: ['0.0.0.0:3389'] | |||
backlog: 2048 | |||
workers: 5 | |||
worker_class: gevent | |||
threads: 1 | |||
worker_connections: 1000 | |||
max_requests: 0 | |||
max_requests_jitter: 0 | |||
timeout: 30 | |||
graceful_timeout: 30 | |||
keepalive: 2 | |||
limit_request_line: 4094 | |||
limit_request_fields: 100 | |||
limit_request_field_size: 8190 | |||
reload: False | |||
reload_engine: auto | |||
reload_extra_files: [] | |||
spew: False | |||
check_config: False | |||
preload_app: False | |||
sendfile: None | |||
reuse_port: False | |||
chdir: /root/albumy | |||
daemon: False | |||
raw_env: [] | |||
pidfile: log/gunicorn.pid | |||
worker_tmp_dir: None | |||
user: 0 | |||
group: 0 | |||
umask: 0 | |||
initgroups: False | |||
tmp_upload_dir: None | |||
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'} | |||
forwarded_allow_ips: ['127.0.0.1'] | |||
accesslog: None | |||
disable_redirect_access_to_syslog: False | |||
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" | |||
errorlog: - | |||
loglevel: debug | |||
capture_output: False | |||
logger_class: gunicorn.glogging.Logger | |||
logconfig: None | |||
logconfig_dict: {} | |||
syslog_addr: udp://localhost:514 | |||
syslog: False | |||
syslog_prefix: None | |||
syslog_facility: user | |||
enable_stdio_inheritance: False | |||
statsd_host: None | |||
dogstatsd_tags: | |||
statsd_prefix: | |||
proc_name: None | |||
default_proc_name: run:app | |||
pythonpath: None | |||
paste: None | |||
on_starting: <function OnStarting.on_starting at 0x7f4348074a60> | |||
on_reload: <function OnReload.on_reload at 0x7f4348074b70> | |||
when_ready: <function WhenReady.when_ready at 0x7f4348074c80> | |||
pre_fork: <function Prefork.pre_fork at 0x7f4348074d90> | |||
post_fork: <function Postfork.post_fork at 0x7f4348074ea0> | |||
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f4348094048> | |||
worker_int: <function WorkerInt.worker_int at 0x7f4348094158> | |||
worker_abort: <function WorkerAbort.worker_abort at 0x7f4348094268> | |||
pre_exec: <function PreExec.pre_exec at 0x7f4348094378> | |||
pre_request: <function PreRequest.pre_request at 0x7f4348094488> | |||
post_request: <function PostRequest.post_request at 0x7f4348094510> | |||
child_exit: <function ChildExit.child_exit at 0x7f4348094620> | |||
worker_exit: <function WorkerExit.worker_exit at 0x7f4348094730> | |||
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f4348094840> | |||
on_exit: <function OnExit.on_exit at 0x7f4348094950> | |||
proxy_protocol: False | |||
proxy_allow_ips: ['127.0.0.1'] | |||
keyfile: None | |||
certfile: None | |||
ssl_version: 2 | |||
cert_reqs: 0 | |||
ca_certs: None | |||
suppress_ragged_eofs: True | |||
do_handshake_on_connect: False | |||
ciphers: None | |||
raw_paste_global_conf: [] | |||
strip_header_spaces: False | |||
[2021-01-14 09:06:33 +0800] [17510] [INFO] Booting worker with pid: 17510 | |||
[2021-01-14 09:06:33 +0800] [17512] [INFO] Booting worker with pid: 17512 | |||
[2021-01-14 09:06:33 +0800] [17509] [INFO] Booting worker with pid: 17509 | |||
[2021-01-14 09:06:33 +0800] [17511] [INFO] Booting worker with pid: 17511 | |||
[2021-01-14 09:06:33 +0800] [17518] [INFO] Booting worker with pid: 17518 | |||
[2021-01-14 09:06:33 +0800] [14269] [DEBUG] 5 workers | |||
[2021-01-14 09:06:33 +0800] [14269] [INFO] Handling signal: term | |||
[2021-01-14 09:06:35 +0800] [17476] [INFO] Worker exiting (pid: 17476) | |||
[2021-01-14 09:06:35 +0800] [17481] [INFO] Worker exiting (pid: 17481) | |||
[2021-01-14 09:06:35 +0800] [17511] [INFO] Worker exiting (pid: 17511) | |||
[2021-01-14 09:06:35 +0800] [17518] [INFO] Worker exiting (pid: 17518) | |||
[2021-01-14 09:06:35 +0800] [17510] [INFO] Worker exiting (pid: 17510) | |||
[2021-01-14 09:06:35 +0800] [17512] [INFO] Worker exiting (pid: 17512) | |||
[2021-01-14 09:06:35 +0800] [17509] [INFO] Worker exiting (pid: 17509) | |||
[2021-01-14 09:06:35 +0800] [14269] [INFO] Shutting down: Master |
@ -0,0 +1,4 @@ | |||
# pack-refs with: peeled fully-peeled sorted | |||
326f368eeaac6faa708e788440893c1d39acf864 refs/remotes/origin/develop | |||
42295b43602cb2dd7896c365a821f6d6afba4672 refs/remotes/origin/feature | |||
549e8bab6eb6120bd84ff14324503868ec124b4e refs/remotes/origin/master |
@ -0,0 +1,31 @@ | |||
blinker==1.4 | |||
bootstrap-flask==1.2.0 | |||
click==7.1.1 | |||
flask-avatars==0.2.2 | |||
flask-dropzone==1.5.4 | |||
flask-login==0.5.0 | |||
flask-mail==0.9.1 | |||
flask-moment==0.9.0 | |||
flask-sqlalchemy==2.4.1 | |||
flask-whooshee==0.7.0 | |||
flask-wtf==0.14.3 | |||
flask==1.1.2 | |||
itsdangerous==1.1.0 | |||
jinja2==2.11.1 | |||
markupsafe==1.1.1 | |||
pillow==7.1.1 | |||
python-dotenv==0.12.0 | |||
sqlalchemy==1.3.15 | |||
werkzeug==1.0.1 | |||
whoosh==2.7.4 | |||
wtforms==2.2.1 | |||
# dev | |||
faker==4.0.2 | |||
pathtools==0.1.2 | |||
python-dateutil==2.8.1 | |||
six==1.14.0 | |||
text-unidecode==1.3 | |||
watchdog==0.10.2 | |||
gunicorn | |||
gevent==1.4 | |||
pymysql |
@ -0,0 +1,7 @@ | |||
from albumy.__init__ import create_app | |||
from flask import Flask | |||
app = create_app() | |||
if __name__ == "__main__": | |||
app.run() |