Merge pull request #76 from vapor/deploy

nginx deploy
This commit is contained in:
Tanner 2016-11-10 12:38:28 -05:00 committed by GitHub
commit 6c95959e65
5 changed files with 228 additions and 3 deletions

View File

@ -152,8 +152,19 @@ menu:
relativeUrl: websockets/custom.html
testing:
name: testing
name: Testing
items:
testing-basic:
text: Basic
relativeUrl: testing/basic.html
deploy:
name: Deploy
items:
deploy-nginx:
text: Nginx
relativeUrl: deploy/nginx.html
deploy-supervisor:
text: Supervisor
relativeUrl: deploy/supervisor.html

149
deploy/nginx.md Normal file
View File

@ -0,0 +1,149 @@
---
currentMenu: deploy-nginx
---
# Deploying with Nginx
Nginx is an extremely fast, battle tested, and easy-to-configure HTTP server and proxy. While Vapor supports directly serving HTTP requests with or without TLS, proxying behind Nginx can provide increased performance, security, and ease-of-use.
> Note: We recommend proxying Vapor HTTP servers behind Nginx.
## Overview
What does it mean to proxy an HTTP server? In short, a proxy acts as a middleman between the public internet and your HTTP server. Requests come to the proxy and then it sends them to Vapor.
An important feature of this middleman proxy is that it can alter or even redirect the requests. For instance, the proxy can require that the client use TLS (https), rate limit requests, or even serve public files without talking to your Vapor application.
![nginx-proxy](https://cloud.githubusercontent.com/assets/1342803/20184965/5d9d588a-a738-11e6-91fe-28c3a4f7e46b.png)
### More Detail
The default port for receiving HTTP requests is port `80` (and `443` for HTTPS). When you bind a Vapor server to port `80`, it will directly receive and respond to the HTTP requests that come to your server. When adding a proxy like Nginx, you bind Vapor to an internal port, like port `8080`.
> Note: Ports greater than 1024 do not require `sudo` to bind.
When Vapor is bound to a port besides `80` or `443`, it will not be accessible to the outside internet. You then bind Nginx to port `80` and configure it to route requests to your Vapor server bound at port `8080` (or whichever port you've chosen).
And that's it. If Nginx is properly configured, you will see your Vapor app responding to requests on port `80`. Nginx proxies the requests and responses invisibly.
## Install Nginx
The first step is installing Nginx. One of the great parts of Nginx is the tremendous amount of community resources and documentation surrounding it. Because of this, we will not go into great detail here about installing Nginx as there is almost definitely a tutorial for your specific platform, OS, and provider.
Tutorials:
- [How To Install Nginx on Ubuntu 14.04 LTS](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-14-04-lts)
- [How To Install Nginx on Ubuntu 16.04](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04)
- [How to Deploy Nginx on Heroku](https://blog.codeship.com/how-to-deploy-nginx-on-heroku/)
- [How To Run Nginx in a Docker Container on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-run-nginx-in-a-docker-container-on-ubuntu-14-04)
### APT
Nginx can be installed through APT.
```sh
sudo apt-get update
sudo apt-get install nginx
```
Check whether Nginx was installed correctly by visiting your server's IP address in a browser
```sh
http://server_domain_name_or_IP
```
### Service
Ther service an be started or stopped.
```sh
sudo service nginx stop
sudo service nginx start
sudo service nginx restart
```
## Booting Vapor
Nginx can be started an stopped with the `sudo service nginx ...` commands. You will need something similar to start and stop your Vapor server.
There are many ways to do this, and they depend on which platform you are deploying to. Check out the [Supervisor](supervisor.md) instructions to add commands for starting and stopping your Vapor app.
## Configure Proxy
The configuration files for enabled sites can be found in `/etc/nginx/sites-enabled/`.
Create a new file or copy the example template from `/etc/nginx/sites-available/` to get started.
Here is an example configuration file for a Vapor project called `Hello` in the home directory.
```sh
server {
server_name hello.com;
listen 80;
root /home/vapor/Hello/Public/;
location @proxy {
proxy_pass http://127.0.0.1:8080;
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Server;
proxy_connect_timeout 3s;
proxy_read_timeout 10s;
}
}
```
This configuration file assumes the `Hello` project binds to port `8080` when started in production mode.
### Serving Files
Nginx can also serve public files without asking your Vapor app. This can improve performance by freeing up the Vapor process for other tasks under heavy load.
```sh
server {
...
# Serve all public/static files via nginx and then fallback to Vapor for the rest
try_files $uri @proxy;
location @proxy {
...
}
}
```
### TLS
Adding TLS is relatively straightforward as long as the certificates have been properly generated. To generate TLS certificates for free, check out [Let's Encrypt](https://letsencrypt.org/getting-started/).
```sh
server {
...
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/hello.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hello.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
...
location @proxy {
...
}
}
```
The configuration above are the relatively strict settings for TLS with Nginx. Some of the settings here are not required, but enhance security.

65
deploy/supervisor.md Normal file
View File

@ -0,0 +1,65 @@
---
currentMenu: deploy-supervisor
---
# Supervisor
[Supervisor](http://supervisord.org) is a process control system that makes it easy to start, stop, and restart your Vapor app.
## Install
```sh
sudo apt-get update
sudo apt-get install supervisor
```
## Configure
Each Vapor app on your server should have its own configuration file. For an example `Hello` project, the configuration file would be located at `/etc/supervisor/conf.d/hello.conf`
```sh
[program:hello]
command=/home/vapor/hello/.build/release/App serve --env=production
directory=/home/vapor/hello/
user=www-data
stdout_logfile=/var/log/supervisor/%(program_name)-stdout.log
stderr_logfile=/var/log/supervisor/%(program_name)-stderr.log
```
As specified in our configuration file the `Hello` project is located in the home folder for the user `vapor`. Make sure `directory` points to the root directory of your project where the `Config/` folder is.
The `--env=production` flag will disable verbose logging and prioritize the `Config/production` sub folder of your configuration files.
### Environment
You can export variables to your Vapor app with sueprvisor.
```sh
environment=PORT=8123
```
Exported variables can be used in Vapor's configuration files with the `$` prefix.
`Config/production/servers.json `
```json
{
"my-server": {
"port": "$PORT"
}
}
```
The above config file will start a server named `my-server` on the port number exported by supervisor. This is a great way to control how Vapor starts from the supervisor config scripts. Feel free to name the server whatever you like.
## Start
You can now load and start your app.
```sh
supervisorctl reread
supervisorctl add hello
supervisorctl start hello
```
> Note: The `add` command may have already started your app.

View File

@ -25,7 +25,7 @@ h1, h2, h3, h4, h5, h6 {
h1 {
font-size: 38px;
font-weight: 200; }
font-weight: 300; }
@media screen and (min-width: 720px) {
h1 {
font-size: 42px; } }

View File

@ -31,7 +31,7 @@ h1
font-size: 38px
@media screen and (min-width: $tablet)
font-size: 42px
font-weight: 200
font-weight: 300
h2
font-size: 30px