Deploying Next.js to Apache server - node.js

I've been developing a Next.js website locally and now want to set it up on my Apache server (with cPanel). However, I'm very new to Next.js and Node apps and not too sure how to go about it.
Has anyone done this successfully? Can you list the required steps and what files should be on the server?
Also, can this be done on a subdomain?
Thank you!

To start with some clear terms just so we're on the same page, there are two or three very different things people mean when they say "server":
A Server Machine is a computer that is connected to the internet that you intend to use to serve something to people on the internet.
A Server Program is some software you run on your Server Machine. The job of the Server Program is to actually calculate the responses to various requests.
A Server as a Service is a webapp provided by a company that stores your code and then puts it onto Server Machines with the right Server Program as needed.
While we're here, let's also define:
A Programming Language is the language your website is written in. Some sites have no language (and are just raw HTML/CSS files that are meant to be returned directly to the user). Many sites, though, have some code that should be run on the server and then the result of that code should be returned to the user.
In your case, you have a Machine whose condition we don't know other than that it is running the Program Apache (or probably "Apache HTTP Server"). Apache HTTP server is very old and proven and pretty good at serving raw files back to users. It can also run some Programming Languages like PHP and return the result.
However, Next.JS is built on top of the Programming Language Javascript, which Apache does not have the ability to run. Next.JS instead wants its Server Program to be Node.
So the problem here is basically that you have a hammer, but only screws. You can't use the tool you have, Apache, to solve the problem you need solved, running Node code and returning the result. To get around this you have two options:
First, you can find a way to access the Server Machine that is currently running Apache and tell it, instead, to run Node pointed at your Next.JS code whenever it starts up. This might not be possible, depending on who owns this machine and how they've set it up.
Second, and probably easier, is to abandon this Machine and instead use a Server as a Service. Heroku, AWS, and Netlify all support Next.JS and have a free tier. The easiest solution, though, is probably to just deploy it on Vercel, which is a Server as a Service run by the same team that makes Next.JS and which has a very generous free tier for you to get started with.
The good news, though, is that yes next.js does totally support being hosted from a subdomain.

Next.JS allows you to build fully functional Node Applications, as well as simple statically-generated sites like Jeckyl or Docpad. If your use case is a simple statically generated site look here: https://nextjs.org/docs/advanced-features/static-html-export
In particular the next build && next export command will create all the HTML and assets necessary to host a site directly via an HTTP server like Apache or Ngnix. Contents will be outputed to an out directory that could serve as the server root.
Pay very close attention to what features are not supported via this approach.

Related

What's the difference between a web server and a development server?

So a bit of context - I'm trying to give my create-react-app project a backend using express.
I'm following a tutorial that talks about having two servers working concurrently. This leaves me a bit confused - what's the difference between a web and a dev server, and how you can have two servers working simultaneously?
I think the underlying issue here is that I only have a shallow understanding of what a server actually is: I only understand it as being a process that listens to requests and sends responses.
Cheers
The tutorial most likely refers to the following definitions:
development server
available at localhost
runs on your local machine, i.e. your PC
intended for local development and testing
web server
available at an IP adress or domain
runs on a remote server like a cloud server such as Google Cloud / Heroku / Digital Ocean
intended for production for your real users
From what I understand of your question, this tutorial seems to be talking about 2 separate environments, a production environment (i.e. where the 'real' code that clients/users will use runs), and a development environment (i.e. where code that is currently under testing and not ready for the 'real world' runs).
The reason you want (at least) 2 of them is so you can deploy your code to the dev environment and then test it out, see if it works, how it works, and if it breaks anything, without risking the real server going out, or maybe accidentally wiping your real customer database or something like that. When you deploy to your dev environment and see that everything work as it should and nothing is broken, then you can put that version of the code to run in your real, production environment, and be pretty sure your backend is not gonna go out while you are developing
I may be misunderstanding what the article is saying, but from your description I think that is it
Hope that helps you!

Use Google App Engine or Google Cloud Compute VM to Test Run My App?

