- Create an SSH Key
- Create a Digital Ocean account and droplet
- Connect to your server with SSH
- Create a new user and disable root access
- Give your new user sudo privileges and add SSH keys to his/her account
- Disable remote access to root account
- Test your SSH connection
- Set up your custom domain
- Add some swap space
- Set up SSL
- Ports and Redirects with nginx
- Install Meteor Up
- Visit your domain
If you don't already have one, create an RSA key pair. In Terminal enter:
ssh-keygen -t rsa
It will then ask you to name the file. Leave it empty and hit enter to accept the defualt name, id_rsa
.
Enter file in which to save the key (/demo/.ssh/id_rsa):
You'll then be asked to enter a passphrase. Again, leave it empty and hit enter.
Enter passphrase (empty for no passphrase):
Select Ubuntu for your operating system. For production apps, it's recommended that you spring for the $10/month set up. For a full walkthrough, read How To Create Your First DigitalOcean Droplet Virtual Server.
When you get to step to add your SSH key, go back to your terminal, copy the contents of your new key with:
cat ~/.ssh/id_rsa.pub | pbcopy
Then, back on Digital Ocean, give the key a name and paste it into the space as shown below:
Copy your IP address from your newly created droplet. In Terminal, enter the following with your IP:
ssh [email protected]
You'll likely be prompted with the following question. Answer yes
.
The authenticity of host 'XXX.XXX.XX.XXX (XXX.XXX.XX.XXX)' can't be established.
RSA key fingerprint is Xx:xX:Xx:XX:XX:Xx:XX:XX:XX:xX:XX:XX:Xx:Xx:xx:Xx.
Are you sure you want to continue connecting (yes/no)?
The following repsonse should be:
Warning: Permanently added 'XXX.XXX.XX.XXX' (RSA) to the list of known hosts.
If your connection is closed after this step, just repeat the ssh [email protected]
step. You are now logged into your server as the root user using an SSH key.
At the prompt on your server (should look something like this root@dropletname:~#
, enter adduser
followed by the username you want the new user to have.
adduser username
You'll be asked to create a password. What you type will not show up on screen, but type your password and hit enter. Then retype and hit enter again:
Enter new UNIX password:
Retype new UNIX password:
SAVE YOUR PASSWORD somewhere safe!
Once you've created and confirmed your new password, you'll be asked a few questions:
Changing the user information for username
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
You can leave these blank if you don't need this info for your new user.
Give your new user sudo privileges and add SSH keys to his/her account
gpasswd -a username sudo
And you also need to add NOPASSWD to your sudoers file. Open it with:
sudo visudo
Then, replace the line that says %sudo ALL=(ALL) ALL
with
%sudo ALL=(ALL) NOPASSWD:ALL
To save these edits, type Ctrl + X
, then confirm by typing Y
and hitting enter:
Now, switch to your new user with: The dash before the username makes sure that you actually log in as the new user.
su - username
Next, create a new folder called .ssh
and then restrict its permissions with the following commands:
mkdir .ssh
chmod 700 .ssh
Using the nano editor, we can create and edit a new file called authorized_keys
using the following command:
nano .ssh/authorized_keys
In another Terminal window or tab, copy your SSH key again with:
cat ~/.ssh/id_rsa.pub | pbcopy
Back in the nano editor window on the server, paste in your key. You should see your key displayed, without wrapping like so:
ssh-rsa MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQXGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63ilAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlFL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5kX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2eplU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
To save these edits, type Ctrl + X
, then confirm by typing Y
and hitting enter:
Save modified buffer (ANSWERING "No" WILL DESTROY CHANGES) ? Y
Now restrict the permissions of the authorized_keys file with this command:
chmod 600 .ssh/authorized_keys
Return to the root
user with:
exit
Which should give you a prompt like the following to let you know that you are back on the root user:
logout
root@dropletName:~#
Open the config file with:
nano /etc/ssh/sshd_config
Around 28 lines down this file, change PermitRootLogin
value to:
PermitRootLogin no
Save the file as before with Ctrl + X
, y
and enter
.
Exit and logout of your server session with:
exit
To test your connection with your new username and SSH key, simply execute:
ssh [email protected]
This should automatically log you on to your server as username
.
Go to your domain registrar and update your nameservers to point to
ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
This is what the iwantmyname settings look like:
Back on Digital Ocean add your domain name to your DNS records:
Now, create a new A record with the name of @
and your IP address like so:
(Optional) Follow the instructions here: How to Add Swap
From the prompt on you server, enter the following where yourserver
is the name of your server:
openssl req -new -newkey rsa:2048 -nodes -keyout yourserver.key -out yourserver.csr
This will generate a series of questions. When asked for Common Name, make sure you enter a wildcar subdomain for your address *.yourdomain.com
:
Common Name (e.g. server FQDN or YOUR name) []: *.yourdomain.com
Now, print the contents of the new yourserver.csr
file using:
cat ~/yourserver.csr
Copy the output with both the -----BEGIN CERTIFICATE REQUEST-----
and -----END CERTIFICATE REQUEST-----
tags. Create new file and save it as yourdomain.key
.
Go purchase your wildcard SSL certificate. After purchasing, follow instructions to activate your cert with your yourserver.csr
key. Be sure to select nginx as your web server. Wait for the emails and follow instructions.
Once you get the zipped file of certs, unzip them and at your yourdomain.key
file to the folder.
First, run this command to remove the password you set on you key:
openssl rsa -in yourdomain.key -out yourdomain.nopass.key
This will generate a new file for you with a key with no password. Now, you'll need to combine them into one file using a the following command with your file names:
cat yourdomain.crt DomainValidationSecureServerCA.crt AddTrustCA.crt.crt AddTrustExternalCARoot.crt yourdomain.nopass.key > ssl.pem
Save the ssl.pem
file for later (or move it to a directory called mup-your-project-name
somewhere outside your app repo).
Ports and Redirects with nginx
Back on your server, run the following commands update your packages and install nginx:
sudo apt-get update
sudo apt-get install nginx
Answer yes, when asked if you want to continue. Now open the server block default config file with:
sudo nano /etc/nginx/sites-enabled/default
Next, paste the following block into the file and edit to match your domain name. You can redirect just the www
subdomain to you non-www domain with, or use a wildcard:
# redirect www to non-www
server {
listen 80;
# to redirect all subdomains use *.yourdomain.com instead of www.yourdomain.com
server_name www.yourdomain.com;
return 301 $scheme://yourdomain.com$request_uri;
}
Save the file as before with Ctrl + X
, y
and enter
.
Now, let's forward our domain to a different port number since nginx is listening on port 80. We'll use port 3000. Create and edit a new file with:
sudo nano /etc/nginx/sites-enabled/yourappname.com.conf
Then past this block into that file:
server {
listen 80;
server_name YOURDOMAIN.com;
access_log /var/log/nginx/app.dev.access.log;
error_log /var/log/nginx/app.dev.error.log;
location / {
proxy_pass http://XXX.XXX.XX.XXX:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Save and exit this file. Next, we'll add a small security measure by hiding our nginx version number. Run,
sudo nano /etc/nginx/nginx.conf
Find and uncomment the line with
server_tokens off;
Save and exit this file. Then run:
sudo service nginx restart
To test the change, open a new terminal window and run:
curl -I http://www.yourdomain.com
The top line should read HTTP/1.1 301 Moved Permanently
.
Install Meteor Up
npm install -g mup
Now, create a directory called mup-your-project-name
somewhere outside your app's repo, switch to it, and initialize mup.
mkdir ~/mup-your-project-name
cd ~/mup-your-project-name
mup init
This should create two files: mup.json
and settings.json
. Open mup.json
and under the servers block, put in your details:
// Server authentication info
"servers": [
{
// the domain linked to Digital Ocean
"host": "yourdomain.com",
// the new user you created on the server
"username": "username",
// the SSH key you generated earlier
"pem": "~/.ssh/id_rsa"
}
],
"ssl": {
"pem": "./ssl.pem"
},
Then, a bit further down in the same file:
// Application name (No spaces)
"appName": "your-project-name",
// Location of app (local directory)
"app": "/path/to/the/app",
// Configure environment
"env": {
"ROOT_URL": "http://yourdomain.com",
// any port other than 80 (the default)
// because nginx is running on port 80
"PORT": 3000
},
Now, within your ~/mup-your-project-name
directory, setup your server by running
mup setup
After that's done, it should look something like this (make your command line look awesome):
Then deploy your app with:
mup deploy
If successful, your output should look like:
That should do it. Your site should be live.
This guide assumes that the user has at least meteor and nodejs installed, and the project downloaded somewhere. It wasn't my case and now this isn't working, but because you never described all the prerequisites I have no idea if this caused something that's missing. Does someone know the prerequisites?