Coder Social home page Coder Social logo

ansible-symfony2's Introduction

Symfony2

Build Status

If you use ansible <2.0, please do a ansible-galaxy install servergrove.symfony2,v1.9.0 to get the last backwards-compatible version. Otherwise you can stick with stable "master" :-)

Ansible role to easily deploy Symfony2 applications. It will clone a git repository, a specific branch or a tag, download and run composer install, and run assetic:dump when finished. The resulting directory structure is similar to what capifony/capistrano creates:

project
    composer.phar
    releases
        release
    shared
        web
            uploads
        app
            config
            logs
    current -> symlink to latest deployed release

It will also keep the releases directory clean and deletes all but your configured amount of releases. You're also able to switch on/off whether ansible should execute doctrine migrations, or mongodb schema update, etc.

Requirements

Installed version of Ansible.

Installation

Ansible galaxy

    $ ansible-galaxy install servergrove.symfony2

Usage

This playbook is taken from the travis testcase. You can always pass these values as commandline parameters.

---
- hosts: servers
  roles:
    - servergrove.symfony2

  vars:
    symfony_project_root: /tmp/test_app
    symfony_project_name: travis-test
    symfony_project_composer_path: /tmp/test_app/shared/composer.phar
    symfony_project_repo: https://github.com/symfony/symfony-standard.git
    symfony_project_env: prod

    symfony_project_console_opts: '--no-debug'
    symfony_project_keep_releases: 5

    symfony_project_branch: "2.6"
    symfony_project_php_path: php
    symfony_project_keep_releases: 5

    symfony_project_manage_composer: True
    symfony_project_composer_opts: '--no-dev --optimize-autoloader --no-interaction'

Commandline: ~$ ansible-playbook -i inventory --extra-vars "symfony_project_release=20150417142505,symfony_project_branch=master" test.yml

Role Variables

Possible variables

These are the possible role variables - you only need to have a small set defined, there are defaults.

---
- vars:
    # necessary project vars
    symfony_project_root: Path where application will be deployed on server.
    symfony_project_composer_path: path where composer.phar will be stored (e.g. project_root/shared)
    symfony_project_repo: URL of git repository.
    symfony_project_release: Release number, can be numeric, we recommend to set it to release date/time, 20140327100911
    symfony_project_env: prod

    # optional parameters, covered by defaults
    symfony_project_post_folder_creation_tasks: task hook after folder creation
    symfony_project_pre_cache_warmup_tasks: after cache warmup
    symfony_project_pre_live_switch_tasks: before live symlink is switched
    symfony_project_post_live_switch_tasks: after live symlink is switched

    symfony_project_branch: git branch, commit hash or version tag to deploy - defaults to master
    symfony_project_php_path: php
    symfony_project_php_options: ""
    symfony_project_keep_releases: 5
    symfony_project_git_clone_depth: 1 # uses git shallow copy
    symfony_project_github_token: Auth token for github rate limits
    symfony_project_console_opts: ''
    symfony_project_console_command: 'app/console' # sf >= 3.0 bin/console
    symfony_project_config_dir: 'app/config' # symfony configuration dir
    symfony_project_parameters_file: parameters.yml # optional fixed parameters file in shared
    symfony_project_cache_command: cache:warmup

    symfony_project_manage_composer: True
    symfony_project_composer_opts: '--no-dev --optimize-autoloader --no-interaction'
    symfony_project_composer_run_install: True

    symfony_project_enable_cache_warmup: True warmup symfony cache, check out cache command!
    symfony_project_fire_schema_update: False # rund mongodb schema update if installed
    symfony_project_fire_migrations: run doctrine migrations, if installed
    symfony_project_symlink_assets: run assets:create with symlink options

    symfony_project_shared_folders: # folders to be linked from shared directory to release dir
      - {name: logs, src: app/logs, path: app/logs}

    symfony_project_managed_folders: # folderst to be created/checked in release dir
      - {name: cache, path: app/cache}

Role variable defaults

As you can see, the release number default is the current date/time with seconds to allow for easy multiple releases per day. But you can always overwrite with --extra-vars="" option.

