Zero time deploy of Laravel project with Ansible
In this post I’d like to introduce yet another solution for zero time deployment of laravel project. My solution is based on ansible. Ansible is an open-source automation engine that automates software provisioning, configuration management, and application deployment.
Suppose you recently created fresh droplet on digitalocean.com with Ubuntu 16.04. To run new website on this server you need to do many things:
- add new user, grant him sudo access
- configure sshd: prevent root login, disable password authentication
- configure iptables and fail2ban
- configure automatic security updates
- configure timezone
- install php, nginx, mysql
- install ssl sertificate
- create swap file
To make life easier I created repository, which contains ansible playbook to do all the things listed above.
Firstly, you need to install ansible (I assume you are using Ubuntu 16.04).
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
Then you need to clone my repository, which contains ansible playbooks for laravel project deployment and server provision, and install dependencies.
git clone https://github.com/melihovv/initial-webserver-setup
cd initial-webserver-setup
ansible-galaxy install -r requirements.yml
After that copy vars/main.yml.example
to vars/main.yml
and change variables values for your needs. You need to specify
- your user name, which will be created on server
- his password
in hashed form, usesudo install -y whois && mkpasswd --method=SHA-512
- your public key
- your email, to which letsencrypt will send notifications
- timezone
- domain of your site
- link to your repository
- take a look for other variables and change them if you need, comments provided to them
Also specify ip address of your server in inventory
file in the root of repository.
[web]
46.101.210.137
Then type in your terminal
ansible-playbook initial-setup.yml
This playbook will install python2 and aptitude, which are necessary for ansible to work. Also this playbook creates user with sudo rights and configures sshd.
Now place nginx config for your site in roles/nginx/templates/<your-site>.j2
and config for php-fpm pool in roles/php/templates/<your-pool>.conf.j2
. Example of such configs you can find here.
Now type in your terminal
ansible-playbook setup.yml
This playbook will
- install git, ntp, vim, tmux, htop, curl, unzip
- configure automatic security updates (do not reloads server, only installs updates)
- setup timezone
- configure iptables and fail2ban
- create swap file
- setup ssl certificate with letsencrypt
- install node.js, npm and yarn
- install nginx
- install php and composer
- install mysql
- creates folders structure for zero time deployment
If you need to run only some of these steps, type in your terminal
ansible-playbook setup.yml --tags=user,nginx
If you need to exclude some of these steps, type in your terminal
ansible-playbook setup.yml --skip-tags=user,nginx
Now link your .env
file to /path/to/initial-webserver-setup/files/.env
. And you are ready to deploy! Type in your terminal
ansible-playbook deploy
That is it! Enjoy!
How zero time deployment organized?
What is under the hood of deploy.yml?
- clone repository
- set correct permissions
- link
/path/to/release/storage
to/path/to/domain/persistent/storage
- install composer dependencies
- link
/path/to/release/.env
to/path/to/domain/persistent/.env
- install npm dependencies and generate assets
- optimize laravel application
- backup database
- run new migrations
- link
/path/to/domain/current
to/path/to/domain/releases/new-release
- delete all, but 10 latest releases
If build fails
- rollback migrations
- remove new release folder
- link
/path/to/domain/current
to/path/to/domain/releases/last-success-release
Feel free to comment out features you don’t need, customize them or write your own.