Buy
Buy

Installing Composer Deps

Ok, let's install our Composer dependencies already! Go back to the Ansible composer module for reference. Then, find your playbook and add a new task with a poetic and flowery name: "Install Composer's dependencies":

---
- hosts: vb
... lines 3 - 6
tasks:
... lines 8 - 109
- name: Install Composer's dependencies
... lines 111 - 113

Ok, boring name, but clear! Use the composer module, and set the one required option - working_dir - to {{ symfony_root_dir }}:

---
- hosts: vb
... lines 3 - 6
tasks:
... lines 8 - 109
- name: Install Composer's dependencies
composer:
working_dir: "{{ symfony_root_dir }}"

Hey, that variable is coming in handy!

Run that playbook!

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

It's running... running, installing Composer's dependencies and... explosion! Ah! So much red! Run!

Then... come back. Let's see what's going on. It looks like it was downloading stuff... if we move to /var/www/project on the VM and ls vendor/, yep, it was populated.

The problem was later - when one of Symfony's post-install tasks ran:

Fatal error: Uncaught exception, SensioGeneratorBundle does not exist.

Oh yea. By default, the composer module runs composer like this:

composer install --no-dev

This means that your require-dev dependencies from composer.json are not installed:

78 lines composer.json
{
... lines 2 - 35
"require-dev": {
"sensio/generator-bundle": "^3.0",
"symfony/phpunit-bridge": "^3.0",
"doctrine/data-fixtures": "^1.1",
"hautelook/alice-bundle": "^1.3"
},
... lines 43 - 76
}

If you're deploying to production, you may want that: it gives you a slight performance boost. But in a Symfony 3 application, it makes things blow up! You can fix this by setting an environment variable... and we will do that later.

But, since this is a development machine, we probably do want the dev dependencies. To fix that, in the playbook, set no_dev to no:

---
- hosts: vb
... lines 3 - 6
tasks:
... lines 8 - 109
- name: Install Composer's dependencies
composer:
working_dir: "{{ symfony_root_dir }}"
no_dev: no

Try the playbook now.

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

This time, I personally guarantee it'll work. In fact, I'm so confident, that if it doesn't work this time, I'll buy you a beer or your drink of choice if we meet in person. Yep, it's definitely going to work - I've never been so sure of anything in my entire life.

Ah! No! It blew up again! Find the culprit!

Attempted to load class "DOMDocument" from the global namespace.

Uh oh. I skipped past something I shouldn't have. When you download a new Symfony project, you can make sure your system is setup by running:

php bin/symfony_requirements

Your system is not ready to run Symfony projects.

Duh! The message - about the SimpleXML extension - means that we're missing an extension! In our playbook, find the task where we install PHP. Add another extension: php7.1-xml:

---
- hosts: vb
... lines 3 - 6
tasks:
... lines 8 - 55
- name: Install PHP packages
... lines 57 - 60
with_items:
... lines 62 - 66
- php7.1-xml
... lines 68 - 115

Run that playbook - hopefully - one last time:

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

Ya know, this is the great thing about Ansible. Sure, we might have forgotten to install an extension. But instead of installing it manually and forgetting all about it next time, it now lives permanently in our playbook. We'll never forget it again.

Phew! It worked! Go back to the VM and check out requirements again:

php bin/symfony_requirements

We're good! And most importantly, we can boot up our Symfony app via the console:

php bin/console

Our app is working! And there's just one last big step to get things running: configure NGINX with PHP-FPM and point it at our project. Let's go!

