2

I am looking for some way to have a maximally simple(no Jenkins or anything like that) automatic production deployment for a Node.js application on a RHEL 7 system. The caveat is:

At the organization where I work, we have a very restricted IT environment, that prohibits access to any ports other than 80 and 443 from anywhere, and only allows 22(ssh) from within some rooms in the office building. To upload files a tunnel is needed which is slow and is also not available in some places. And SSHing to the server to run commands is a huge pain for multiple reasons too. And no - I can't do anything about it.

In light of this the 'trigger' has to initiate from the server itself. The server should somehow decide to pull changes from a certain branch, ideally when a special commit message is seen, and then run some pre-configured scripts to deploy it. The tests at that point are already all done, the app has been at the staging and beta server and so the only things needed is to copy directory, update dependencies, compile frontend assets and restart the systemd service that runs the app (all that I already have in the script that Jenkins executes on staging server after running all the tests).

I would imagine the sever would need to poll, e.g. every minute for changes to the repo, and yes, that can be done with a cron job, but I am not sure how, and if there are some tools that make it easier, without creating a resource hog that Jenkins does (which is what we use on our staging and beta servers), then I would like to know about it (I wasn't able to find anything yet, maybe I am not using the right search terms).

Any advice?

Update-1: I am aware of Puppet and Chef, but if at all possible, would prefer avoiding proprietary solutions if possible for now because a - our project is not big enough yet for the decision makers to put real resources in it, and b - even if those have free versions available, they are most likely cumbersome and do a lot of things, whereas we want as simple a solution as possible, because that solution might be part of the package if we sell the project elsewhere (naturally we don't want to also "re-sell" Puppet or Chef). Some kind of Open Source solution, or simply a method of doing it using simple shell scripts would be best.

Update-2: As Tensibai mentioned - Chef is open source and fits our purposes, but it's a huge platform with a lot of features, which is precisely what we are trying not to use in production server (otherwise we'd just use Jenkins like we do in staging).

  • Well, you needs a pull model and to set it to run periodically. Any configuration management system working on a pull model would do, so this let mainly chef and puppet for the case, I do prefer chef for the flexibility personally, ansible and salt are push models and as such would suffer the problem of ssh access. – Tensibai Sep 11 '17 at 12:40
  • Yesh, I am aware of Puppet and Chef, but if at all possible, would prefer avoiding proprietary solutions because a - our project is not big enough yet for the decision makers to put real resources in it, and b - even if those have free versions available, they are most likely cumbersome and do a lot of things, whereas we want as simple a solution as possible, because that solution might be part of the package if we sell the project elsewhere(naturally we don't want to also "re-sell" Puppet or Chef). – Megakoresh Sep 11 '17 at 12:48
  • 1
    Ok so 1) chef is fully open-source (either client or server on all paltforms including windows) 2) reinventing the wheel is rarely the 'as simple solution as possible' and usually a footgun. – Tensibai Sep 11 '17 at 12:52
  • Regarding your second point by the way: I am not trying to integrate to AWS, Azure, Google Cloud, manage a cluster of VMs, Nginx, Apache servers, supporting authentication from multiple providers, automatically scale VM instances and 1000+ other things that Chef does. So calling me not wanting all those features bundled in the solution "Reinventing the wheel" is, let's say, mildly inappropriate. – Megakoresh Sep 11 '17 at 13:33
  • Provisioning is not the core of chef-client , All you said is done by tools around chef, but that's not core chef goal, if you want to say there's extraneous features, say it does service management (restart if stopped), templates rendering (for config files), directory sync from remote source, setup of cronjobs, a bunch of code for powershell you won't need on linux boxes, but talk about configuration management things inside an operating system. – Tensibai Sep 11 '17 at 13:45
1

Ok, let's assume you'll pull the latest version of branch prod from a git repo, here's what it would take with chef on a basic illustrative purpose:

git "/opt/my_application" do
  source "https://<git_host>/<you_repo_url>/<repo.git>"
  revision "production"
  action :sync
  notifies :run,"execute[app_config]"
end

execute "app_config" do
  command "npm install"
  cwd "/opt/my_application"
  action :nothing
end

For more advanced use cases you can have a look at the poise application cookbooks, it includes a javascript plugin for node.js application.

chef is fully open source, either client or server side (out of the fancy UI) and on all OSes including windows.

  • I wasn't aware that Chef was open sourced, they don't make it very clear on the homepage. It also looks like the license is totally fine for our purpose. My second point stands though - it's a huge platform that does a lot of things and I'd rather avoid that. All I want is to pull a branch from repo and if theres a certain commit message, run a shell script file. If nobody can provide a simpler solution than to install and use Chef, I will accept this answer. – Megakoresh Sep 11 '17 at 13:22
  • @Megakoresh Chef takes 207MB on my system, it has the advantage of being mainly independent of the OS (libs are internal in the omnibus package, but it requires a specific install path for this reason). It does what you ask it to do, and I highly doubt you won't do more than just pulling your app once you'll have started to use it, describing a whole system and moving to the phoenix server pattern is a huge gain on mid term. – Tensibai Sep 11 '17 at 13:30
  • I'll install it on a test VM and get back to you on how simple it is to install, configure and use. In my experience things like that require someone working full time on their maintenance alone, it took me a month to get Jenkins to work 100% reliably for the project. And Jenkins takes 300MB of ram when Idling. If Chef is somehow miraculously an exception to that rule, I'll use it, but I hope you understand my scepticism. BTW: I am packaging the project atm, however it will be managed later is not my concern, phoenix or not. – Megakoresh Sep 11 '17 at 13:38
  • @Megakoresh Chef takes ram only when it runs, it can set a cronjob for itself to run every X minutes if you ask it to do so. The install of chef itself is the matter of doing a curl command. Writing a first cookbook is not really hard, going further has a learning curve as everything, you should have a look at learn.chef.io – Tensibai Sep 11 '17 at 13:48
1

All this time after I think I am finally able to answer this question. The solution is Ansible - just like @James Shewey mentioned. It's agentless and quite light python framework, that can be made to work through jump hosts and perform automated tasks through SSH. This means it requires no server setup or manual operations of any kind from our customer to deploy the application.

Without anything else it's a one-command deployment solution, which is almost as good as a fully automated one and it has the benefit of being readable and usable by people not familiar with code.

Puppet offers similar functionality, but it has an agent which means if packaged with the application, it does require manual server setup from the customer. Also Puppet is ruby and I try to stay clear of that thing as much as possible. I've learned the hard way just how bad ruby is for anything other than prototyping.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.