也不意味着工作就结束了。在部署之前,它仍然是无用的并且很容易被其他人访问。部署模型的方法有很多种,我想谈谈一个适用于基本MVP的非常简单的解决方案——使用Flask为模型编写API,使用Gunicorn作为软件服务器,使用Nginx作为Web服务器,以及将其包装在Docker中,以便更轻松地部署到其他机器(尤其是AWS和GCP)上。设置服务器我更喜欢使用专门为此目的租用的服务器来试验新配置,而不是使用个人或工作硬件。那样的话,就算有什么东西被严重损坏了,也没关系。因此,笔者推荐使用Linode。作者自己用它做实验,他们的硬件用起来感觉不错。只要你在Ubuntu18.04LTS上,你就可以随意使用任何其他服务。这部分适合使用Linides的人学习借鉴。导航到Linodes并单击添加Linode。有些东西需要填写。在发行版中,我建议选择Ubuntu18.04LTS映像:区域-离你最近的区域(我使用的是德国法兰克福)Linode计划-Nanode(每月仅需$5,足够远根据需要)root密码-您的密码,然后单击创建。几分钟后,您可以转到网络,您可以在其中找到有关通过SSH访问服务器的信息。下一步应该是连接到服务器并创建一个具有sudo权限的非根用户。这背后的逻辑相当简单:您不想在服务器上以root身份运行所有内容,因为这样更容易破坏。adduserusernameusermod-aGsudousername最后,切换到新用户。su——用户名创建应用容器整个系统配置分为两部分:应用容器(Flask+Gunicorn)和web容器(Nginxwebserver)。图片来源:unsplash(1)Step0-InstallDockerandDockerComposeDocker和Docker-compose的安装非常简单,分别4行和2行即可完成。(2)Step1-创建FlaskApp和WSGI入口点在主目录中创建flaskapp目录,并将以下文件放入其中。fromflaskimportFlaskserver=Flask(__name__)@server.route('/')defhello_world():return'helloworld!'这是最基本的Flask应用,几乎没有任何功能,不需要加载任何模型,没有添加GET/POST请求和内容(这些将在下面出现)。现在,我们只有一个在主页上显示“helloworld”的应用程序。这部分非常简单-只需为Gunicorn创建一个单独的文件以在端口8000上运行。(3)第2步-为Flask创建一个Docker镜像现在我们需要创建一个将使用这些文件的Dockerfile并创建一个将运行的镜像之后。FROMpython:3.6.7WORKDIRusr/src/flask_appCOPYrequirements.txt.RUNpipinstall--no-cache-dir-rrequirements.txtCOPY..对于那些不熟悉Docker的人,这个脚本执行以下操作:importPython3.6.7imagesetupallfiles工作目录复制包含Flask、Gunicorn和运行Flask应用程序所需的所有其他文件的需求文件。然后,通过RUN命令安装所有必要的包,最后将所有文件从flaskdir复制到容器内的usrscrflask应用程序中。现在只需将此文件放在同一个flask_app目录中并添加requirements.txt。flaskgunicorn请记住,如果您对目录和内容感到困惑,只需查看文章末尾的完整项目结构,或访问GitHub存储库。(4)第三步——创建Nginx文件源:unsplash需要配置一些内容才能运行Nginx。但在进行下一步之前,请在您的主目录中创建nginx目录(与flask_app处于同一级别)。之后,我们需要的第一个文件是nginx.conf,里面包含了几乎所有的Nginx基本信息和变量。来看一个Nginx基本设置:#DefinetheuserthatwillownandruntheNginxserverusernginx;#Definethenumberofworkerprocesses;recommendedvalueisthenumberof#coresthatarebeingusedbyyourserverworker_processes1;#Definethelocationonthefilesystemoftheerrorlog,plustheminimum#severitytologmessagesforerror_log/var/log/nginx/error.logwarn;#DefinethefilethatwillstoretheprocessIDofthemainNGINXprocesspid/var/run/nginx.pid;#eventsblockdefinestheparametersthataffectconnectionprocessing.events{#Definethemaximumnumberofsimultaneousconnectionsthatcanbeopenedbyaworkerproce$worker_connections1024;}#httpblockdefinestheparametersforhowNGINXshouldhandleHTTPwebtraffichttp{#IncludethefiledefiningthelistoffiletypesthataresupportedbyNGINXinclude/etc/nginx/mime.types;#Definethedefaultfiletypethatisreturnedtotheuserdefault_typetext/html;#Definetheformatoflogmessages.log_formatmain'$remote_addr-$remote_user[$time_local]"$request"''$status$body_bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for"';#DefinethelocationofthelogofaccessattemptstoNGINXaccess_log/var/log/nginx/access.logmain;#Definetheparameterstooptimizethedeliveryofstaticcontentsendfileon;tcp_nopushon;tcp_nodelayon;#Definethetimeoutvalueforkeep-aliveconnectionswiththeclientkeepalive_timeout65;#Definetheusageofthegzipcompressionalgorithmtoreducetheamountofdatatotransmit#gzipon;#Includeadditionalparametersforvirtualhost(s)/server(s)include/etc/nginx/conf.d/*.conf;}第二个文件-特定于应用程序的配置有两种更通用的方法可以做到这一点:在/etc/nginx/sites-available/your_project创建一个配置文件,然后创建一个符号链接到/etc/nginx/sites-enabled/your_project在Nginx主目录下新建一个project.conf即可,下面介绍第二种方法。服务器{listen80;server_namedocker_flask_gunicorn_nginx;location/{proxy_passhttp://flask_app:8000;#Donotchangethisproxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for/}location/static)/$1break;root/static;}}有几点需要注意:首先,看一下listen80,它指定了应用程序运行的端口。作为默认端口,我们选择80。第二,服务器名称。您可以指定从Linode获取的IP地址,或者只使用docker镜像名称。最后,代理传递命令,它应该将Nginx配置指向flask项目。由于flask容器的名字是flask_app(后面会介绍),所以直接使用Flask工程中指定的容器名和端口即可。(5)第4步-为Nginx创建Docker镜像这个特定的Docker镜像非常简单。和Flask一样,它只包含5行并且只做2件事:FROMnginx:1.15.8RUNrm/etc/nginx/nginx.confCOPYnginx.conf/etc/nginx/RUNrm/etc/nginx/conf.d/default.confCOPYproject.conf/etc/nginx/conf.d/导入nginx镜像,复制文件,替换为默认文件。(6)Step5-结合Dockerfiles与docker-compose现在有2个Dockerfiles:一个用于Flask+Gunicorn,一个用于Nginx。现在是时候让它们交互并运行整个系统了。为此,使用了docker-compose。我们只需要在我们的主目录中创建docker-compose.yml文件。版本:'3'服务:flask_app:container_name:flask_apprestart:alwaysbuild:./flask_appports:-"8000:8000"command:gunicorn-w1-b0.0.0.0:8000wsgi:servernginx:container_name:nginxrestart:alwaysbuild:./nginxports:-"80:80"depends_on:-flask_app为了理解它是如何工作的,让我们来处理几个重要的问题:首先,docker-compose分为两部分(2个服务):flask_app和nginx。正如您从以下几行中看到的那样-flask_app容器执行运行Flask应用程序的Gunicorn,并使用1个worker将其转换为端口8000。第二个容器只在80端口上运行Nginx。另外,请注意depends_on部分,它指示docker-compose先启动flask_app容器,然后启动---nginx,因为这两个容器相互依赖。图片来源:unsplash此外,还应添加一件事,以便更轻松地运行此Docker设置。那就是run_docker.sh文件。echokillingolddockerprocessesdocker-composerm-fsechobuildingdockercontainersdocker-composeup--build-d此设置仅运行docker-compose,但首先确保此时没有旧的docker进程处于活动状态。(7)第6步-将所有东西放在一起你当前的项目结构应该是这样的:.├──flask_app│├──app.py│├──wsgi.py│└──Dockerfile├──nginx│├──nginx.conf│├──project.conf│└──Dockerfile├──docker-compose.yml└──run_docker.sh一切就绪后,就可以运行docker了。bashrun_docker.sh并通过导航到从Linode获得的IP在浏览器中查看主页:(8)第7步-没有产生任何结果,我该怎么办?先在Linode上租一台服务器,安装docker和docker-compose,然后克隆git仓库,然后运行??bashrun_docker.sh。一旦你确定它运行成功,就开始改变。尝试Flask、Dockerfiles或docker-compose直到出现问题。之后,尝试找出问题所在并加以解决。(9)第8步-下一步是什么?图片来源:unsplash接下来要添加的是FlaskApp中对POST请求的支持。这样,可以向模型发送请求并获得响应。需要满足两件事:一个可以处理请求的模型,以及一个自支撑的POST请求。fromflaskiimportFlask,request,jsonifyserver=Flask(__name__)defrun_request():index=int(request.json['index'])list=['red','green','blue','yellow','black']returnlist[index]@server.route('/',methods=['GET','POST'])defhello_world():ifrequest.method=='GET':return'Themodelisupandrunning.SendaPOSTrequest'else:returnrun_request()为方便起见,在这种情况下,模型仅返回颜色列表的第i个元素。但实际上,运行哪个模型并不重要,只需在所有方法上创建模型的实例(几乎是在您拥有server=Flask(__name__)的地方)。现在,如果您导航到该IP地址,您将看到一条消息-“模型已启动并正在运行。正在发送POST请求”,因为只要转到该IP就会将其视为GET请求。但是让我们尝试使用包含模型索引的json文件发送POST请求。我使用Postman,但您可以根据自己的喜好使用它(即Curl)。作品!现在,您可以添加其他路径来接收GET/POST请求。这个想法背后的原因是可以通过加载多个模型来根据URL向特定模型发送请求。(10)第9步-进一步发展如何?实际上,还有一个更重要的步骤需要完成。为了快速部署此Docker设置,最好将其部署在云空间中。这种方法的一个主要优势是:AWS将提供集群管理基础设施。你学会了吗?