---
- vars
    symfony_project_release: <datetime> # internally replaced with YmdHis
    symfony_project_branch: master
    symfony_project_php_path: /usr/bin/php
    symfony_project_keep_releases: 5
    symfony_project_git_clone_depth: 1
    symfony_project_console_opts: ''
    symfony_project_composer_opts: '--no-dev --optimize-autoloader --no-interaction'
    symfony_project_fire_migrations: False
    symfony_project_symlink_assets: True

hooks

If you need any more tasks and stuff in your deployment, you now have the option to include hook scripts. In my projects there's often e.g. a gulp task that has to be started before finishing the release. You're also free to create more folders yourself or do whatever you need. As an additional goodie, you can use the internal dynamically created facts from main role:

---
  symfony_project_release # release timestamp
  symfony_current_release # release name
  symfony_current_release_dir # fully qualified path to release
  symfony_shared_dir # shared folder base path
  symfony_console # fully qualified console command path

possible hooks:

---
  symfony_project_post_folder_creation_tasks: task hook after folder creation
  symfony_project_pre_cache_warmup_tasks: after cache warmup
  symfony_project_pre_live_switch_tasks: before live symlink is switched
  symfony_project_post_live_switch_tasks: after live symlink is switched

These hooks trigger an include when defined. Define hooks:

  symfony_project_post_folder_creation_tasks: "{{playbook_dir}}/hooks/post_folder_creation.yml"

The "hooks" dir should be in your deployment project as a subfolder. I'd recommend to use this name as a convention. Also it's convinient to use the name of the hook task as a yml name.

hook examples

These examples can be found in the package's hooks dir.

php-fpm process restart

E.g. restart php-fpm after successfully finishing deployment. This is much easier to maintain for different environments.

Create <your deployment>/hooks/post_live_switch.yml:

---
- name: hook | Restart php-fpm
  service: name=php5-fpm state=restarted
  when: symfony_project_env == "prod"

create and maintain web/downloads folder

Example for managing additional directories

Create <your deployment>/hooks/post_folder_creation.yml:

---
- name: hook | Create web/uploads folder.
  file: state=directory path={{symfony_shared_dir}}/web/uploads

- name: hook | Symlink to release.
  file: state=link src="{{symfony_shared_dir}}/web/uploads" path="{{symfony_current_release_dir}}/web/uploads"

As an alternative to managing folders via hooks, you can also configure either the shared folders or the creation of folders in your release directory in your confguration:

---
symfony_project_shared_folders: # folders to be linked from shared directory to release dir
  - {name: logs, src: app/logs, path: app/logs}
  - {name: uploads, src: web/uploads, path: web/uploads}

Passing PHP options

Suppose you need to overide some of php's options on the command line. Simply set the symfony_project_php_options. For example

---
- hosts: servers
  roles:
    - servergrove.symfony2

  vars:
    symfony_project_root: /tmp/test_app
    symfony_project_name: travis-test
    symfony_project_composer_path: /tmp/test_app/shared/composer.phar
    symfony_project_repo: https://github.com/symfony/symfony-standard.git
    symfony_project_env: prod

    symfony_project_console_opts: '--no-debug'
    symfony_project_keep_releases: 5

    symfony_project_php_path: php
    symfony_project_php_options: -dmemory_limit=512M -dzend.enable_gc=0

This will set the php variables memory_limit to 512M and zend.enable_gc to 0 when any php command is run, such as composer install or cache:warmup.

Dependencies

None

Testing

The deployment contains a basic test, executed by travis. If you want to locally test the role, have a look into .travis.yml for the exceution statements. Make sure you have a local php executable (needed for composer install and symfony console scripts). Add a file ansible.cfgto your deployment project folder with contents:

[defaults]
roles_path = ../

The test setup looks like this:

servergrove.symfony2
    tests
        inventory # hosts information
        test.yml # playbook
    .travis.yml # travis config

License

MIT license

Author Information

Contributions are welcome: https://github.com/servergrove/ansible-symfony2

ansible-symfony2's People

Contributors

