发布于:2021-01-20 11:27:02
0
852
0
如果生产服务器不能访问Internet或内部网络,则需要将Python依赖项(作为轮文件)和解释器与源代码捆绑在一起。
本文将介绍如何打包一个Python项目,以便在一台使用Docker与Internet断开连接的机器上进行内部分发。
目标
在这篇文章的结尾,您将能够……
描述Python wheels和egg之间的区别
说明为什么您可能要在Docker容器中构建Python wheel文件
启动自定义环境以使用Docker构建Python wheels
将Python项目捆绑并部署到无需访问Internet的环境
解释如何将该部署设置视为不变的
场景
这篇文章的起源来自一个场景,在这个场景中,由于安全原因,我不得不将一个遗留的Python 2.7 Flask应用程序分发到一个Centos 5盒子中,而这个盒子无法访问Internet。
Python wheels(而不是eggs)是这里的方法。
Python wheels文件与eggs类似,因为它们都是只是用来分发代码的zip文件。wheels的不同之处在于它们是可安装的,但不是可执行的。它们也是预编译的,这样用户就不用自己构建包了;因此,加快了安装过程。可以将它们看作是Python eggs的更轻的预编译版本。它们特别适合于需要编译的包,如lxml或NumPy。
这样,wheels应该建立在运行它们的相同环境上,因此,使用多个版本的Python跨多个平台构建它们可能是一个巨大的难题。
这就是Docker发挥作用的地方。
Bundle
在开始之前,需要注意的是,我们将使用Docker简单地启动一个构建wheels的环境。换句话说,我们将使用Docker作为构建工具,而不是部署环境。
此外,请记住,此过程不仅适用于旧版应用程序,还可用于任何Python应用程序。
堆栈:
OS: Centos 5.11
Python version: 2.7
App: Flask
WSGI: gunicorn
Web server: Nginx
环境设置
我们将在本节中通过网络下载和安装依赖项。假设您通常不需要设置服务器本身;它应该已经预先配置好了。
由于控制盘是在Centos 5.11环境下构建的,因此几乎可以在任何Linux环境下工作。因此,如果您想继续,请使用最新版本的Centos启动一个Digital Ocean droplet。
SSH into the box,作为root用户,在继续本教程之前,请添加安装Python所需的依赖项:
$ yum -y install
gzipzlib
zlib-devel
gcc
openssl-devel
sqlite-devel
bzip2-devel
接下来,安装并运行Nginx:
$ yum -y install
epel-release
nginx
$ sudo /etc/init.d/nginx start
在浏览器中导航到服务器的IP地址。您应该看到默认的Nginx测试页面。
接下来,更新/etc/Nginx/conf.d中的Nginx配置/默认.conf要重定向流量:
server {
listen 80;
listen [::]:80;
location / {
proxy_pass http://127.0.0.1:1337;
}
}
重新启动Nginx:
$ service nginx restart
现在您应该在浏览器中看到502错误。
在框中创建常规用户:
$ useradd$ passwd
退出完成后的环境。
部署
要部署,首先通过tarball和安装脚本手动保护副本,setup.sh,到远程框:
$ scp app-v20180119.tar.gz@:/home/$ scp setup.sh@:/home/
快速查看安装脚本:
#!/bin/bash
USAGE_STRING="USAGE: sh setup.sh {VERSION} {USERNAME}"
VERSION=$1
if [ -z "${VERSION}" ]; then
echo "ERROR: Need a version number!" >&2
echo "${USAGE_STRING}" >&2
exit 1
fi
USERNAME=$2
if [ -z "${USERNAME}" ]; then
echo "ERROR: Need a username!" >&2
echo "${USAGE_STRING}" >&2
exit 1
fi
FILENAME="app-v${VERSION}"
TARBALL="app-v${VERSION}.tar.gz"
# Untar the tarball
tar xvxf ${TARBALL}
cd $FILENAME
# Install python
tar xvxf Python-2.7.14.tar.xz
cd Python-2.7.14
./configure
--prefix=/home/$USERNAME/python2.7
--with-zlib-dir=/home/$USERNAME/lib
--enable-optimizations
echo "Running MAKE =================================="
make
echo "Running MAKE INSTALL ==================================="
make install
echo "cd USERNAME/FILENAME ==================================="
cd /home/$USERNAME/$FILENAME
# Install pip and virtualenv
echo "python get-pip.py ==================================="
/home/$USERNAME/python2.7/bin/python get-pip.py
echo "python -m pip install virtualenv ==================================="
/home/$USERNAME/python2.7/bin/python -m pip install virtualenv
# Create and activate a new virtualenv
echo "virtualenv venv ==================================="
/home/$USERNAME/python2.7/bin/virtualenv venv
echo "source activate ==================================="
source venv/bin/activate
# Install python dependencies
echo "install wheels ==================================="
pip install wheels/*
这应该相当简单:这个脚本只是设置一个新的Python环境和在新的虚拟环境中安装依赖项。
将SSH放入框中并运行安装脚本:
$ ssh@$ sh setup.sh 20180119
这将需要几分钟。完成后,cd
进入app目录并激活虚拟环境:
$ cd app-v20180119
$ source venv/bin/activate
运行测试:
$ python test.py
完成后,启动gunicorn作为守护程序:
$ gunicorn -D -b 0.0.0.0:1337 app:app
结论
在本文中,我们研究了如何打包一个带有Docker和Pythonwheels的Python项目,以便在与Internet断开的机器上部署。
通过这种设置,由于我们打包了代码、依赖项和解释器,我们的部署被认为是不可变的。对于每个新部署,我们将启动一个新环境,并在关闭旧环境之前进行测试以确保其正常工作。这将消除继续在遗留代码之上部署时可能出现的任何错误或问题。另外,如果您发现了新部署的问题,您可以轻松回滚。
作者介绍