Leave a comment!

  • 2018-04-04 Victor Bocharsky

    Hey Nia,

    Thanks for sharing your temporary solution with others! Most of the times I just hardcode strings in "changed_when" statements, it makes sense to create a var only when you need to use that string in a few places. But yeah, good work!

    Cheers!

  • 2018-04-04 Nia Kathoni

    Went with the 3rd option and added
    register: composer_dependencies_installed
    changed_when: "composer_no_update not in composer_dependencies_installed.stdout_lines"
    with
    vars:
    composer_no_update: "Nothing to install or update"
    Thanks again, I will try to make the composer module work in the future.

  • 2018-04-03 Victor Bocharsky

    Hey Nia,

    > The latest version on the guest or host OS?
    I meant that OS on which you run that composer install task and see that error.

    So if you run "composer install" manually and it works fine without any errors but failed with Ansible - most probably related to the Composer module. If you have a detailed steps to reproduce, I think you can report an issue in Ansible's repository if nobody did it already.

    So there're a few possible solutions:
    1. Try to downgrade your composer.phar file to a lower version with which this task worked fine. But for this one your need to know what version worked fine for you before.
    2. Wait for the fix, but you need to be sure that this bug is reported and confirmed, so someone will fix it.
    3. Or temporarily write a custom composer task using "command" module to install composer dependencies. You can even play with "changed_when" based on the output to make this task green if nothing was done by Composer.

    If first 2 cases are not an option for you - I think the 3rd should be good and easy to implement.

    Cheers!

  • 2018-04-02 Nia Kathoni

    Hi Victor,

    Running "composer install --no-ansi --no-interaction --no-progress" manually didn't yield any errors and by googling the error it looks like it something related to the composer module.
    > Btw, do you have the latest Composer version?
    The latest version on the guest or host OS? If guest I using the script at https://getcomposer.org/doc... to download it and install it as suggested in the screencast.

    > Do you have any other extra Composer parameters in your task?
    No extras parameters in the task.
    - name: Install Composer's dependencies
    composer:
    working_dir: "/var/www/project"
    no_dev: no
    Also using "ubuntu/xenial64" for vagrant box.

    Thanks for the quick reply and feedback.

  • 2018-04-02 Victor Bocharsky

    Hey Nia,

    Hm, you can try to run "composer install --no-ansi --no-interaction --no-progress" manually, do you see any errors in the output? If not, then there's some bug in Ansible's Composer module. Btw, do you have the latest Composer version? Do you have any other extra Composer parameters in your task?

    Cheers!

  • 2018-04-01 Nia Kathoni

    The Install Composer's dependencies is failing for me with
    TASK [Install Composer's dependencies] *****************************************
    fatal: [192.168.33.10]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Shared connection to 192.168.33.10 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File \"/tmp/ansible_c3hnjciv/ansible_module_composer.py\", line 233, in <module>\r\n main()\r\n File \"/tmp/ansible_c3hnjciv/ansible_module_composer.py\", line 212, in main\r\n for param, option in option_params.iteritems():\r\nAttributeError: 'dict' object has no attribute 'iteritems'\r\n", "msg": "MODULE FAILURE"}
    as output. The error seems to be related to the version of python but I am not sure if it's the local version or the guest os one.

  • 2018-03-21 Victor Bocharsky

    Glad it was helpful for you!

    Cheers!

  • 2018-03-20 gstanto

    Thanks Victor. I did as you said, no errors in console when I was direct on Vagrant. Ran a second time was still fine. Deleted everything, ran and still fine. Changed everything to work for Symfony4, still fine! Must have been me.
    sorry for the hassle and thanks for the help. This tutorial was extremely helpful, btw.

  • 2018-03-20 Victor Bocharsky

    Hm, I just double checked the downloaded course code from both start/ and finish/ directories and it works for me well when I run both "composer install" and "composer install --optimize-autoloader" commands several times locally, i.e. I don't see the error you mentioned. Btw, could you try to install dependencies by yourself, i.e. not via Ansible but directly in your console as I did. Do you also see this error?

    Cheers!

  • 2018-03-19 gstanto

    I can't get it to run. I deleted composer.lock, vendor dir, and deleted all cache files, and everything resolved. But only the first run. Same thing happened with previous version install. If I find a solution, I'll post it here. Thank you very much for the timely response btw.

  • 2018-03-19 Victor Bocharsky

    Hey gstanto ,

    Hm, difficult to say why without debugging, probably it's a bug in Composer, I'd recommend to you to upgrade your composer to the latest available version and try again.

    Btw, sometimes problems could be due to the PHP version difference, e.g. when you use different PHP versions locally (where you lock dependencies in composer.lock) and on the server where you're trying to run this script.

    UPD: Actually, I found a similar issue in Composer repo: https://github.com/composer... try to follow some instructions from there. Probably the easy fix is to upgrade/downgrade Composer, maybe you just have a bad version.

    Let us know if a solution from the issue works for you.

    Cheers!

  • 2018-03-17 gstanto

    Not sure why but I get an error running the composer install the second time.
    Uncaught TypeError: Argument 1 passed to Composer\\Autoload\\ClassLoader::addClassMap() must be of the type array, integer given

    Error goes away only when 'optimize_autoloader' is disabled

    - name: Install Composer Dependencies
    composer:
    working_dir: "{{ symfony_root_dir }}"
    no_dev: no
    optimize_autoloader: false

  • 2017-05-18 Diego Aguiar

    Yeah, give it a try and let us know if you encounter to any problem :)

  • 2017-05-18 jian su

    Ah I see. So I just need download previous version then I should be fine

  • 2017-05-18 jian su

    Awesome. Thank you!

  • 2017-05-17 weaverryan

    Hey jian su!

    Ah, ha! This is related to Symfony! Are you trying to use the new Symfony 3.3 dependency injection features? The exclude key is pretty new (only a few days old), so you likely need to update to the absolute latest commit of Symfony on the master branch. I hope you enjoy those features - I've been personally working very hard on them (along with other people).

    Cheers!

  • 2017-05-17 weaverryan

    Yo jian su!

    Yes and no :). This depends on your task, and it's something we talk about later, in fact in the *next* chapter to be released: https://knpuniversity.com/s...

    When you use the apt module, it's basically running apt-get install php7.1. And apt is smart enough to not re-download and re-install something if it's already there (however, if you use the "latest" state, then it *will* upgrade the package if there is a new version). So for apt the answer is mostly no: the packages are not redownloaded and reinstalled.

    But for Composer, the answer (until the later chapter), is YES! This is because we're simply telling Ansible to run some commands (which download Composer), so it simply runs those commands *every* time. That's not a big deal, but it is wasteful. So, we fix it later.

    Cheers!

  • 2017-05-17 jian su

    Hi Guys:

    After running this task and have problem

    - name: Install Composer's dependencies
    composer:
    working_dir: "{{ symfony_root_dir }}"
    no_dev: no

    Need help, I have the following error

    [Symfony\Component\Config\Exception\FileLoaderLoadException]
    The configuration key "exclude" is unsupported for definition "AppBundle\" in "/var/www/project/app/config/services.yml". Allowed configuration key
    s are "resource", "parent", "shared", "lazy", "public", "abstract", "deprecated", "factory", "arguments", "properties", "configurator", "calls", "t
    ags", "autowire", "autoconfigure" in /var/www/project/app/config/services.yml (which is being imported from "/var/www/project/app/config/config.yml
    ").

  • 2017-05-17 jian su

    If I made mistakes like you, and I rerun the playbook again. Does that mean I re-download php7.1 mysql and composer......over again??