bonswouar avatar cordoval avatar gnat42 avatar maschmann avatar pgodel avatar servergrove avatar vviippola avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ansible-symfony2's Issues

Composer install won't finish

From the last master version.

When it runs ansible-symfony2 | Run composer install., it never ends.

I think (but I might be wrong?) it's because of the prompt asking for params (or use default ones).

Here is the -vvv debug :

REMOTE_MODULE command cd /home/www/git/proj/releases/20150610111810 && export SYMFONY_ENV=prod && php /home/www/git/proj/composer.phar install --no-dev --optimize-autoloader #USE_SHELL

And when I run it outside of Ansible I get the prompt asking for :

Some parameters are missing. Please provide them.
secret (ThisTokenIsNotSoSecretChangeIt): 

Running role for the first time generates an error.

When running the following command:
ansible-playbook -l test -i inventory.ini -e "symfony2_project_release=1" deploy.yml -vvv

I get this error:
msg: refusing to convert between directory and link for /var/www/vhosts/exampl/releases/1/app/logs

I have confirmed that the folder exists in the repo and the only file in the folder is a ".gitkeep" file.

Require parameters.yml link symlink prior to cache warmup

Hello,

We have a situation where a project has some deployed server/environment variables that are different than development or other deployments - for example its behind a reverse proxy and so we have to set some base_path/url overrides. We've done this by adding this to our config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: config_who.yml, ignore_errors: true }

Thus if the config_who.yml filed doesn't exist it continues on, but if it does it's included with its config overrides.

Now if we want to use this role, we'd like to put that file in the same shared/app/config directory and have it symlink to the releases/ReleaseVersion/app/config directory. Looking at the system there are no hooks that apply or configuration options for this.

I'm wondering how we should solve this. I don't mind creating a PR but it seems this could be solved two ways.

1 - Add something to the 10-config.yml file to do the same thing for parameters.yml for other files. Probably changing it so that it works on a loop of files to link with only parameters.yml as default
2 - pre-cache hook.

Which would you prefer?

Optional webserver/php process restart

For each symfony2 deployment you need to flush the opcode and userland caches. That's normally either done by script or via webserver/php-fpm restart.
I'd like to introduce an optional task (when: symfony2_project_restart_webserver) where you can add a configurable commandline-option (e.g. shell: sudo service nginx restart; sudo service php5-fpm restart) where you can configure the actual command through an additional variable.

How to execute post install composer scripts

Hi.

I need to execute Incenteev\\ParameterHandler\\ScriptHandler::buildParameters interactively. Is this possible?

My deploy config is:

---
- name: Deploy project to S6 production server
  hosts: s6
  roles:
    - { role: servergrove.symfony2 }
  vars:
    # custom config
    vhost_name: "<HIDDEN_SECRET>"
    vhost_path: "<HIDDEN_SECRET>"
    # mandatory role config
    symfony_project_root: "{{ vhost_path }}/{{ vhost_name }}"
    symfony_project_composer_path: "{{ vhost_path }}/{{ vhost_name }}/shared/composer.phar"
    symfony_project_repo: "<HIDDEN_SECRET>"
    symfony_project_env: "prod"
    # optional role config
    symfony_project_branch: "master"
    symfony_project_keep_releases: 3
    symfony_project_composer_opts: "--no-dev --optimize-autoloader"
    symfony_project_shared_folders:
      - { name: logs, src: app/logs, path: app/logs }

Error github.com has an unknown hostkey

I always have this error cloning from my git repo.
I do not have much experience with ansible, so it may be a stupid question. I didn't found any help.

msg: github.com has an unknown hostkey. Set accept_hostkey to True or manually add the hostkey prior to running the git module

FATAL: all hosts have already failed -- aborting

weird behaviour. it does not pull sources from repo.

don't understand whats happening. i think it is not related with ansible.symfony2 but please advise.....

i have left to test only this task:

- name: Pull sources from the repository.
  git: repo={{symfony2_project_repo}} dest={{symfony2_project_root}} version={{symfony2_project_branch}}

if i execute it i got correct result:

