gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Hey guys! Ok, here's my situation: I've built this amazing new app: MooTube: the latest fad in cow fitness. There's just one more problem to solve, before cattle start signing up in herds: the site only lives on my local computer! It's time to release it to the cow masses. Yep, it's time to deploy!
But... how? There are probably 50 good ways to deploy! Bah! And these days, you can even deploy with a Platform as a Service: something like Platform.sh or Heroku. These take care of almost everything for you. I love these, and we use Platform.sh for part of KnpUniversity. They do have some limitations, but they are the fastest way to get your app to production.
In this tutorial, we're going to talk about one, really nice deployment tool: Ansistrano. It's built on top of Ansible... so if you watched our Ansible tutorial, you're going to love it! And if you haven't, what are you waiting for!? Well actually, I'll give you all the details you need, regardless.
As always, learning, like grazing, is best done in a group: so you should definitely code along with me. Download the course code from this page and unzip it. Inside, you'll find a start/
directory, which will have the same code I have here. See that README file? It holds all the secrets for getting the project setup. But actually... this is a tutorial about deployment! So... you don't really need to get the project running locally... because we're going to get the project running... in the cloud!
But, if you do want to get the project running, the last step will be to find your terminal, sip some coffee, and run:
bin/console server:run
to start the built-in PHP web server. Open the app in your browser at http://localhost:8000
. Ah yes, MooTube: our bovine fitness app that is about to stampede through the cow world! This is the same app we used in our Ansible tutorial, with just a few small changes.
Let's get to work! So first... well... we need a server! You can use any service to get a server, but I already booted a new EC2 instance from AWS. I actually did this via Ansible. In our Ansible tutorial, we created a small playbook - aws.yml
- whose only job is to boot an EC2 instance using an Ubuntu 14.04 image.
You're free to get a server from anywhere... but if you do want to use this script to boot a new instance, you'll just need to do 2 things. First, edit the ansible vault at ansible/vars/aws_vault.yml
.
ansible-vault edit ansible/vars/aws_vault.yml
The password is beefpass
.
These access keys are mine... and as much fun as it would be for me to pay for your servers... these keys won't work anymore. Sorry! Replace them with your own. Second, in aws.yml
, see that key_name
?
- hosts: local | |
... lines 3 - 13 | |
tasks: | |
- name: Create an instance | |
ec2: | |
... lines 17 - 21 | |
key_name: KnpU-Tutorial | |
... lines 23 - 31 |
You'll need to create your own "Key Pair" in the EC2 management console, and put its name here. The key pair will give you the private key needed to SSH onto the new server.
Once you have a server... deploying is really two steps. Step 1: provisioning: the fancy word that basically means installing everything you need, like Nginx, PHP, PHP extensions and whatever else. And then step 2: actually deploying.
I don't care how you setup - or provision - your server. In the Ansible tutorial, we - of course! - used Ansible to do this, but that is not a requirement for using Ansistrano.
But since we already have a working provision playbook, let's use it! First, I'll find the public IP address to my new server. Open ansible/hosts.ini
and put this under the aws
group:
... lines 1 - 6 | |
[aws] | |
54.205.128.194 | |
... lines 9 - 13 |
If you're still new to Ansible, we'll talk more about this file once we start to deploy.
Now, run Ansible:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini -l aws
Go Ansible go! See that -l aws
at the end? Well, the provision playbook - playbook.yml
- is setup to provision both my aws
hosts and also a local VirtualBox machine. The -l
tells Ansible to only provisioning the AWS server right now.
Behind the scenes, Ansible is SSH'ing onto the server and running commands. But... how does authentication to the server work? In our case, it's with the private key from the "Key Pair" that we used to boot the server. Open ansible/group_vars/aws.yml
:
ansible_user: ubuntu | |
ansible_ssh_private_key_file: ~/.ssh/KnpU-Tutorial.pem | |
ansible_python_interpreter: /usr/bin/python3 | |
host_server_name: mootube.example.com |
Because we're using the aws
group, this file is automatically loaded. It sets two important variables: ansible_user
and ansible_ssh_private_key_file
.
When you use Ansistrano to deploy, you'll need to make sure these two variables are set... or ansible_ssh_pass
if you're using a password. You don't need to set them in a fancy group variable file like this. If you're still new to Ansible, I'll show you how to create variables right in your deploy playbook later.
For now, just know that we are telling Ansible how to authenticate: there's no magic.
Since Ansible is still working, open a third tab. Let's SSH onto the server: ssh -i
, the path to the private key, then ubuntu@
followed up the IP address:
ssh -i ~/.ssh/KnpU-Tutorial.pem ubuntu@54.XXX.XX.XXX
Perfect! Now... pour a fresh cup of coffee and learn a foreign language while we wait for provisioning to finish. Fast forward!!!!!
Ding! Our server is ready! Check this out! We have PHP 7.1, Nginx and even an Nginx Virtual host.
cd /etc/nginx/sites-available
sudo vim mootube.example.com.conf
Our site will be mootube.example.com
, and this is setup with a document root at /var/www/project/web
. Right now, there is a /var/www/project
directory... but it's empty. Putting code there? Yea, that's the job of this tutorial.
Let's go!
Hey Markus L.
Thanks for sharing it! Windows likes to make things harder than it should be :)
Cheers!
Hey, I've been using a deployment system based off this great tutorial for some time now - it's saved me so many errors before they hit production it's unreal!
I'm now looking to update the underlying ansistrano code - as I would like this in particular. How would you recommend to do that? I see on the ansistrano readme is refers to updating via ansible galaxy, but I don't think that's an option in this case, as the role isn't installed as such in the first place.
Hey Patrick,
I suppose you use requirements.yml file as we do in our screencast: https://symfonycasts.com/sc... . So, you can tweak the version constraint and install the new version of Ansistrano Deploy role. Unfortunately, I don't see any CHANGELOG there, so it's difficult to say if you would have any BC breaks or no after upgrade, but I think you can check descriptions to releases to get a clue what was changed since the version you've installed: https://github.com/ansistra...
I hope this helps!
Cheers!
Hi Victor,
Just to note that this method worked perfectly.
You need to change the name of the role to ansistrano.deploy as it mentions in the tutorial update (it's been changed on Galaxy) but it's working great at version 2.11 with ansible 2.9
Cheers
Patrick
Hi, great tutorial. Is moving working project to ansistrano is complicated? I thought about it and the best way is to: init ansistrano folder structure, get need code from git, then do the rest (like in tutorial, move current files/logs/etc) and than change paths? like nginx vhost (/var/www/project/current/web instead of /var/www/project/web?) and in code if needed?
Hey Krzysiek,
Actually, it's not much complicate than moving an empty project to Ansistrano. You basically need to do the same Symfony framework stuff, like we do in this course, e.g. build assets, clear and warmup the cache, run migrations, etc. Well, sure, it depends on your project complexity, but I think if you watch this course - you will have the exact vision of how complex would be to start using Ansistrano on your project, though I think it's still not too much complex.
and yes, your thoughts sound good to me. Sure, you will have to tweak your Ngixn host to point to a new directory, though, I think you can even avoid this if you make "/var/www/project/web" as a symlink to /var/www/project/current/web. But sure, better is to tweak your Nginx host to avoid 2 symlinks. Anyway, I think we covered MOST cases in this tutorial, so I don't think you will have many unique to your project things when will move your existent project to Ansistrano.
Cheers!
Hey guys!
Just wanted to ask if you will be releasing a tutorial on deploying your symfony application onto your (multiple-server) infrastracture - since we are dealing with this in our company and it's quite a pain in the ass right now!
Thank you
Hey Milan,
Stay tuned, we'll answer your question a bit further in this course. Actually, thanks to the Ansible background, Ansistrano can handle multiple-server deployment as well. If you're wondering about it right now, take a look at: https://knpuniversity.com/s... . So we don't plan any releases on it because it's already released in this course ;)
Cheers!
Hi. I don't want to use Ansible for booting or provisioning my AWS EC2. Instead, I did that using the Console in AWS and I installed LAMP manually by ssh (https://docs.aws.amazon.com.... My server now is working but I wanted to know if I need to install more things. I was reading the playbook.yml file of this tutorial and I only could see that I need Composer. What other things do I need? I hope you can help me because it's my first Symphony deployment.
Hey Cesar,
Yes, you can totally provision your prod server by yourself, but it probably depends on what screencast you're on. So, for the start of this tutorial, you need to download the course code and go to the start/ directory, where you can find ansible/playbook.yml file. Look over it to find out what you need to install. You can also look at finish/ directory to see the difference of what you will need to have on your prod server to the end of tutorial, but going through the tutorial we'll guide you to install more tools if it's needed. For example, on this page: https://knpuniversity.com/s... - we need to install NodeJS and Yarn on your prod server. So here's a list of packages you need to install at the start of this course:
- nginx
- redis
- zip
- unzip
- git
- mysql-server
- php7.1-cli
- php7.1-curl
- php7.1-fpm
- php7.1-intl
- php7.1-mysql
- php7.1-xml
- composer
And also set up date.timezone in php.ini. So all of that I get from start/ansible/playbook.yml file of course code downloaded archive.
Cheers!
Thanks Victor. I am in the first screencast of Ansistrano. So, I want to be sure that I am provisioning my server correctly. Can you tell me how can I check if my server has installed all the packages that you told me? I am using Amazon Linux in a EC2 instance. Sorry if my question is basic but this is my first time. I hope you can help me.
Hey Cesar,
Good question! I'd say run Ansible playbook... but you said you want to provision by yourself :) Seriously, running "ansible/playbook.yml" provision playbook you will see *what* was _changed_ (i.e. installed or updated) and _skipped_ (i.e. was already installed and up to date). So I'd recommend you to review your point of view.
Nevertheless, it's a bit tricky to check was it installed manually, because different packages have different approaches. For example, to check that Composer is installed and what version it has - run "composer --version" in console. To check PHP extensions - run "php -m | grep mysql" or any other extension you need instead of mysql. For Nginx - run "nginx -v", etc. I think you got the idea. Probably there's another, more proper, way to check some packages, but I don't know.
Cheers!
Thanks for the tips Victor. They helped me to provision my server. I am thinking to buy your screencast of Ansible but I am not sure yet. I will see.
Hey Cesar,
You're welcome! Yes, sure, it depends on how much automation do you need. Btw, if you're interested in several tutorials I'd recommend you to look at our monthly subscription but it's up to you.
If you have other questions - just let us know.
Cheers!
Hi Victor. At the end I have bought the Ansible tutorial for provisioning my server and it was a great purchase because it really saves me a lot of time. Now, I have provisioned my server and deployed my app using Ansible and Ansistrano. So, thank you for all your answers and suggestions!
Now, do you have any screencast where you explain how to configure an SSL in the Nginx server using Ansible? I want to put Let's Encrypt for having https. Please, let me know.
Hey Cesar,
I'm glad you like it! Ansible helps with my tasks a lot too ;)
What about configuring SSL - unfortunately, we do not have any screencasts about it yet, and probably do not have any plans on it in the nearest future. But, if you use AWS, you can take a look at AWS ELB, i.e. even if you use only one EC2 instance, you can configure ELB which will help you with SSL configuration - load balancer handle SSL for you. AFAIK, we do so for KnpU SSL certificate. But if you're not on AWS, then probably it's not an option for you.
Cheers!
came from Ansible course to here. My question is doesn't Ansible can do all of this features? why we need another tool like Ansistrano?
Yo jian su!
Great question :). And yea... Ansible *can* do all of these things. But, it's not really another tool: Ansistrano is just an Ansible *role*. So, instead of you creating all the tasks necessary to clone your repository, clear the cache, change the symlinks, etc, those tasks already live inside the Ansistrano role. You can see the tasks here: https://github.com/ansistra.... It's actually pretty simple - you could even "steal" tasks from this and use Ansible directly :).
Cheers!
// composer.json
{
"require": {
"php": ">=5.5.9",
"doctrine/doctrine-bundle": "^1.6", // 1.6.8
"doctrine/orm": "^2.5", // v2.7.2
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"sensio/distribution-bundle": "^5.0.19", // v5.0.20
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.26
"symfony/monolog-bundle": "^3.1.0", // v3.1.0
"symfony/polyfill-apcu": "^1.0", // v1.4.0
"symfony/swiftmailer-bundle": "^2.3.10", // v2.6.3
"symfony/symfony": "3.3.*", // v3.3.5
"twig/twig": "^1.0||^2.0", // v1.34.4
"doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.1
"predis/predis": "^1.1", // v1.1.1
"composer/package-versions-deprecated": "^1.11" // 1.11.99
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.1.6
"symfony/phpunit-bridge": "^3.0", // v3.3.5
"doctrine/data-fixtures": "^1.1", // 1.3.3
"hautelook/alice-bundle": "^1.3" // v1.4.1
}
}
# ansible/requirements.yml
-
src: DavidWittman.redis
version: 1.2.4
-
src: ansistrano.deploy
version: 2.7.0
-
src: ansistrano.rollback
version: 2.0.1
To get the project running on my windows machine when it comes to running 'yarn' I first had to:
- install windows build tools globally in administrator mode
- install node-sass explicitly: yarn add node-sass