Documentation: full deployment example in AWS with Ubuntu 20.04
This commit is contained in:
parent
72377d3438
commit
dc816d0e59
|
@ -1,6 +1,7 @@
|
||||||
node_modules
|
node_modules
|
||||||
coverage
|
coverage
|
||||||
dist
|
dist
|
||||||
|
.env
|
||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.nyc_output
|
.nyc_output
|
||||||
|
|
|
@ -49,6 +49,7 @@ Cynthia Pereira
|
||||||
Daniel Thorn
|
Daniel Thorn
|
||||||
Daniela Arcese
|
Daniela Arcese
|
||||||
Danny Coates
|
Danny Coates
|
||||||
|
David Dumas
|
||||||
Davide
|
Davide
|
||||||
Derek Tamsen
|
Derek Tamsen
|
||||||
Dhyey Thakore
|
Dhyey Thakore
|
||||||
|
|
|
@ -81,7 +81,7 @@ A file sharing experiment which allows you to send encrypted files to other user
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- [Node.js 12.x](https://nodejs.org/)
|
- [Node.js 15.x](https://nodejs.org/)
|
||||||
- [Redis server](https://redis.io/) (optional for development)
|
- [Redis server](https://redis.io/) (optional for development)
|
||||||
- [AWS S3](https://aws.amazon.com/s3/) or compatible service (optional)
|
- [AWS S3](https://aws.amazon.com/s3/) or compatible service (optional)
|
||||||
|
|
||||||
|
@ -141,6 +141,8 @@ Find a list of public instances here: https://github.com/timvisee/send-instances
|
||||||
|
|
||||||
See also [docs/deployment.md](docs/deployment.md)
|
See also [docs/deployment.md](docs/deployment.md)
|
||||||
|
|
||||||
|
AWS example using Ubuntu Server `20.04` [docs/AWS.md](docs/AWS.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Clients
|
## Clients
|
||||||
|
|
|
@ -0,0 +1,236 @@
|
||||||
|
# Deployment to AWS
|
||||||
|
|
||||||
|
This document describes how to do a deployment of Send in AWS
|
||||||
|
|
||||||
|
## AWS requirements
|
||||||
|
|
||||||
|
### Security groups (2)
|
||||||
|
|
||||||
|
* ALB:
|
||||||
|
- inbound: allow traffic from anywhere on port 80 and 443
|
||||||
|
- ountbound: allow traffic to the instance security group on port `8080`
|
||||||
|
|
||||||
|
* Instance:
|
||||||
|
- inbound: allow SSH from your public IP or a bastion (changing the default SSH port is a good idea)
|
||||||
|
- inbound: allow traffic from the ALB security group on port `8080`
|
||||||
|
- ountbound: allow all traffic to anywhere
|
||||||
|
|
||||||
|
### Resources
|
||||||
|
|
||||||
|
* An S3 bucket (block all public access)
|
||||||
|
|
||||||
|
* A private EC2 instance running Ubuntu `20.04` (you can use the [Amazon EC2 AMI Locator](https://cloud-images.ubuntu.com/locator/ec2/) to find the latest)
|
||||||
|
|
||||||
|
Attach an IAM role to the instance with the following inline policy:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Action": [
|
||||||
|
"s3:ListAllMyBuckets"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"Effect": "Allow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Action": [
|
||||||
|
"s3:ListBucket",
|
||||||
|
"s3:GetBucketLocation",
|
||||||
|
"s3:ListBucketMultipartUploads"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::<s3_bucket_name>"
|
||||||
|
],
|
||||||
|
"Effect": "Allow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Action": [
|
||||||
|
"s3:GetObject",
|
||||||
|
"s3:GetObjectVersion",
|
||||||
|
"s3:ListMultipartUploadParts",
|
||||||
|
"s3:PutObject",
|
||||||
|
"s3:AbortMultipartUpload",
|
||||||
|
"s3:DeleteObject",
|
||||||
|
"s3:DeleteObjectVersion"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::<s3_bucket_name>/*"
|
||||||
|
],
|
||||||
|
"Effect": "Allow"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* A public ALB:
|
||||||
|
|
||||||
|
- Create a target group with the instance registered (HTTP on port `8080` and path `/`)
|
||||||
|
- Configure HTTP (port 80) to redirect to HTTPS (port 443)
|
||||||
|
- HTTPS (port 443) using the latest security policy and an ACM certificate like `send.mydomain.com`
|
||||||
|
|
||||||
|
* A Route53 public record, alias from `send.mydomain.com` to the ALB
|
||||||
|
|
||||||
|
## Software requirements
|
||||||
|
|
||||||
|
* Git
|
||||||
|
* NodeJS `15.x` LTS
|
||||||
|
* Local Redis server
|
||||||
|
|
||||||
|
### Prerequisite packages
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add repositories
|
||||||
|
|
||||||
|
* NodeJS `15.x` LTS (checkout [package.json](../package.json)):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
|
||||||
|
echo 'deb [arch=amd64] https://deb.nodesource.com/node_15.x focal main' | sudo tee /etc/apt/sources.list.d/nodejs.list
|
||||||
|
```
|
||||||
|
|
||||||
|
* Git (latest)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo add-apt-repository ppa:git-core/ppa
|
||||||
|
```
|
||||||
|
|
||||||
|
* Redis (latest)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo add-apt-repository ppa:redislabs/redis
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install required packages
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install git nodejs redis-server telnet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Redis server
|
||||||
|
|
||||||
|
#### Password (optional)
|
||||||
|
|
||||||
|
Generate a strong password:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
makepasswd --chars=100
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit Redis configuration file `/etc/redis/redis.conf`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
requirepass <redis_password>
|
||||||
|
```
|
||||||
|
|
||||||
|
_Note: documentation on securing Redis https://redis.io/topics/security_
|
||||||
|
|
||||||
|
#### Systemd
|
||||||
|
|
||||||
|
Enable and (re)start the Redis server service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable redis-server
|
||||||
|
sudo systemctl restart redis-server
|
||||||
|
sudo systemctl status redis-server
|
||||||
|
```
|
||||||
|
|
||||||
|
## Website directory
|
||||||
|
|
||||||
|
Setup a directory for the data
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo mkdir -pv /var/www/send
|
||||||
|
sudo chown www-data:www-data /var/www/send
|
||||||
|
sudo 750 /var/www/send
|
||||||
|
```
|
||||||
|
|
||||||
|
### NodeJS
|
||||||
|
|
||||||
|
Update npm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo npm install -g npm
|
||||||
|
```
|
||||||
|
|
||||||
|
Checkout current NodeJS and npm versions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Clone repository, install JavaScript packages and compiles the assets:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo su -l www-data -s /bin/bash
|
||||||
|
cd /var/www/send
|
||||||
|
git clone https://gitlab.com/timvisee/send.git .
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the file `/var/www/send/.env` used by Systemd with your environment variables
|
||||||
|
(checkout [config.js](../server/config.js) for more configuration environment variables):
|
||||||
|
|
||||||
|
```
|
||||||
|
BASE_URL='https://send.mydomain.com'
|
||||||
|
NODE_ENV='production'
|
||||||
|
PORT='8080'
|
||||||
|
REDIS_PASSWORD='<redis_password>'
|
||||||
|
S3_BUCKET='<s3_bucket_name>'
|
||||||
|
```
|
||||||
|
|
||||||
|
Lower files and folders permissions to user and group `www-data`:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo find /var/www/send -type d -exec chmod 750 {} \;
|
||||||
|
sudo find /var/www/send -type f -exec chmod 640 {} \;
|
||||||
|
sudo chmod 750 /var/www/send/node_modules/.bin/*
|
||||||
|
```
|
||||||
|
|
||||||
|
### Systemd
|
||||||
|
|
||||||
|
Create the file `/etc/systemd/system/send.service` with `root` user and `644` mode:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Send
|
||||||
|
After=network.target
|
||||||
|
Requires=redis-server.service
|
||||||
|
Documentation=https://gitlab.com/timvisee/send
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/bin/npm run prod
|
||||||
|
EnvironmentFile=/var/www/send/.env
|
||||||
|
WorkingDirectory=/var/www/send
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
_Note: could be better tuner to secure the service by restricting system permissions,
|
||||||
|
check with `systemd-analyze security send`_
|
||||||
|
|
||||||
|
Enable and start the Send service, check logs:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable send
|
||||||
|
sudo systemctl start send
|
||||||
|
sudo systemctl status send
|
||||||
|
journalctl -fu send
|
||||||
|
```
|
|
@ -1,16 +1,20 @@
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
This document describes how to do a full deployment of Send on your own Linux server. You will need:
|
This document describes how to do a full deployment of Send on your own Linux server. You will need:
|
||||||
|
|
||||||
* A working (and ideally somewhat recent) installation of NodeJS and NPM
|
* A working (and ideally somewhat recent) installation of NodeJS and npm
|
||||||
* GIT
|
* Git
|
||||||
* An Apache webserver
|
* Apache webserver
|
||||||
* Optionally telnet, to be able to quickly check your installation
|
* Optionally telnet, to be able to quickly check your installation
|
||||||
|
|
||||||
For Debian/Ubuntu systems this probably just means something like this:
|
For example in Debian/Ubuntu systems:
|
||||||
|
|
||||||
* apt install git apache2 nodejs npm telnet
|
```bash
|
||||||
|
sudo apt install git apache2 nodejs npm telnet
|
||||||
|
```
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
* We assume an already configured virtual-host on your webserver with an existing empty htdocs folder
|
* We assume an already configured virtual-host on your webserver with an existing empty htdocs folder
|
||||||
* First, remove that htdocs folder - we will replace it with Send's version now
|
* First, remove that htdocs folder - we will replace it with Send's version now
|
||||||
* git clone https://github.com/timvisee/send.git htdocs
|
* git clone https://github.com/timvisee/send.git htdocs
|
||||||
|
@ -19,51 +23,74 @@ For Debian/Ubuntu systems this probably just means something like this:
|
||||||
* npm run build
|
* npm run build
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
To have a permanently running version of Send as a background process:
|
To have a permanently running version of Send as a background process:
|
||||||
|
|
||||||
* Create a file "run.sh" with:
|
* Create a file `run.sh` with:
|
||||||
```
|
|
||||||
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
nohup su www-data -c "npm run prod" 2>/dev/null &
|
nohup su www-data -c "npm run prod" 2>/dev/null &
|
||||||
```
|
```
|
||||||
* chmod +x run.sh
|
|
||||||
* ./run.sh
|
* Execute the script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x run.sh
|
||||||
|
./run.sh
|
||||||
|
```
|
||||||
|
|
||||||
Now the Send backend should be running on port 1443. You can check with:
|
Now the Send backend should be running on port 1443. You can check with:
|
||||||
* telnet localhost 1443
|
|
||||||
|
```bash
|
||||||
|
telnet localhost 1443
|
||||||
|
```
|
||||||
|
|
||||||
## Reverse Proxy
|
## Reverse Proxy
|
||||||
|
|
||||||
Of course, we don't want to expose the service on port 1443. Instead we want our normal webserver to forward all requests to Send ("Reverse proxy").
|
Of course, we don't want to expose the service on port 1443. Instead we want our normal webserver to forward all requests to Send ("Reverse proxy").
|
||||||
|
|
||||||
# Apache webserver
|
# Apache webserver
|
||||||
|
|
||||||
* a2enmod proxy
|
* Enable Apache required modules:
|
||||||
* a2enmod proxy_http
|
|
||||||
* a2enmod proxy_wstunnel
|
|
||||||
* a2enmod rewrite
|
|
||||||
|
|
||||||
In your Apache virtual host configuration file, insert this:
|
```bash
|
||||||
|
sudo a2enmod headers
|
||||||
|
sudo a2enmod proxy
|
||||||
|
sudo a2enmod proxy_http
|
||||||
|
sudo a2enmod proxy_wstunnel
|
||||||
|
sudo a2enmod rewrite
|
||||||
|
```
|
||||||
|
|
||||||
|
* Edit your Apache virtual host configuration file, insert this:
|
||||||
|
|
||||||
```
|
```
|
||||||
# Enable rewrite engine
|
# Enable rewrite engine
|
||||||
RewriteEngine on
|
RewriteEngine on
|
||||||
|
|
||||||
# Make sure the original domain name is forwarded to Send
|
# Make sure the original domain name is forwarded to Send
|
||||||
# Otherwise the generated URLs will be wrong
|
# Otherwise the generated URLs will be wrong
|
||||||
ProxyPreserveHost on
|
ProxyPreserveHost on
|
||||||
|
|
||||||
# Make sure the generated URL is https://
|
# Make sure the generated URL is https://
|
||||||
RequestHeader set X-Forwarded-Proto https
|
RequestHeader set X-Forwarded-Proto https
|
||||||
|
|
||||||
# If it's a normal file (e.g. PNG, CSS) just return it
|
# If it's a normal file (e.g. PNG, CSS) just return it
|
||||||
RewriteCond %{REQUEST_FILENAME} -f
|
RewriteCond %{REQUEST_FILENAME} -f
|
||||||
RewriteRule .* - [L]
|
RewriteRule .* - [L]
|
||||||
|
|
||||||
# If it's a websocket connection, redirect it to a Send WS connection
|
# If it's a websocket connection, redirect it to a Send WS connection
|
||||||
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
||||||
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
|
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
|
||||||
|
|
||||||
# Otherwise redirect it to a normal HTTP connection
|
# Otherwise redirect it to a normal HTTP connection
|
||||||
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
|
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
|
||||||
ProxyPassReverse "/" "http://127.0.0.1:1443"
|
ProxyPassReverse "/" "http://127.0.0.1:1443"
|
||||||
|
```
|
||||||
|
|
||||||
|
* Test configuration and restart Apache:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apache2ctl configtest
|
||||||
|
sudo systemctl restart apache2
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue