-
Notifications
You must be signed in to change notification settings - Fork 3
Deployment
There's multiple ways to deploy your apps depending on your current application setup worry not for we will cover a couple here in hopes you find any of these convenient for you.
This is important since we're running an express app you'll need a reverse proxy to send request from port 80 to your node app(s).
We're going to assume you've already installed nginx and you're just missing the configuration for this app.
server {
listen 80;
listen [::]:80;
server_name webapp.com www.webapp.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}You can install PM2 to manage your app, it's got a simple configuration and you can use it to power multiple apps at the same time and use nginx to proxy said apps.
First make sure you got enough rights to install pm2 globally in the server, then:
npm install pm2 -gYou can create config file for all your apps in your home directory:
// $HOME/ecosystem.config.js
module.exports = {
apps: [
{
name: 'webapp',
script: 'build/bundle.js', // this is the server bundle
cwd: 'webapp',
instances: 1,
autorestart: true,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production',
PORT: 8080,
}
}
]
};We're going to assume that your web app will live in $HOME/webapp so once
you've clone and built or clone and upload into $HOME/webapp run:
pm2 startSet up the nginx config posted above in your server's available sites directory and restart nginx, and that's it you should now be able to browse your app through port 80.
This boilerplate comes with a Dockerfile for running the app in production, so to run this app in Docker containers you
only need to do the following:
Make sure you save the nginx config posted above into config/nginx.conf then you'll need
to create a docker-compose.yml file in your projects root directory with the following content:
version: "3"
services:
proxy:
image: "nginx:alpine"
command: ["nginx-debug", "-g", "daemon off;"]
ports:
- 80:80
environment:
- NGINX_HOST=webapp.dev
- NGINX_PORT=80
volumes:
- ./config/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- webapp
webapp:
build:
context: .
dockerfile: Dockerfile
image: "webapp:boiler"
env_file: .envAfterwards simply run:
docker-compose build # this builds your app into a docker container
docker-compose up # spins up your app and the proxy serverYou should now be able to visit your web app via port 80.
Github pages don't have support for a backend server, for such instances, only the client code is needed. In order to do so, we need to install a webpack plugin that uses an html template.
Keep in mind that for routing to work with multiple pages you'll need to use <HashRouter />. You can obtain more information here (HashRouter API Docs @ reacttraining.com).
First let's start by installing one dependency:
npm install -D html-webpack-plugin@latestThen we'll need to create an html template for our github page so under src/gh-pages.html save:
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="vendors.css">
<link rel="stylesheet" href="styles.css">
<script src="vendors.js"></script>
</head>
<body>
<div id="app">
</div>
<script src="bundle.js"></script>
</body>
</html>Now to get to the meat of this we'll need github pages webpack recipe, this will be basically identical to the client's production
recipe and given that the webpack recipes are nothing more than objects we can import we can make use of node modules to extend the
production config, save the following to config/webpack/gh-pages.js:
const path = require('path');
const production = require('./production');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const bundlePath = path.join(__dirname, '../../gh-pages');
const plugins = production.plugins.concat([
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../../src/gh-pages.html'),
}),
]);
const output = Object.assign(production.output, { path: bundlePath });
module.exports = Object.assign(production, { output, plugins });You can see that we've only injected html-webpack-plugin and changed the output dir, everything else intact.
Lastly we'll add a new environment to our webpack.client.js, adding environments is actually really simple here's how:
const prodConfig = require('./config/webpack/production');
const devConfig = require('./config/webpack/development');
const ghPages = require('./config/webpack/gh-pages');
const PRODUCTION = 'production';
const GH_PAGES = 'gh-pages';
const reduceEnv = function(environment) {
switch(environment) {
case PRODUCTION:
return prodConfig;
case GH_PAGES:
return ghPages;
default:
return devConfig;
}
};
module.exports = reduceEnv(process.env.NODE_ENV);The moment of truth, we compile our gh-pages bundle like this:
NODE_ENV=gh-pages npx webpack --config webpack.client.jsYou can put this in the scripts section of package.json for faster access if you like.
Now it's just a matter of using git subtree to push your bundled code to gh-pages:
git add gh-pages && git commit -m "My gh-pages commit"
git subtree push --prefix gh-pages origin gh-pagesThis Wiki is under MIT licence, you can find the complete License here: LICENSE