changed: [localhost] => {"after": "bda8a73a1d08494488c21ca8f3baa0e10ba69bc2", "before": null, "changed": true}

TASK: [shell echo 'Deployment complete.'] *************************************
skipping: [localhost]

PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0

but dest directory is always empty not having my sources!!!!!!!!! P.D: please note that "after": "bda8a73a1d08494488c21ca8f3baa0e10ba69bc2" is showing correct hash of repo commit!

thx

Create symlink for parameters file fails

Hi,

while migrating from 1.0 version to new version I've encountered the following issue:

TASK: [servergrove.symfony2 | Check if config dir exists.] ********************
ok: [xxx.xxx.xxx.xxx]

TASK: [servergrove.symfony2 | Link configs dir if not yet exists.] ************
skipping: [xxx.xxx.xxx.xxx]

TASK: [servergrove.symfony2 | Check if parameters file exists.] ***************
ok: [xxx.xxx.xxx.xxx]

TASK: [servergrove.symfony2 | Create symlink for parameters file from shared directory.] ***
failed: [xxx.xxx.xxx.xxx] => {"failed": true}
msg: unsupported parameter for module: creates

FATAL: all hosts have already failed -- aborting

Error on deploy: boostrap.php.cache missing

After updating to latest project version (v2.0.1-alpha) I get this error on the "Dump assetic assets":

require_once([...]/app/bootstrap.php.cache): failed to open stream: No such file or directory

AFAIK that file is automatically generated when building the cache, so is there a missing step?

Thank you!

Default value of "symfony2_project_composer_opts" is wrong for DEV environment

The default value for symfony2_project_composer_opts is

'--no-dev --optimize-autoloader --no-interaction'

but this value produces an error if symfony2_project_env is set to dev.

Of course I can force the value in my deploy.yml, but I was wondering if it's possible to programmatically change the default value for symfony2_project_composer_opts according to the set value of symfony2_project_env.

I am a beginner with Ansible so I can't suggest a solution.

First execution throws error for creating link to source file

following instruction here: http://blog.servergrove.com/2014/04/01/deployment-symfony2-applications-ansible/

i got this error:

failed: [localhost] => {"failed": true, "item": "", "path": "/home/myproject/master/releases/1/app/logs", "src": "/home/myproject/master/shared/app/logs", "state": "absent"}
msg: src file does not exist, use "force=yes" if you really want to create the link: /home/myproject/master/shared/app/logs

when executing: ansible-playbook -l prod -i app/config/hosts.ini -e "symfony2_project_release=1" app/config/deploy.yml -vvv --check

thx in advance

Local Cache Folder

How do you folks usually deal with permissions around the cache folder? I created my own "hook" file currently to do the chmod.

Milestones for a v1.0 release

Checklist of open points for a 1.0 release:

  • Make schema update configurable or exclude as separate module
  • Integrate MongoDB reindex PR
  • Add Travis CI testing env
  • Cleanup readme
  • Add changelog
  • Add datetime release-dirs as default

Is master branch usable to deploy sf3.3/3.4 in production ?

Is this project still maintained and suitable to deploy SF3.3/3.4 projects in production?
I tried ansistrano but I didn't managed to do it easily with the handling/hooks of symlinks of the shared folder on iSCSI shared disks..
Thanks in advance.

Refusing to convert between directory and link

Running the ansible-symfony2 playbook gives me an error while creating a symlink for release.

FAILED! => {"changed": false, "gid": 33, "group": "www-data", "mode": "0774", "msg": "refusing to convert between directory and link for /var/www/my.app.com/current", "owner": "www-data", "path": "/var/www/my.app.com/current", "size": 4096, "state": "directory", "uid": 33}

I have removed app/logs and app/cache from my repo but its still not working. I currently have no clue how to proceed.

Overwriteable subtasks?

I'm thinking about making some of the includes, e.g. the git checkout part as overwriteable include, to provide more freedom of customizing (nearly) every step in the deployment process.

example:

---
- include: "{{ symfony_project_my_custom_git_handling | default('11-git.yml') }}"

This solution uses the "hook" handling.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.