diff --git a/COMMIT_EDITMSG b/COMMIT_EDITMSG
new file mode 100644
index 0000000..a34af0e
--- /dev/null
+++ b/COMMIT_EDITMSG
@@ -0,0 +1 @@
+README CHANGE
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..415dc17
--- /dev/null
+++ b/Dockerfile
@@ -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"]
diff --git a/FETCH_HEAD b/FETCH_HEAD
new file mode 100644
index 0000000..62c1bea
--- /dev/null
+++ b/FETCH_HEAD
@@ -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
diff --git a/HEAD b/HEAD
new file mode 100644
index 0000000..7ee7e4f
--- /dev/null
+++ b/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/develop
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ef2a417
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/ORIG_HEAD b/ORIG_HEAD
new file mode 100644
index 0000000..06dbb81
--- /dev/null
+++ b/ORIG_HEAD
@@ -0,0 +1 @@
+c4729ee28f6cff91fd35196a61d75723434b9c5a
diff --git a/Pipfile b/Pipfile
new file mode 100644
index 0000000..b80b0bc
--- /dev/null
+++ b/Pipfile
@@ -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 = "*"
diff --git a/Pipfile.lock b/Pipfile.lock
new file mode 100644
index 0000000..52f5349
--- /dev/null
+++ b/Pipfile.lock
@@ -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"
+        }
+    }
+}
diff --git a/README.md b/README.md
index 60142cd..95e08f1 100644
--- a/README.md
+++ b/README.md
@@ -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,同上)
+
+   ![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/压测albumy.png)
+
+不重启主机,对测试主机配置后开始测试:
+        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中拉取镜像运行即可。
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/docker_image.png)
+
+新建云主机,安装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
+```
+
+将我们启动好的三台云主机啊加到我们的负载均衡当中
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/负载均衡.png)
+
+使用负载均衡之后的压测效果更好
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/压测albumy.png)
+
+### 三、连接云数据库
+
+为了保证负载均衡的服务器的数据一致性,我们将数据库挂在到云数据库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状态则
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/错误1.png)
+
+查看创建日志,发现是容器创建失败,谷歌不能访问,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的教育云出问题了之前第八次实验的时候还可以用,现在就不可以用了。
+
+)
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/错误2.png)
+
+解决方法如下,从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
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/docker镜像.png)
+
+ucloud上docker部署镜像名:docker_nginx_mysql
+
+![](http://106.75.225.141/guoteng/albumy/raw/develop/readme_image/镜像.png)
+
+集群部署有点问题被墙了。
+
diff --git a/albumy-master.iml b/albumy-master.iml
new file mode 100644
index 0000000..91e2f1b
--- /dev/null
+++ b/albumy-master.iml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <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="$MODULE_DIR$/albumy/templates" />
+      </list>
+    </option>
+  </component>
+</module>
\ No newline at end of file
diff --git a/config b/config
new file mode 100644
index 0000000..12878cc
--- /dev/null
+++ b/config
@@ -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
diff --git a/description b/description
new file mode 100644
index 0000000..498b267
--- /dev/null
+++ b/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/gconfig.py b/gconfig.py
new file mode 100644
index 0000000..8a5845c
--- /dev/null
+++ b/gconfig.py
@@ -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'
+
diff --git a/index b/index
new file mode 100644
index 0000000..5438156
Binary files /dev/null and b/index differ
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..bf8b9e5
--- /dev/null
+++ b/main.py
@@ -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/
diff --git a/nginx_flask.conf b/nginx_flask.conf
new file mode 100644
index 0000000..95bfe6d
--- /dev/null
+++ b/nginx_flask.conf
@@ -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;
+    }
+}
+
diff --git a/nohup.out b/nohup.out
new file mode 100644
index 0000000..4f0a4f1
--- /dev/null
+++ b/nohup.out
@@ -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
diff --git a/packed-refs b/packed-refs
new file mode 100644
index 0000000..b44eac8
--- /dev/null
+++ b/packed-refs
@@ -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
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..e5bd62d
--- /dev/null
+++ b/requirements.txt
@@ -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
diff --git a/run.py b/run.py
new file mode 100644
index 0000000..db9c03f
--- /dev/null
+++ b/run.py
@@ -0,0 +1,7 @@
+from albumy.__init__ import create_app
+from flask import Flask
+
+app = create_app()
+
+if __name__ == "__main__":
+    app.run()
\ No newline at end of file