{"action":"created","issue":{"url":"https://api.github.com/repos/deployphp/deployer/issues/549","repository_url":"https://api.github.com/repos/deployphp/deployer","labels_url":"https://api.github.com/repos/deployphp/deployer/issues/549/labels{/name}","comments_url":"https://api.github.com/repos/deployphp/deployer/issues/549/comments","events_url":"https://api.github.com/repos/deployphp/deployer/issues/549/events","html_url":"https://github.com/deployphp/deployer/issues/549","id":130696907,"number":549,"title":"Is it possible to run a build task locally just once, and then deploy to many servers in the same deploy?","user":{"login":"philbates35","id":4882082,"avatar_url":"https://avatars.githubusercontent.com/u/4882082?v=3","gravatar_id":"","url":"https://api.github.com/users/philbates35","html_url":"https://github.com/philbates35","followers_url":"https://api.github.com/users/philbates35/followers","following_url":"https://api.github.com/users/philbates35/following{/other_user}","gists_url":"https://api.github.com/users/philbates35/gists{/gist_id}","starred_url":"https://api.github.com/users/philbates35/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/philbates35/subscriptions","organizations_url":"https://api.github.com/users/philbates35/orgs","repos_url":"https://api.github.com/users/philbates35/repos","events_url":"https://api.github.com/users/philbates35/events{/privacy}","received_events_url":"https://api.github.com/users/philbates35/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2016-02-02T14:23:29Z","updated_at":"2016-02-19T19:31:29Z","closed_at":null,"body":"I have a multi-tenant application, each tenant has their own instance of the application.\r\n\r\nCurrently we do a separate deployment for each application, but this results in a separate `composer install`, `npm install` etc for every tenant, and as the number of tenants grows this is taking too long.\r\n\r\nI would like Deployer to sit on a build server, and run `composer install`, `npm install`, `gulp` etc in the release directory locally. **This should only happen once on the build server.** Then when that is done, I want to upload the entire release directory (include Composer's `vendor` directory and all built assets`) from the build server to the release directory on each of the tenant application servers. This means the build process only happens once, and will drastically speed up deployment time.\r\n\r\nI've looked at the `local` recipe provided by the `deployphp/recipes` package, but from what I can see, all `runLocally` tasks run once for every server, which I don't want - I want the build process to happen only once.\r\n\r\nI've also seen that I can define a task to run locally only once using `task()->once()` - the problem with this is that because there is no environment available when I define a task as `once`, I get an error `Call to a member function parse() on a non-object in /home/www/deployer/vendor/deployer/deployer/src/functions.php on line 316` when I try and `runLocally()` in the task that should run only once.\r\n\r\nHere's some psudo-code for what I'd like to be able to do, but as far as I can see isn't possible.\r\n\r\n```\r\n// This task should only be run once locally, regardless of how many servers there are\r\ntask('local:build', function() {\r\n    runLocally('cd {{local_release_path}} && composer install --no-dev);\r\n    runLocally('cd {{local_release_path}} && npm install --production);\r\n    runLocally('cd {{local_release_path}} && gulp);\r\n})->once();\r\n```\r\nDoes this make sense? And if so, is there a way that I've missed to achieve what I want? Or is this currently not possible?\r\n\r\nGreat project btw :)"},"comment":{"url":"https://api.github.com/repos/deployphp/deployer/issues/comments/186369971","html_url":"https://github.com/deployphp/deployer/issues/549#issuecomment-186369971","issue_url":"https://api.github.com/repos/deployphp/deployer/issues/549","id":186369971,"user":{"login":"clphillips","id":682986,"avatar_url":"https://avatars.githubusercontent.com/u/682986?v=3","gravatar_id":"","url":"https://api.github.com/users/clphillips","html_url":"https://github.com/clphillips","followers_url":"https://api.github.com/users/clphillips/followers","following_url":"https://api.github.com/users/clphillips/following{/other_user}","gists_url":"https://api.github.com/users/clphillips/gists{/gist_id}","starred_url":"https://api.github.com/users/clphillips/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clphillips/subscriptions","organizations_url":"https://api.github.com/users/clphillips/orgs","repos_url":"https://api.github.com/users/clphillips/repos","events_url":"https://api.github.com/users/clphillips/events{/privacy}","received_events_url":"https://api.github.com/users/clphillips/received_events","type":"User","site_admin":false},"created_at":"2016-02-19T19:31:29Z","updated_at":"2016-02-19T19:31:29Z","body":"> Do you mean Jenkins and Deployer would be in the same server, and Jenkins as it's last build step would talk to Deployer, which would look in the Jenkins build directory and just copy (rsync etc) the archive to the servers?\r\n\r\nYes, precisely. I'd recommend using the deployer PHAR for this purpose. If you're using ANT, your target might look like:\r\n\r\n```xml\r\n    <target name=\"deploy\" description=\"Deploy using Deployer\">\r\n        <exec executable=\"dep\">\r\n            <arg value=\"deploy\" />\r\n            <arg value=\"-f deploy.php\" />\r\n        </exec>\r\n    </target>\r\n```\r\n\r\nIf you choose to use deployer to build your project as well (which I don't recommend because Jenkins does this so much easier), your *localbuild.php* might look something like:\r\n\r\n```php\r\n<?php\r\nrequire 'recipe/common.php';\r\n\r\nlocalServer('local')\r\n    ->env('deploy_path', './build/dist')\r\n    ->stage('local');\r\n\r\ntask('composer', function () {\r\n    run('composer install --prefer-dist --no-interaction');\r\n});\r\n\r\ntask('npm', function () {\r\n    run('npm install');\r\n});\r\n\r\ntask('gulp', function () {\r\n    run('gulp');\r\n});\r\n\r\ntask('archive', function () {\r\n   // do whatever you need to do archive files\r\n});\r\n\r\ntask('build', [\r\n    'composer',\r\n    'npm',\r\n    'gulp',\r\n    'archive'\r\n]);\r\n```"}}