如何使用 ansible 在远程机器上激活 python 虚拟环境?
How to activate python virtual environment on remote machine with ansible?
我正在学习 Vagrant 和 Ansible,我正在尝试使用 Nginx 在 ubuntu20.04 中为基本的 flask 应用程序设置本地开发环境。
我的 vagrantfile 看起来像这样:
Vagrant.configure("2") do |config|
config.vm.define :ubuntuserver do | ubuntuserver |
ubuntuserver.vm.box = "bento/ubuntu-20.04"
ubuntuserver.vm.hostname = "ubuntuserver"
ubuntuserver.vm.provision :ansible do | ansible |
ansible.playbook = "development.yml"
end
ubuntuserver.vm.network "private_network", ip:"10.11.1.105"
ubuntuserver.vm.network "forwarded_port", guest: 80, host: 8080
ubuntuserver.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
ubuntuserver.vm.provider :virtualbox do |vb|
vb.memory = "1024"
end
ubuntuserver.vm.synced_folder "./shared", "/var/www"
end
end
我的 ansible-playbook 是这样的:
-
name: local env
hosts: ubuntuserver
tasks:
- name: update and upgrade apt packages
become: yes
apt:
upgrade: yes
update_cache: yes
- name: install software properties common
apt:
name: software-properties-common
state: present
- name: install nginx
become: yes
apt:
name: nginx
state: present
update_cache: yes
- name: ufw allow http
become: yes
community.general.ufw:
rule: allow
name: "Nginx HTTP"
- name: installing packages for python env
become: yes
apt:
name:
- python3-pip
- python3-dev
- build-essential
- libssl-dev
- libffi-dev
- python3-setuptools
- python3-venv
update_cache: yes
- name: Create app directory if it does not exist
ansible.builtin.file:
path: /var/www/app
state: directory
mode: '0774'
- name: Install virtualenv via pip
become: yes
pip:
name: virtualenv
executable: pip3
- name: Set python virual env
command:
cmd: virtualenv /var/www/app/ -p python3
creates: "/var/www/app/"
- name: Install requirements
pip:
requirements: /var/www/requirements.txt
virtualenv: /var/www/app/appenv
virtualenv_python: python3
我的剧本在下一个任务中失败并出现错误:
- name: Activate /var/www/app/appenv
become: yes
command: source /var/www/app/appenv/bin/activate
fatal: [ubuntuserver]: FAILED! => {"changed": false, "cmd": "source /var/www/app/appenv/bin/activate", "msg": "[Errno 2] No such file or directory: b'source'", "rc": 2}
剧本的其余部分
- name: ufw allow 5000
become: yes
community.general.ufw:
rule: allow
to_port: 5000
- name: Run app
command: python3 /var/www/app/appenv/app.py
根据我在 this 线程中的理解,必须从 vagrant 机器内部使用“source”命令。 (我尝试了线程中的解决方案但无法让它工作)
如果我 ssh 进入 vagrant 机器并手动执行我的剧本的最后三个命令:
source /var/www/app/appenv/bin/activate
sudo ufw allow 5000
python3 /var/www/app/appenv/app.py
我的基本 Flask 应用程序 运行 在 vagrantfile 10.11.1.105 中设置的 IP 端口 5000 上
我的问题是:
我怎样才能让 playbook 工作而不必通过 ssh 进入机器来完成同样的事情?
我的方法是否正确,知道我的最终目标是在 vagrant 机器中复制一个与生产环境类似的环境,并从 synced folder 中的本地机器开发 flask 应用程序?
提供最多的信息,如果有人想重现这个。
我还有一个 shared/app/appenv/app.py 文件,其中包含基本的烧瓶应用程序
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
和shared/requirements.txt文件
wheel
uwsgi
flask
我为 Linux 台 Python 3.x 的计算机写了这篇文章。在这种情况下,这是您的 Ansible 开发机器。首先,验证安装的 Python 版本和路径:
# check Python version
$ python3 -V
Python 3.6.8
$ which python3
/usr/bin/python3
我建议为虚拟环境设置一个目录:
$ mkdir python-venv
$ cd !$
创建新的虚拟环境
$ python3 -m venv ansible2.9
$ ls
ansible2.9
激活python venv
$ source ansible2.9/bin/activate
(ansible2.9)$ python3 -V
Python 3.6.8
升级点数
(ansible2.9)$ python3 -m pip install --upgrade pip
在虚拟环境中安装Ansible
(ansible2.9)$ python3 -m pip install ansible==2.9
(ansible2.9)$ which ansible
~/python-venv/ansible2.9/bin/ansible
验证您的新安装:
(ansible2.9)$ ansible --version
ansible 2.9.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/devops/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/devops/python-venv/ansible2.9/lib64/python3.6/site-packages/ansible
executable location = /home/devops/python-venv/ansible2.9/bin/ansible
python version = 3.6.8 (default, Jan 09 2021, 10:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
安装 Ansible 角色或集合
(ansible2.9)$ ansible-galaxy collection install \
kubernetes.core:==1.2.1 -p collections
停用 Python 虚拟环境
(ansible2.9)$ deactivate
为 Ansible 3.0
创建另一个 Python 虚拟环境
$ python3 -m venv ansible3.0
$ ls -1
ansible2.9
ansible3.0
$ source ansible3.0/bin/activate
(ansible3.0)$ which python
~/python-venv/ansible3.0/bin/python
(ansible3.0)$ python3 -m pip install --upgrade pip
(ansible3.0)$ python3 -m pip install ansible==3.0
这个问题来自对 python venv 的误解。
我认为为了在虚拟环境中安装软件包,它必须被激活。
例如:
source env/bin/activate
pip install package_name
后来我明白了我可以在 venv 中安装软件包而不激活它:
env/bin/pip install package_name
所以ansible的解决方案不是激活venv来安装包,而是
- name: "Install python packages with the local instance of pip"
shell: "{{virtualenv_path}}/bin/pip3 install package_name"
become: no
甚至使用 pip 模块和 requirements.txt 文件中的包更好:
- name: Install project requirements in venv
pip:
requirements: '{{project_path}}/requirements.txt'
virtualenv: '{{virtualenv_path}}'
virtualenv_python: python3
我正在学习 Vagrant 和 Ansible,我正在尝试使用 Nginx 在 ubuntu20.04 中为基本的 flask 应用程序设置本地开发环境。
我的 vagrantfile 看起来像这样:
Vagrant.configure("2") do |config|
config.vm.define :ubuntuserver do | ubuntuserver |
ubuntuserver.vm.box = "bento/ubuntu-20.04"
ubuntuserver.vm.hostname = "ubuntuserver"
ubuntuserver.vm.provision :ansible do | ansible |
ansible.playbook = "development.yml"
end
ubuntuserver.vm.network "private_network", ip:"10.11.1.105"
ubuntuserver.vm.network "forwarded_port", guest: 80, host: 8080
ubuntuserver.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
ubuntuserver.vm.provider :virtualbox do |vb|
vb.memory = "1024"
end
ubuntuserver.vm.synced_folder "./shared", "/var/www"
end
end
我的 ansible-playbook 是这样的:
-
name: local env
hosts: ubuntuserver
tasks:
- name: update and upgrade apt packages
become: yes
apt:
upgrade: yes
update_cache: yes
- name: install software properties common
apt:
name: software-properties-common
state: present
- name: install nginx
become: yes
apt:
name: nginx
state: present
update_cache: yes
- name: ufw allow http
become: yes
community.general.ufw:
rule: allow
name: "Nginx HTTP"
- name: installing packages for python env
become: yes
apt:
name:
- python3-pip
- python3-dev
- build-essential
- libssl-dev
- libffi-dev
- python3-setuptools
- python3-venv
update_cache: yes
- name: Create app directory if it does not exist
ansible.builtin.file:
path: /var/www/app
state: directory
mode: '0774'
- name: Install virtualenv via pip
become: yes
pip:
name: virtualenv
executable: pip3
- name: Set python virual env
command:
cmd: virtualenv /var/www/app/ -p python3
creates: "/var/www/app/"
- name: Install requirements
pip:
requirements: /var/www/requirements.txt
virtualenv: /var/www/app/appenv
virtualenv_python: python3
我的剧本在下一个任务中失败并出现错误:
- name: Activate /var/www/app/appenv
become: yes
command: source /var/www/app/appenv/bin/activate
fatal: [ubuntuserver]: FAILED! => {"changed": false, "cmd": "source /var/www/app/appenv/bin/activate", "msg": "[Errno 2] No such file or directory: b'source'", "rc": 2}
剧本的其余部分
- name: ufw allow 5000
become: yes
community.general.ufw:
rule: allow
to_port: 5000
- name: Run app
command: python3 /var/www/app/appenv/app.py
根据我在 this 线程中的理解,必须从 vagrant 机器内部使用“source”命令。 (我尝试了线程中的解决方案但无法让它工作) 如果我 ssh 进入 vagrant 机器并手动执行我的剧本的最后三个命令:
source /var/www/app/appenv/bin/activate
sudo ufw allow 5000
python3 /var/www/app/appenv/app.py
我的基本 Flask 应用程序 运行 在 vagrantfile 10.11.1.105 中设置的 IP 端口 5000 上
我的问题是:
我怎样才能让 playbook 工作而不必通过 ssh 进入机器来完成同样的事情?
我的方法是否正确,知道我的最终目标是在 vagrant 机器中复制一个与生产环境类似的环境,并从 synced folder 中的本地机器开发 flask 应用程序?
提供最多的信息,如果有人想重现这个。 我还有一个 shared/app/appenv/app.py 文件,其中包含基本的烧瓶应用程序
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
和shared/requirements.txt文件
wheel
uwsgi
flask
我为 Linux 台 Python 3.x 的计算机写了这篇文章。在这种情况下,这是您的 Ansible 开发机器。首先,验证安装的 Python 版本和路径:
# check Python version
$ python3 -V
Python 3.6.8
$ which python3
/usr/bin/python3
我建议为虚拟环境设置一个目录:
$ mkdir python-venv
$ cd !$
创建新的虚拟环境
$ python3 -m venv ansible2.9
$ ls
ansible2.9
激活python venv
$ source ansible2.9/bin/activate
(ansible2.9)$ python3 -V
Python 3.6.8
升级点数
(ansible2.9)$ python3 -m pip install --upgrade pip
在虚拟环境中安装Ansible
(ansible2.9)$ python3 -m pip install ansible==2.9
(ansible2.9)$ which ansible
~/python-venv/ansible2.9/bin/ansible
验证您的新安装:
(ansible2.9)$ ansible --version
ansible 2.9.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/devops/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/devops/python-venv/ansible2.9/lib64/python3.6/site-packages/ansible
executable location = /home/devops/python-venv/ansible2.9/bin/ansible
python version = 3.6.8 (default, Jan 09 2021, 10:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
安装 Ansible 角色或集合
(ansible2.9)$ ansible-galaxy collection install \
kubernetes.core:==1.2.1 -p collections
停用 Python 虚拟环境
(ansible2.9)$ deactivate
为 Ansible 3.0
创建另一个 Python 虚拟环境$ python3 -m venv ansible3.0
$ ls -1
ansible2.9
ansible3.0
$ source ansible3.0/bin/activate
(ansible3.0)$ which python
~/python-venv/ansible3.0/bin/python
(ansible3.0)$ python3 -m pip install --upgrade pip
(ansible3.0)$ python3 -m pip install ansible==3.0
这个问题来自对 python venv 的误解。 我认为为了在虚拟环境中安装软件包,它必须被激活。 例如:
source env/bin/activate
pip install package_name
后来我明白了我可以在 venv 中安装软件包而不激活它:
env/bin/pip install package_name
所以ansible的解决方案不是激活venv来安装包,而是
- name: "Install python packages with the local instance of pip"
shell: "{{virtualenv_path}}/bin/pip3 install package_name"
become: no
甚至使用 pip 模块和 requirements.txt 文件中的包更好:
- name: Install project requirements in venv
pip:
requirements: '{{project_path}}/requirements.txt'
virtualenv: '{{virtualenv_path}}'
virtualenv_python: python3