开始使用Django Ansible部署
将应用程序部署到生产环境是一个复杂的过程,需要许多配置和测试。想象一下,你想把你的应用程序的一个新版本部署到生产中。如果你能确保新版本是稳定的并且与现有版本兼容,那将会有所帮助。
你将需要为每个应用程序版本重复部署步骤。如果你想多次将你的应用程序部署到生产中,手动部署会变得很累。这就是ansible发挥作用的地方。它为我们提供了自动部署过程的能力。
在这篇文章中,我们将部署一个Django应用程序到生产中。除了Django框架和ansible,我们还将使用Nginxwebserver。
先决条件
在你开始这篇文章之前,你需要对以下内容有基本的了解。
- [Django]。
- [Nginx]。
- [Python]编程语言和[Python 3]安装在你的机器上。
应用程序设置
我们将建立一个预算管理应用API,它将允许我们创建、更新和删除预算。
-
通过执行以下命令为我们的项目创建一个新的工作目录。
mkdir deployment -
创建一个新的虚拟环境。
virtualenv deployment/venv -
创建一个新的Django项目。
django-admin startproject budgetmanager -
Django将代码组织成较小的单元,称为应用程序。我们将创建一个名为
budget的新应用。django-admin startapp budget -
由于我们要创建RESTful APIS,我们需要通过安装Django REST框架。
pip install django-rest-framework
模型
Django模型是代表数据库表的对象。例如,我们将创建一个映射到数据库中budgets 表的预算模型。
在budget 应用程序中,在models.py ,添加以下代码。
from django.db import models
class Budget(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
amount = models.PositiveIntegerField()
date_creates = models.DateTimeField(auto_created=True, auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
上面的代码片断包含了预算类和它的属性。__str__ 方法返回预算对象的一个字符串表示。
序列化器
Django序列化器用于将Django模型对象转换为JSON对象。Django REST框架提供了一种序列化和反序列化数据的方法。我们将创建一个序列化器,Django用它来序列化和反序列化预算模型。
- 在
budget应用程序中,创建一个名为serializers.py的新文件。 - 在
budget应用程序中,在serializers.py,添加以下代码。
from rest_framework import serializers
from budget.models import Budget
class BudgetSerializer(serializers.ModelSerializer):
class Meta:
model = Budget
fields = "__all__"
"__all__"是一个特殊的关键字,代表模型的所有字段。
视图
Django视图是用来处理来自客户端的请求。因此,我们将创建一个视图,用来处理来自客户端的请求。
- 在
budget应用程序中,在views.py文件中添加下面的代码片段。
from rest_framework.generics import ListAPIView
from rest_framework.generics import CreateAPIView
from rest_framework.generics import DestroyAPIView
from rest_framework.generics import UpdateAPIView
from budget.models import Budget
from budget.serializer import BudgetSerializer
class ListBudgetAPI(ListAPIView):
"""Retrieves all the budgets available in our database"""
queryset = Budget.objects.all()
serializer_class = BudgetSerializer
class CreateBudgetAPI(CreateAPIView):
"""Creates a new budget in our database"""
queryset = Budget.objects.all()
serializer_class = BudgetSerializer
class UpdateBudgetAPI(UpdateAPIView):
"""Update budget with the id sent through the request url path"""
queryset = Budget.objects.all()
serializer_class = BudgetSerializer
class DeleteBudgetAPI(DestroyAPIView):
"""Deletes a budget whose id has been sent through the url path"""
queryset = Budget.objects.all()
serializer_class = BudgetSerializer
URL配置
Django视图被映射到URL上。我们将创建一个URL配置文件,用于将视图映射到URL上。
- 在
budget应用程序中,创建一个名为urls.py的新文件。 - 在
urls.py文件中添加以下代码片段。
from django.urls import path
from budget import views
urlpatterns = [
path("", views.ListBudgetAPI.as_view(), name="budget_list"),
path("create/", views.CreateBudgetAPI.as_view(), name="create_budget"),
path("update/<int:pk>/", views.UpdateBudgetAPI.as_view(), name="update_budget"),
path("delete/<int:pk>/", views.DeleteBudgetAPI.as_view(), name="delete_budget")
]
我们必须始终在位于项目根目录下的主urls.py 文件中添加各自应用程序的url 配置。
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/budget/', include("budget.urls")),
]
Ansible
Ansible使用yml 文件来配置你的服务器。Ansible的yml 文件也被称为playbooks 。在项目根目录下创建一个名为ansible 的新目录。
系统包
- 在
ansible目录中,创建一个名为packages.yml的新文件。 - 在
packages.yml文件中加入下面的代码片段。
---
- hosts: all
gather_facts: no
tasks:
- name: Running apt update
apt: update_cache=yes
- name: Installing required packages
apt: name={{item}} state=present
with_items:
- fail2ban
- git
- python-pip
- rdiff-backup
- libpq-dev
- uwsgi
- uwsgi-plugin-python
- nginx
上述文件包含我们的应用程序在服务器上运行所需的所有系统包。
更新
- 在
ansible目录中,创建一个名为update.yml的新文件。 - 将以下代码添加到
update.yml文件中。
---
- hosts: all
gather_facts: no
tasks:
- name: Runing system update
apt: update_cache=yes
upgrade=safe
register: result
- debug: var=result.stdout_lines
上面的playbook将在服务器上运行apt update 命令,并运行apt upgrade 命令。
生成SSH密钥
为了使我们的服务器能够连接到GitLab并拉取最新的代码,我们需要生成一个SSH密钥。Ansible将使用这个SSH密钥在我们的服务器和GitLab之间建立一个安全连接。
- 在
ansible目录下,创建一个名为generate_ssh_key.yml的新文件。 - 将下面的代码片段添加到上面创建的
generate_ssh_key.yml文件中。
---
- hosts: all
gather_facts: no
tasks:
- name: Create a new system user
user: name=ubuntu generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa #creates a ssh key in .ssh/id_rsa file
- name: Read SSH public key
slurp: src=/home/ubuntu/.ssh/id_rsa.pub
register: public_key
- debug: msg="{{ public_key['content'] | b64decode }}"
上述游戏手册在我们的服务器上生成了一个SSH密钥,并将其存储在.ssh/id_rsa.pub 文件中。
部署
- 在
ansible目录中,创建一个名为deploy.yml的新文件。 - 将下面的代码片段添加到
deploy.yml文件中。
---
- hosts: all
become: yes
become_user: ubuntu
gather_facts: no
tasks:
- name: pull branch master
git: repo={{ repo_url }}/{{ repo }}.git
dest={{ repo_dir }}
accept_hostkey=yes
- hosts: all
gather_facts: no
tasks:
- name: install python requirements
pip: requirements={{ repo_dir }}/requirements/production.txt extra_args=--upgrade
- hosts: all
become: yes
become_user: ubuntu
gather_facts: no
environment:
DJANGO_SETTINGS_MODULE: "{{ django_project }}.settings.production"
STATIC_ROOT: "{{ static_dir }}"
tasks:
- name: create static_root dir
file: path={{ static_dir }} state=directory mode=0755
- name: django collectstatic
shell: ./manage.py collectstatic --noinput chdir={{ django_dir }}
- name: django migrate
shell: ./manage.py migrate --noinput chdir={{ django_dir }}
- name: django loaddata
shell: ./manage.py loaddata user chdir={{ django_dir }}
- hosts: all
gather_facts: no
tasks:
- name: uwsgi restart
service: name=uwsgi state=restarted
上面的配置将从GitLab中提取最新的代码并安装所需的Python包。它还将
- 创建
static_root目录并运行collectstatic命令来收集所有静态文件。 - 运行
migrate命令来迁移数据库。 - 加载
user固定程序以填充数据库。 - 重新启动
uwsgi服务。
仓库配置
我们需要配置我们的服务器以连接到我们的版本库,从而获取最新的代码。
- 在
ansible目录中,创建一个名为hosts的新文件。 - 将下面的代码片段添加到上面创建的
hosts文件中。
all:
hosts: yourserver
vars:
repo_url: ssh://git@bitbucket.org/user
repo: project
home_dir: /home/ubuntu
repo_dir: "{{ home_dir }}/{{ repo }}"
django_dir: "{{ repo_dir }}/django"
django_project: project
- 把
yourserver改为你的服务器名称,把repo_url改为你的版本库网址。
Ansible shell命令
为了将代码从版本库拉到服务器上,我们需要一个shell命令,从hosts 文件中读取配置,并使用提供的信息将代码从版本库拉到服务器上。
在ansible 目录中,创建一个新的文件,名为ansible.sh 。添加以下代码。
#!/bin/bash
ansible-playbook -i ./hosts $1
上面的代码片断将运行服务器的ansible-playbook 命令。
使用以下命令执行ansible.sh 文件。
./ansible.sh generate_ssh_key.yaml
上面的命令在服务器上生成了一个 SSH 密钥,并将其保存在.ssh/id_rsa.pub 文件中;SSH 密钥也被添加到 Git 仓库中。
一旦SSH密钥被添加到Git仓库中,我们就可以把最新的代码拉到服务器上。执行下面的命令,从仓库中提取最新的代码,并将其部署到服务器上。
./ansible.sh packages.yaml
./ansible.sh update.yaml
./ansible.sh deploy.yaml
每当我们想更新我们的应用程序时,我们只需要执行下面的命令,从仓库拉出最新的代码并部署在服务器上。
./ansible.sh deploy.yaml
总结
我们在本教程中创建了一个预算管理应用程序,并使用Ansible将其部署到生产中。
试着在Django项目中使用Ansible实现自动化部署,以减少手动部署Django应用程序的时间。