- 首页
- 正文
用 ansible的playbook模式来部署Flask
我们之前讲了一些 ansible-playbook的一些语法,今天就简单来讲一下用 ansible的playbook模式来部署Flask
一般部署 Flask 都是采用 nginx + redis + mysql + gunicorn(或者 uwsgi) 的,这里没有使用 supervisor,有需要可以自己加上,还有一些权限和配置都是以最简单的方式配置的,如果要部署到线上,还要加以修改,这里只是作为演示 ansible-playbook 的用法,下面是一些操作的步骤:
准备工作
- 远程服务器的 ip 是 11.11.11.11,这里只测试一台服务器
- 服务器的目录为 /root
- 服务器的的目录 /root/blog 放了整个Flask的项目,这里没有使用 git 模块
- ssh 免密码登录
创建项目的所有目录和文件
创建所有目录和文件
mkdir ansible-role-flask
cd ansible-role-flask
touch hosts playbook.yml
mkdir group_vars
touch group_vars/all
mkdir -p roles/{common,mysql,redis,nginx,gunicorn}/{handlers,tasks,templates}
touch roles/{common,mysql,redis,nginx,gunicorn}/{handlers,tasks}/main.yml
touch roles/nginx/templates/nginx.conf.j2
touch roles/gunicorn/templates/gunicorn.py.j2
整个项目目录结构如下:
├── group_vars
│ └── all
├── hosts
├── playbook.yml
└── roles
├── common
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
├── gunicorn
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ └── gunicorn.py.j2
├── mysql
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
├── nginx
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ └── nginx.conf.j2
└── redis
├── handlers
│ └── main.yml
├── tasks
│ └── main.yml
└── templates
roles 下面的目录说明:
- roles/common 目录用来处理通用的功能,像安装 pip 、利用 git 处理文件上传和解压等等
- roles/mysql 目录用来安装和配置 mysql 的
- role/redis 目录用来安装和配置 redis
- role/gunicorn 目录用来安装和配置 gunicorn
- role/nginx 目录用来安装和配置 nginx
配置资源清单
修改 hosts
的文件,添加以下内容:
[webserver]
11.11.11.11
配置项目用到的变量
修改 group_vars/all
的文件,添加以下内容:
---
mysql_db_username: user
mysql_db_password: user
mysql_db: blog
remote_project_dir: /root/blog
remote_project_env: /root/blog/env
remote_project_gunicorn: /root/blog/gunicorn.py
playbook.yml 的内容
修改 playbook.yml
的文件,添加以下内容:
---
- hosts: webserver
remote_user: root
gather_facts: no
roles:
- { role: common }
- { role: mysql }
- { role: redis }
- { role: gunicorn }
- { role: nginx }
注意:
这里可以添加各种变量和标签之类的
安装 pip 和 Flask 的各种插件
修改 roles/common/tasks/main.yml
,添加以下内容:
---
- name: Install pip and virtualenv package
yum:
name: "{{ item }}"
state: present
with_items:
- epel-release
- python-pip
- libffi-devel
- mysql-devel
- openssl-devel
- python-devel
- python-setuptools
- python-virtualenv
- name: Upgrade pip and setuptools
pip:
chdir: "{{ remote_project_dir }}"
virtualenv: "{{ remote_project_env }}"
virtualenv_command: virtualenv
name: "{{ item }}"
state: latest
with_items:
- pip
- setuptools
- name: Install requirements package
pip:
chdir: "{{ remote_project_dir }}"
virtualenv: "{{ remote_project_env }}"
virtualenv_command: virtualenv
name: "{{ item }}"
with_items:
- flask
- flask-script
- flask-login
- flask-sqlalchemy
- flask-migrate
- flask-wtf
- forgerypy
- flask_whooshalchemyplus
- jieba
- flask-debugtoolbar
- flask-cache
- redis
- flask-bootstrap
- flask-markdown
- flask-misaka
- pygments
- supervisor
- mysql-python
- pypinyin
- flask-mail
- Pillow
说明:
在 安装 Flask 插件也可以 指定 requirements.txt 文件路径来安装,这里是用插件名来进行安装的
mysql 的安装与配置
这里安装的是 mysql5.7 版本
修改 roles/mysql/tasks/main.yml
,添加以下内容:
---
- name: Install the mysql repo
yum:
name: http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
state: present
- name: Install mysql package
yum:
name: "{{ item }}"
state: installed
with_items:
- gcc
- mysql-devel
- mysql-community-server
- mysql-server
- MySQL-python
- name: Start mysql service
service:
name: mysqld
state: started
enabled: yes
- name: Create database user
mysql_user:
name: "{{ mysql_db_username }}"
password: "{{ mysql_db_password }}"
priv: "*.*:ALL"
state: "present"
- name: Create app database
mysql_db:
name: "{{ mysql_db }}"
login_user: "{{ mysql_db_username }}"
login_password: "{{ mysql_db_password }}"
collation: "utf8_general_ci"
encoding: "utf8"
state: "present"
- name: Import blog.sql
mysql_db:
name: "{{ mysql_db }}"
login_user: "{{ mysql_db_username }}"
login_password: "{{ mysql_db_password }}"
state: import
target: "{{ remote_project_dir }}/blog.sql"
说明:
这里没有使用 mysql 的配置文件,root 的用户密码也没有修改,就是添加了一个用户,这里还有很多地方需要修改
redis 的安装与配置
修改 roles/redis/tasks/main.yml
,添加以下内容:
--
- name: Install redis package
yum:
name: redis
state: present
register: redis_installed
- name: Start redis
when: redis_installed|success
service:
name: redis
state: started
说明:
这里可以使用 redis 的配置,禁止外网访问、添加密码验证和禁止一些危险命令等等,来保证 redis 的安全
gunicorn 的配置与安装
修改 roles/gunicorn/tasks/main.yml
,添加以下内容:
---
- name: Install gunicorn
pip:
chdir: "{{ remote_project_dir }}"
virtualenv: "{{ remote_project_env }}"
virtualenv_command: virtualenv
name: gunicorn
register: gunicorn_installed
- name: Create gunicorn template
when: gunicorn_installed|success
template:
src: gunicorn.py.j2
dest: "{{ remote_project_gunicorn }}"
notify:
- Start Gunicorn
修改 roles/gunicorn/handlers/main.yml
,添加以下内容:
---
- name: Start Gunicorn
command: "{{ remote_project_dir }}/env/bin/gunicorn -c {{ remote_project_dir }}/gunicorn.py wsgi:app"
args:
chdir: "{{ remote_project_dir }}"
修改 roles/gunicorn/templates/gunicorn.py.j2
,添加以下内容:
import multiprocessing
bind="127.0.0.1:8000"
workers = multiprocessing.cpu_count() * 2
daemon = True
nginx 的安装与配置
修改 roles/nginx/tasks/main.yml
,添加以下内容:
---
- name: Install nginx package
yum:
name: nginx
state: present
register: nginx_installed
- name: Start nginx
when: nginx_installed|success
service:
name: nginx
state: started
- name: Copy nginx.conf.j2 template
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
backup: yes
mode: 0644
notify:
- Restart nginx service
修改 roles/nginx/handlers/main.yml
,添加以下内容:
---
- name: Restart nginx service
service:
name: nginx
state: restarted
修改 roles/nginx/templates/nginx.conf.j2
,添加以下内容:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
说明:
nginx 这里只是简单地反向代理了 gunicorn 的请示
运行并测试
运行 ansible-playbook
ansible-playbook -i hosts playbook.yml -v -o
在浏览器查看效果
http://11.11.11.11
【上一篇】HTTP 基础(下)