I'm moving my Three.js app and its customized node.js environment, which I've been running on my local machine to Google Cloud. I want to test things out there, and hopefully soon get some early alpha testing going with other people.
I'm not sure which is the wiser way to go... to upload the repo I've been running locally as-is onto a VM which users would then access via the VM's external IP until I get a good name to call this app... or merge my local node.js environment with what's available via the Google App Engine and run it on GAE.
Issues I'm running into with the linux VM approach... I'm not sure how to do the equivalent on the VM of what I've been doing locally. In Windows Powershell I cd into the app directory and then enter node index.js. I'm assuming by this method of deployment that I can get the app running as soon as the browser hits the external IP. I should mention too that the app will allow users to save content as well as upload images, and eventually, 3D models as well as json datasets.
Issues I'm running into with the App Engine approach: it looks like I only have access to a linux-based command line, and have to install all the node.js modules manually. Meanwhile I have a bunch of files to upload, both the server-side node files and all the frontend stuff. I don't see where to upload those files, and ultimately what I'd like to do is have access to a visual, editable file-tree interface, as I have in Windows and FileZilla, so I can swap files in and out, etc. Alternatively I suppose I could import a repo from Github? Github would be fine as long as I can visually see what's happening. Is there a visual interface for file structure available in GAE somewhere? Am I missing something?
I went through the GAE "Hello World" tutorial and that worked fine, but was left scratching my head afterward regarding how to actually see and edit the guts of the tutorial app, or even where to look for the files.
So first off, I want to determine what's the better approach, and then if possible, determine how to make the experience of getting my app up there and running a more visual, user-friendly experience.
Thanks.
There are many things to consider when choosing how to run an app, but my instinct for your use case is to simply use a VM on GCE. The most compelling reason for this is that it's the most similar thing to what you have now. You can SSH into the machine and run nohup node index.js & (or node index.js inside tmux/screen if you prefer) and it will start the app and not stop it when you log out of SSH. You can use SCP / SFTP with whatever GUI client you want to upload files. You don't have to learn anything new! If you wanted to, you could even use a Windows VM (although I think you have to pay a little more than for a comparable Linux VM due to the licensing fees).
That said, the other way is arguably more "correct" by modern development standards, but it will involve a lot more learning that will prevent you from getting your app running somewhere other than your laptop in the short term:
First, you'll need to learn about Docker and stateless containers, which is basically what your app runs inside of on AppEngine.
Next, you'll need to learn how to hook up a separate stateful service (database, file server, ...) to your app's container so you can store your files, etc. in it, and then probably rewrite your app somewhat to use it to store stuff.
Next, you'll probably want some way to automatically deploy this from code instead of manually doing it, which gets you into build systems, package managers, artifact storage, continuous integration systems, and on and on and on.
This latter path is certainly what you should choose for a long-running production service if you work with a big team of developers -- but that doesn't mean that it's necessarily the right path for your project today. If you don't care about scaling up automatically, load balancing between nodes, redundant copies of your app running in different regions in case there's a natural disaster, etc., then go with the easy way for now, and you can learn new ways to improve the service when they're actually needed.

Install a server for a node.js web service application

