Symfony Console Commands

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

The project is working! Except... that it's not actually our project: this is the Symfony Standard Edition. Our cow customers are waiting: let's install MooTube!

Head over to https://github.com/knpuniversity/ansible to find the code behind this project. Copy the clone URL and open your editor. Find the spot where we clone the repo and use our new URL:

---
- hosts: vb
... lines 3 - 9
tasks:
... lines 11 - 119
- name: Checkout Git repository
git:
repo: https://github.com/knpuniversity/ansible.git
... lines 123 - 163

You know the drill: run the playbook!

ansible-playbook ansible/playbook.yml -i ansible/hosts.ini

Our repository is public... which makes life easy. If you have a private repository, you'll need to make sure that your server has access to it. They talk about that a bit in the git module docs. You can also use a deploy key.

Using the Console

Once we have the code, we need to setup a few other things, like the database. The README.md file talks about these: after you download the composer dependencies, you can set up the database by running these three commands. Each runs through Symfony's console: an executable file in the bin/ directory.

This is a perfect situation for the command module... because... well, we literally just need to run 3 commands. Head to your playbook. Right above the handlers, add a comment: "Symfony Console Commands". We'll start with a task called "Create DB if not exists":

---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 151
# Symfony console commands
- name: Create DB if not exists
... lines 154 - 174

Use the command module. For the value... we need to know the path to that bin/console file.

This is another good spot for a variable! Create a new one called symfony_console_path set to {{ symfony_root_dir }}/bin/console:

---
- hosts: vb
vars:
... line 5
symfony_root_dir: /var/www/project
... lines 7 - 8
symfony_console_path: "{{ symfony_root_dir }}/bin/console"
... lines 10 - 174

Use that in the command: {{ symfony_console_path }} doctrine:database:create --if-not-exists:

---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 151
# Symfony console commands
- name: Create DB if not exists
command: '{{ symfony_console_path }} doctrine:database:create --if-not-exists'
... lines 155 - 174

That last flag prevents an error if the database is already there.

Awesome! Copy that task to create the second one: "Execute migrations". Use doctrine:migrations:migrate --no-interaction:

---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 151
# Symfony console commands
- name: Create DB if not exists
command: '{{ symfony_console_path }} doctrine:database:create --if-not-exists'
- name: Execute migrations
command: '{{ symfony_console_path }} doctrine:migrations:migrate --no-interaction'
... lines 158 - 174

And add one more: "Load data fixtures". This is something that we only want to run if this is a development machine, because it resets the database. We'll talk about controlling that later.

For this command, use hautelook_alice:doctrine:fixtures:load --no-interaction:

---
- hosts: vb
... lines 3 - 10
tasks:
... lines 12 - 151
# Symfony console commands
- name: Create DB if not exists
command: '{{ symfony_console_path }} doctrine:database:create --if-not-exists'
- name: Execute migrations
command: '{{ symfony_console_path }} doctrine:migrations:migrate --no-interaction'
- name: Load data fixtures
command: '{{ symfony_console_path }} hautelook_alice:doctrine:fixtures:load --no-interaction'
... lines 161 - 174

Ok! The 3 commands are ready! Head back to the terminal. Woh! It exploded!

And actually... the reason is not that important: it says an error occurred during the cache:clear --no-warmup command. After we run composer install, Symfony runs several post install commands. One clears the cache. Changing from one project to an entirely different project temporarily put things in a weird state. This one time, in the virtual machine, just remove the cache manually:

rm -rf var/cache/*

Try the playbook now:

ansible-playbook ansible/playbook.yml -i ansible/hosts.ini

This time composer install should work and hopefully our new commands will setup the database. By the way! A Symfony 3 app reads its configuration from a parameters.yml file... which is not committed to the repository. So... in theory, that file should not yet exist... and none of this should work. But that file does exist! Why? Thanks to a special line in composer.json, after composer install finishes, the parameters.yml.dist file is copied to parameters.yml. And thanks to that dist file, Symfony will try to connect to MySQL using the root user and no password. If that's not right, just modify the file on the VM directly for now. Later, we'll talk about how we could properly update this file.

Yes! It worked! Notice: the three new tasks all say changed. That's because the command module isn't smart enough to know whether or not these actually changed anything. But, more on that soon!

Find your browser and refresh! Welcome to MooTube! The fact that it's showing these videos means our database is working. Now, let's talk about tags: a cool way to help us run only part of our playbook.

Leave a comment!

This tutorial is built using an older version of Symfony, but the core concepts of Ansible are still valid. New versions of Ansible may contain some features that we don't use here.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*", // v3.1.4
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.4
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // 2.11.1
        "symfony/polyfill-apcu": "^1.0", // v1.2.0
        "sensio/distribution-bundle": "^5.0", // v5.0.12
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.0
        "snc/redis-bundle": "^2.0", // 2.0.0
        "predis/predis": "^1.1" // v1.1.1
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.8
        "symfony/phpunit-bridge": "^3.0", // v3.1.4
        "doctrine/data-fixtures": "^1.1", // 1.3.3
        "hautelook/alice-bundle": "^1.3" // v1.4.1
    }
}