Ansible is a scripting language mostly used to automate installing applications, deploying apps etc..
You may think why to learn a new language if I can do the same using shell scripts, well that's ok but in my opinion ansible doesn't take much time to learn and shell scripts could become complex as the projects scale up. You can read further details over here(https://news.ycombinator.com/item?id=6431552).
Before we start it's important that you have an overview of uwsgi and Nginx configurations to deploy a project. You can look over this(http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html) beautiful and simple docs.
Recomended: pip install ansible
Archlinux: pacman -S ansible Note: archlinux uses python3 as default so you need to create a file /etc/ansible/group_vars/all and paste: --- ansible_python_interpreter: /usr/bin/python2
Ubuntu:
sudo apt-add-repository ppa:ansible/ansible sudo apt-get update sudo apt-get install ansible
Create /etc/ansible/hosts file with
[server1] your_server_ip_address_here
and execute: ansible all -m ping
you will get a response as pong. The above command executes ping over all servers to specify any group(specific servers) then execute: ansible server1 -m ping
Note: Here I assume Ubuntu 14.04 server and ssh permission to it.
Let's install vim over the server.
First provide the IP address in /etc/ansible/hosts file
[my_server] my_server_ip_address
Now create a task file. Ansible uses yml language.
create script.yml and paste the following
--- - name: install vim package apt: name=vim state=latest force=yes
Now create a playbook which runs above created role over specified hosts:
create playbook.yml with the following
--- - hosts: my_server remote_user: root roles: - script
ansible-playbook playbook.yml
The above script installs latest vim package with apt-get package manager.
First, before updating we have to create grub file as some packages require it. So create update_ubuntu.yml file with
--- - name: check grub file # task name shell: test -f /boot/grub/menu.lst # shell module is no different than executing a command in shell eg: /bin/sh register: grub_file # store the result of a shell command in grub_file failed_when: False # silently fail when there are errors - name: update grub command: "sudo update-grub -y" # different from shell module as this does not have access to variables like $HOME etc.. environment: DEBIAN_FRONTEND: noninteractive # suppress debconf questions when: grub_file.rc != 0 - name: update apt-packages apt: "upgrade=dist update_cache=yes" # uses apt module to upgrade distribution
Now as before creating a playbook with required configs:
In playbook.yml:
--- - hosts: my_server remote_user: root roles: - update_ubuntu
Create file django_project.yml and paste:
Note: project_name is provided in the playbook.yml file.
--- - name: Install required apt-packages apt: "name='{{ item }}' state=present force=yes" # this is like looping through all the items provided and install each respectively. with_items: - python-dev - python-virtualenv - python-pip - openjdk-7-jre-headless - libjpeg8-dev - zlib1g-dev - libfreetype6-dev - liblcms2-dev - libwebp-dev - libtiff-dev - tcl-dev - tk-dev - python-tk - redis-server - git - ruby - name: Creates directory file: "path=/home/{{project_name}} state=directory" # similar to mkdir this creates directory given by project_name - name: create virtualenv and install django in it pip: "name=django virtualenv=/home/{{project_name}}/env virtualenv_command=virtualenv" - name: install a django project command: "/home/{{project_name}}/env/bin/django-admin.py startproject {{project_name}} chdir=/home/{{project_name}}/"
--- - hosts: my_server remote_user: root roles: - { role: django_project, project_name: 'mysite' }
run ansible-playbook playbook.yml
That's it, your django project is created.
The supervisor is just a process control system like it starts or stops an instance. Here we control uwsgi service using su
Things that we need here are the configuration files, ansible uses jinja2 template for configurations.
First create uwsgi template:
create uwsgi.j2 file and paste:
[uwsgi] chdir = /home/{{project_name}}/{{project_name}}/ module = {{project_name}}.wsgi home = /home/{{project_name}}/env master = true processes = 4 socket = /home/{{project_name}}/{{project_name}}.sock chmod-socket = 666 vacuum = true harakiri = 60 max-requests = 5000
For running uwsgi in emperor mode we use supervisor.
Create configuration for supervisor, so create uwsgi_server.j2 jinja2 template and paste:
[program:uwsgi-runner] stdout_logfile = /var/log/supervisor/uwsgi-runner-out.log stderr_logfile = /var/log/supervisor/uwsgi-runner-err.log logfile_maxbytes = 50MB logfile_backups = 10 command = /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals
In nginx.j2 paste:
upstream {{project_name}} { server unix:///home/{{project_name}}/{{project_name}}.sock; } server { listen {{ server_port }}; server_name {{ server_name }}; charset utf-8; client_max_body_size 75M; error_log {{nginx_error_log}}; location / { uwsgi_pass {{project_name}}; include uwsgi_params; } location /static { alias /home/{{project_name}}/{{project_name}}/static; expires 365d; } location /media { alias /home/{{project_name}}/{{project_name}}/media; expires 365d; } location /player/private/media/ { alias /home/{{project_name}}/{{project_name}}/media/; } location /robots.txt { root /home/{{project_name}}/{{project_name}}/static/; } location /favicon.ico { root /home/{{project_name}}/{{project_name}}/static/; } }
In step 7 we create roles using these templates.
Create uwsgi_django_setup.yml file and include:
--- - name: Install python-dev apt: "name='python-dev' state=present force=yes" - name: Install python-pip apt: "name='python-pip' state=present force=yes" - name: install uwsgi pip: name=uwsgi - name: Install supervisor apt: name=supervisor state=present force=yes when: is_installed.rc != 0 - name: Create UWSGI vassals directory file: "path={{vassals_dir}} state=directory" - name: setup uwsgi in supervisor template: "src=uwsgi-server.j2 dest={{supervisor_conf_dir}}/uwsgi-runner.conf" - name: update supervisor supervisorctl: name=uwsgi-runner state=restarted - name: setup project uwsgi configuration file template: "src=uwsgi.j2 dest=/home/{{project_name}}/{{project_name}}_uwsgi.ini" - name: create a symlink of uwsgi in vassals file: "src=/home/{{project_name}}/{{project_name}}_uwsgi.ini dest=/etc/uwsgi/vassals/{{project_name}}_uwsgi.ini state=link" - name: touch the symlink file command: "touch /etc/uwsgi/vassals/{{project_name}}_uwsgi.ini"
create file nginx_django_setup.yml and paste:
--- - name: Install nginx apt: "name='nginx' state=present force=yes" - name: copy nginx config of project template: "src=nginx.j2 dest={{nginx_conf_dir}}/{{project_name}}.conf" - name: copy nginx conf from sites-available to sites-enabled file: "src={{nginx_conf_dir}}/{{project_name}}.conf dest={{nginx_sites_dir}}/{{project_name}}.conf state=link" - name: create project log directory file: "path=/home/{{project_name}}/logs state=directory" - name: start nginx service: "name=nginx state=started"
--- - hosts: my_server remote_user: root roles: - { role: uwsgi_django_setup, project_name: 'mysite'} - { role: nginx_django_setup, project_name: 'mysite' }
Run ansible-playbook playbook.yml, your project will be deployed.
Note: We have hosted these scripts over ansible galaxy. You can pull using:
ansible-galaxy pull micropyramid.django
Micropyramid is a software development and cloud consulting partner for enterprise businesses across the world. We work on python, Django, Salesforce, Angular, Reactjs, React Native, MySQL, PostgreSQL, Docker, Linux, Ansible, git, amazon web services. We are Amazon and salesforce consulting partner with 5 years of cloud architect experience. We develop e-commerce, retail, banking, machine learning, CMS, CRM web and mobile applications.
Django-CRM :Customer relationship management based on Django
Django-blog-it : django blog with complete customization and ready to use with one click installer Edit
Django-webpacker : A django compressor tool
Django-MFA : Multi Factor Authentication
Docker-box : Web Interface to manage full blown docker containers and images
More...