I've built an application that run with node.js, which permit to retrieve some data through a REST API.
I want to put it online on a personal computer (Windows), but I have no idea how to install a server and what I need to make my application available online.
Can someone explain me the steps to do it ? I know that some online services exists like Heroku but I want to do it by myself.
Thank you
This question looks small, but it's actually huge. I started writing this as a basic guide, and it ended up really being quite a lengthy answer, so I split it into pieces. Overall hope this helps!
Using a VPS
You don't want to serve a website from your personal computer, because any time your computer is off, the website will be down. You don't want that kind of responsibility with your computer, so much of the time people choose to essentially rent server space from companies that's sole purpose is to get you space/bandwidth on a simple computer that is always on. These are often called VPS's (virtual private servers).
So the first step I'd recommend is to grab a VPS for yourself. Digital Ocean is a great service that you can get a solid server from for $5/month, I would recommend starting there. There are bunches of other companies you can get VPS's from though if you prefer, probably the most popular alterntive being linode.
Once you've got yourself a VPS, log in to it using ssh. Usually it will look something like this:
ssh root#000.000.0000
...with the number at the end being the IP address of your server. Most VPS's are some flavor of linux, so being familiar with the linux command line interface is important. Once you're all set in your server, you'll want to do a few things. This is what I usually do, in order:
Install vim
For me, vim is the easiest way to edit files through the command line. This certainly might not be the case for everyone - some people prefer emacs, and some nano, which is a lot simpler. If you are interested in learning about vim, there are loads of tutorials around the 'net. If getting into vim isn't your thing, I'd recommend using nano instead wherever I mention it from here on.
To get it installed, we can use apt, which is aptitude, the package manager on ubuntu, the flavor of linux I'll use in this answer since it's a popular one for servers, and is the default for digital ocean. Just run apt-get update to make sure packages are up to date, then apt-get install vim to put in vim.
Add your ssh key
Add your ssh key to ~/.ssh/authorized_keys so that you don't need a password to log in. If you are unfamiliar with ssh keys, they are basically a pair of cryptographic keys that you can use to avoid needing to authorize with a password every time. By adding your public key to the ~/.ssh/authorized_keys file, you are essentially telling the server "this is my computer, so you don't need to ask me for a password to log in". Github has a great guide on how to generate keys. Once this is done, you can open the file with vim, get into insert mode, and paste the public key in from your local machine. Save and quit and you're set.
Install node.js
If you are trying to run a node app, you will of course need to have node! Installing node on linux is a bit different because the node installer I'm sure you used locally is graphical, where here you only have the command line. Luckily, it's not much more difficult with this set of instructions, which you can follow exactly. Make sure you do not just do the default apt-get install nodejs, as this will install an old version. Take the couple steps after the second paragraph to add ppa and get a newer version.
Deploy your app
Ok, so you have a machine that has node and theoretically could run your app. This is good news. Now we need to actually get the app onto the machine. There are a few ways you can do this. If you have ruby installed locally, you can use capistrano, a popular deployment solution. A lighter weight approach that I often prefer is deploy, although I don't think that will work on windows. You can also just use github or bitbucket - push your app to a remote repo then clone it down from your VPS (make sure to apt-get install git and set up your username first - if it's a private repo you'll probably have generate and add a key to get access to pull it down). However you manage to do it, get the files transferred.
Test your app
On your VPS, cd into wherever your app was put and run it. Make sure everything is working ok, and hit http://YOUR_IP:PORT, just your ip address followed by a port number that your app is running on after the colon. You should be able to see your app. If not check back to the terminal, it may have crashed. Sometimes you can find flukes when you are setting it up on a different system. If your app uses a database, you might need to get this configured too. You can google "ubuntu setup database name" and find some tutorials -- digital ocean has a pretty solid library of these types of tutorials themselves.
Install nginx
Nginx is a great way to serve multiple apps on one machine, and to handle domain names and such. I wrote an article on how to set up nginx that you can check out to learn the basics and get it installed. Once this is done, you can link up your app with a proxy_pass. Rather than try_files, which is what the article does to server static files, just drop in a proxy_pass statement to the port your app is running on instead, and nginx will direct traffic right through to your app. Here's an example, if you had your app running on port 1234 and your domain name was example.com
server {
server_name example.com;
location / {
proxy_pass http://localhost:1234;
}
}
This will just take traffic coming into the box from example.com and pass it to your app, which is awesome.
Get your domain in order
I have to assume you don't want to require people to use an IP address to access your app, and you want a domain name. Go grab one from wherever, and once you have this you need to edit the DNS records. I've found that it's easiest to use dnsimple for this, as not every domain registrar has solid dns record handling, and you can keep all your dns management in one place. Now, just put an A record on the root of your domain, pointing it to your VPS's IP address. After giving it a couple minutes for the records to propigate, a hit to that domain should go directly to your server - fantastic.
Now is the time to check through and make sure that your app is running properly and that your nginx configuration is correct (and that you have reloaded nginx). Make sure that in your configuration, the server_name mirrors the domain you set to point at your VPS. Make sure the port in the proxy_pass is the same as your app is running on. Once this has been confirmed, go to the domain, and if you did it right, your app will come up. Whoo!
Run it on a production server
Great, so we got our app running and it's online on the internet for the public to enjoy. Just about time to sit back and let everyone throw money at you, a common occurance whenever you get a site shipped. But don't recline too quickly, because the last thing we need is to make sure this app stays up and continues running even if something goes wrong, or you log out of your VPS, so you don't always have to keep a terminal window open running the app. For this, we can use what some call production servers -- servers made specifically to ensure that your app runs in the background and stays running all the time. Luckily, node has a few of these open source, my favorite being pm2. Check out this page, read the getting started instructions, install pm2 on your machine, and run your app. The process might look something like this:
npm install pm2 -g
cd path_to_my_app
pm2 start app.js
Since you ran it on the same port, your nginx configuration should remain the same, and your app should still be up if you visit the domain.
Phew, that was a lengthy process. Probably more than you expected - makes sense why something like heroku exists. So is this really worth it, running and maintaining the site yourself? I'd argue yes, and I host every one of the sites and apps I run like this. Here's why:
learning: I learn tons about how things work this way, and get much better at sysops.
cost: You can host like 20 sites on a single $5 digital ocean box. hosting is pennies.
control: Heroku sometimes goes down and it sucks because all you can do is wait for them to get it back up. If my site goes down, it's my fault and I can find out why and fix it.
I'm sure this answer was more than you ever expected to get here, but hope this helps! Getting from dev to sysops is a journey and sometimes can get really frustrating, but I promise once you have a good handle on things, it feel great and really helps your skills a lot.
Finally, I want to note that this is without a doubt an opinionated guide. There are tons of other tools and other ways to do these things -- the workflow I have here is just the way I prefer to do things. By all means feel free to tinker and suit the workflow to your needs once you have it under your belt! There are also lots of other details that could be added in here about setting up different databases, improving your deploy/restart flow, and securing your box a little more throughly. Would love to hear any feedback and add any of these pieces in if you or others are interested.
Google Platform has resources for Node developers. There is a tutorial shows you how to deploy a simple Node.js application to Google App Engine Managed VMs. Detail of the pricing is here.
Amazon Web Service (AWS) also has the similar service. Here is the tutorial. The AWS Free Tier is designed to enable you to get hands-on experience with AWS at no charge for 12 months after you sign up. You can investigate AWS as a platform for your Node.js application. Check it here.

