How to deploy your node app on Linux, 2016 edition
certsimple.com
certsimple.com
* Install NPM in a way that you can upgrade easily. Your package manager was designed to do this, so use it. Never ever put untracked files in the system directories.
* Don't git clone into production. You need to know which version was deployed when and where. At the very least set a tag. Better yet, roll a package from that tag (see above) which you then can sign and store. It's very easy and there are tools to help.
* Schedule when and how you upgrade your operating system, NPM, and your application. To do this you need a way to take an application out of production, which brings us to...
* You generally want a load balancer or some sort of web server between the world and your application. This could be as simple as an Apache or nginx. Don't muck about with port forwards!
* And most importantly, document this down to every command in the internal wiki! Even better, write a Puppet/Salt/Ansible file and put it under version control.
In short: Tools exist for a reason. Use them. Don't hack files manually until you master the tools and know why they exist.
The articles uses the package manager - specifically, the article directs people to install node using nodesource's RPM and dpkg node packages (npm is included with node), and only mentions tarballs if these don't exist for your OS.
> * Schedule when and how you upgrade your operating system, NPM, and your application. To do this you need a way to take an application out of production, which brings us to... > You generally want a load balancer or some sort of web server between the world and your application.
Hence covering that and load balancing with HAProxy in the article. This is mentioned in the introduction.
> * And most importantly, document this down to every command in the internal wiki! Even better, write a Puppet/Salt/Ansible file and put it under version control.
Hence mentioning exactly that in the opening few paragraphs.
It's very clear you didn't read the article before commenting.
> The articles uses the package manager - specifically, the article directs people to install node using nodesource's RPM and dpkg node packages (npm is included with node), and only mentions tarballs if these don't exist for your OS.
Sure, but it also advises users that it's generally OK to extract tarballs into /usr/local. While this clearly is OK in some circumstances, the target audience for this article clearly aren't in a position to make that decision, or understand the consequences of doing this. The article could have suggested "/opt/node" for example and avoided the issue at the expense of explaining how PATH variables work.
The FHS forbids distros from installing software to either location.
See http://www.pathname.com/fhs/2.2/fhs-4.9.html:
> "The /usr/local hierarchy is for use by the system administrator when installing software locally. It needs to be safe from being overwritten when the system software is updated. It may be used for programs and data that are shareable amongst a group of hosts, but not found in /usr."
Ah, I did miss the subfolder. This is a very unusual convention for installation into /usr/local. Typically, this is what modern day usage of /opt looks like.
> The FHS forbids distros from installing software to either location.
> See http://www.pathname.com/fhs/2.2/fhs-4.9.html:
Correct, both options are valid per the FHS. Yet, the description for /opt describes the pattern used in your example.
See http://www.pathname.com/fhs/2.2/fhs-3.12.html:
"A package to be installed in /opt must locate its static files in a separate /opt/<package> directory tree, where <package> is a name that describes the software package."
I'm thinking about changing it to /opt instead (and will credit you if I do it), alas /opt/bin isn't in $PATH on most distros.
> Programs to be invoked by users must be located in the > directory /opt/<package>/bin. If the package includes UNIX > manual pages, they must be located in /opt/<package>/man > and the same substructure as /usr/share/man must be used.
Static packages should be kept together as /opt/myprogramm and mostly follow the same structure as /usr than so like: /opt/myprogramm/bin /opt/myprogramm/include /opt/myprogramm/lib ...
Mostly I put my programs there, too. /opt/app1 /opt/app2
Looks like /usr/local wins.
Also they don't screw the system as others do that won't get installed with the package manager.
Don't touch any directory without the package manager, if you still do use /opt.
If no repository is available you should not proceed with anything until you have a plan in place how to keep track of updates and security issues. How often do you update? Do you backport security issues or upgrade? There will be backwards incompatible changes upstream which fixes security problems, and you need to have a plan in advance when in panic mode.
And if no package is available you must first know why. Is it not supported? Is there a better way? What does that mean for your deployment? With this knowledge you create a package. Install it and keep a copy for future troubleshooting. Always use packages in Linux, unless you have a very good and specific reason not to.
Under no circumstances should you drop untracked files in your environment, unless it is a one man show.
I'm actually really surprised you showed up again. You made a post loudly proclaiming the lack of packaging, high availability, and Ansible in an article that had all those things, in the opening paragraphs.
I'm trying to think of a polite way to say this, but: putting down someone else's work based on it missing things it actually includes (since you haven't bothered to read the article) is incredibly rude. Perhaps you forgot something in your most recent reply?
I feel it's often the other way around: don't hack around with big powerful tools until you know what the underlying problem is and what steps are actually needed to solve it.
Exactly my thoughts... this is for toy projects.
It's 2016 and we have proper tools like PM2 [0], StrongPM [1], or even better, Serverless [2] (this is only for AWS but sooo cool) ...
- The article uses systemd for process monitoring rather than PM2 since it's built into the OS.
- The article uses HAProxy as a load balancer.
- Ansible playbooks, Dockerfiles, and the AWS API are all mentioned in the opening section of the article. Serverless sounds fine too. Personally I use http://mikemaccana.com/images/work/screenshots/firework-0.pn... which I made using the AWS API. Either way, you will need some logic to capture inside these tools. Rather than write an article on Dockerfiles, Ansible playbooks, or the AWS or DO APIs, the article covers the devops basics one needs to know before using these tools.
'Use ${TOOL}' doesn't help you create or understand the contents of ${TOOL}s Dockerfile.
Many tools are popular because they provide powerful and convenient abstractions. For many folks, it's all about saving time (and therefore money). There's value in leaving the underlying working internals to specialists (that's why we don't need to understand the linux In-kernel API when we use Ubuntu Server's networking)
However many developers wish to have more control over their environment than what a PaaS provides, and a lot of the tools they'd use for that - Ansible, Docker, etc - require basic DevOps skills.
[replying from old account due to rate limit]
As its doc states: PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.
It also provides a very nice integration with keymetrics.io, which is the paid service which finance PM2 development (they do provide a free tier).
PS: Apart from using it and loving it, I am not affiliated with this product's team.
[1] http://pm2.keymetrics.io/docs/usage/deployment/
[2] https://keymetrics.io/2014/06/25/ecosystem-json-deploy-and-i...
I'd also recommend including your dependencies in your deployment package anyway to avoid a deployment being held up by npmjs.org downtime.
PS. npm v3 still needs it, in fact it makes it better - `install --save` updates the shrinkwrap file.
Re: checking in modules, I used to do this during 2013 when npm was up and down every few days, but stopped a couple of years ago after npm Inc stabilised everything. It's been solid so far and the smaller repo sizes (and faster deploys) have been worth it.
I think I also read many other blogs suggesting serving static files with nginx in front of nodejs. Are you sure that this does not make sense?
As the article mentions, you'll probably want a load balancer for high availability. Whether you use haproxy or nginx for that is a whole different discussion.
You should aim to have the bulk of your payload be static, and all of the static payload be served by apache or nginx. It's the difference between getting good feedback from a Show HN post or completely missing out and looking like a fool.
Something's massively wrong with your node setup. node won't be as fast, but it should be on the same order of magnitude as nginx: https://github.com/observing/balancerbattle (or any other benchmark)
As far as I know, using nginx in front helps with serving static files, which is a moot point on a REST API.
Well, that depends on the API; for example, a product inventory API might need to serve many product images, a document management API might have to serve PDFs and such, etc.
I get `git push dokku master` deployment for free, for any application, I dont have to worry about conflicting node versions between applications and it took a lot less setup for all of my applications than this process describes for one.
From then on you can - and should - deploy everything with Ansible playbooks, AWS AMIs / Digital Ocean images, Dockerfiles, or whatever else. You've already been doing this for years and have the experience - this is written for developers who haven't done a lot of Linux before and want to take control of the process.
Switched to using github to push to, which fires off a build on a ci server, which fires off a push to docker registry and my server pulls that and rolls the versions.
This setup allows me to have everything on a single server until an app starts needing it's own, then I deploy a new CoreOS server and transfer the fire system to that one.