Node equivalent to index.html

I'm coming from a LAMP background and want to test out node for production.
What seems a little confusing to me is that in Apache url's map to folders, and the server will automatically look for an index.html or index.php if you aren't re-writing urls.
What would the equivalent be in node?
I'm thinking it'd be something like checking the request url and matching it, then loading a specific node module which runs the app.
This might seems simple for a single app, but we run tons of client apps on our server so i'm used to having different frameworks in different folders and index.php just runs it.
to be more specific. i'm currently running a few codeigniter and wordpress installations on our server. so i'd want to run a few node apps/frameworkds in different 'subfolders'
With Node you don't really use Apache. It's similar to Ruby in that is runs its own web server.
However, you can probably get Apache to run Node files using mod_node. As far as I know this is non-standard though and you definitely lose the "non-blocking" advantages of Node. But for experimenting (and not load testing) it's fine.
Check out Express if you're looking for an MVC architecture written in Node.
If you're just looking to run the most basic sample web server, just run the example hosted on the main page: http://nodejs.org/
Lastly, I had that same issue you are experiencing where I have one box hosting a lost of stuff and Apache taking up port 80. The answer here is to use a reverse proxy like Nginx to run on port 80 and redirect traffic to Apache / Node / Ruby / etc. Best of both worlds and since Nginx is written non-blocking you still gain the benefits of node.
I actually wrote an in-depth blog article about this a few months ago:
http://readystate4.com/2011/07/15/nginx-apache-and-node-all-living-harmony/

Nodejs on Nearlyfreespeech?

I'm looking at an existing website, deployed on an NFS server. I'd like to rewrite some portions of it to run on nodejs. As far as I can tell, nodejs isn't supported by the NFS folk, but I am constrained to using their servers.
So, is there a way to shoe-horn nodejs onto a nearlyfreespeech server? Has anyone tried this successfully?
As of 24/September/2014 NFS now support persistent processes:
Intro and overview - More power, more control, more insight, less cost
Official example - How-To: Django on NearlyFreeSpeech.NET
3rd party example - Run node.js on NearlyFreeSpeech.Net
To summarise the process described in mopsled.com's third-party example:
1) In NFS.N's admin UI, select your site's domain shortname under Sites, then change that site's "Server Type" to "Custom" instead of PHP / Apache.
2) Put your Node server code somewhere in /home/protected/
3) Create a shell script (eg run.sh) file somewhere in /home/protected/ that contains the command(s) to start your server (eg npm run start or node server.js). NFS.N will automatically run this script as a continuous process using a "Daemon", which we'll configure in the next step.
4) Select "Daemons" in your site's NFS.N admin UI, and enter your server's startup shell script path in the "command line" field. Complete the other fields as you see fit.
5) NFS.N will now ensure that your custom server process will run indefinitely. Your web server will now be available at the port your server listens at. However, NFS.N doesn't give root access for your server to communicate through the normal "low-level" internet ports (eg :80 and :443), so if you want to serve those, you must use NFS.N's "Proxy" feature described in the next step.
6) If you need to listen on low-level ports: select "Add a Proxy" in your site's NFS.N admin UI and enter the relevant settings, checking the "Bypass Apache entirely" option and giving the port your server is listening on for the "Target Port" option.
That's it! You can now stop/restart the server's continuous process (the shell script that the Daemon is maintaining) in the Daemon's configuration page.
NFS.net have a new "NFGI" architecture that may open the possibility to this:
NFGI can be made to work with other languages as well, making them first-class citizens of our service, just as fast and integrated as PHP currently is. This paves the way for making all sorts of frameworks viable that have traditionally been too slow when run through CGI. Rails. Catalyst. Django. We also believe it can be leveraged to make node.js work on our service, but we’re not 100% sure about that.
(Source: http://blog.nearlyfreespeech.net/2013/09/21/cgissh-upgrades/)
If you want this feature you can vote for it in their feature request system at https://members.nearlyfreespeech.net/support/voting
Although to be honest, I concur with earlier answers, using Node via CGI would lose some of the benefit...but would not be without its charms. Something like http://larsjung.de/node-cgi/ for NFS.net would be an interesting JavaScript replacement for PHP.
The problem is not that NFS.net will not support NodeJS. The thing is that you can't have "long running processes", i.e. servers. Since you can't run servers, you can't run Node.
In fact, the only way you can have anything dynamic there is by using CGI. There's no reason why Javascript engine could not be used to generate pages in response to requests, but I am not sure that can be done with node.

Resources