Skip to content

Instantly share code, notes, and snippets.

@Maximization
Last active April 2, 2022 21:33
Show Gist options
  • Save Maximization/a545e568a7c1f760f830b4753b830661 to your computer and use it in GitHub Desktop.
Save Maximization/a545e568a7c1f760f830b4753b830661 to your computer and use it in GitHub Desktop.
Server Template Instructions

Server Template for Busy Hackers

These are the instructions for the Server Template for Busy Hackers.

Getting started

1. Sign up for a DigitalOcean account (if you don't have one)

We'll be using DigitalOcean to spin up a server (or droplets as they're called). DigitalOcean is a popular choice for developers because of its friendly user interface and good customer support. Their prices are competitive and they offer good value for what you pay.

You can use my referral link to get $100 in credit valid for 60 days.

2. Create a DigitalOcean API key

A DigitalOcean API key grants the script access to create a server in your behalf. To create a token, please follow these instructions: https://www.digitalocean.com/docs/apis-clis/api/create-personal-access-token/

Make sure the token has write permission. Add the token in vars/main.yml file:

do_api_token: "your_api_token"

3. Install Ansible

Ansible is an open-source software used to automate IT infrastructure. It's the underlying tool used by the script to provision & configure the server and deploy your applications.

macOS

The easiest way to install Ansible on macOS, is to use Homebrew:

brew install ansible

Linux

Linux users can install Ansible from apt.

Windows

If you're on Windows, you'll need the Windows Subsystem for Linux (WSL). The official installation instructions from Microsot explain how to install WSL on Windows 10. After having installed WSL, you can install Ansible through apt similar to Linux users.

In case you already have Ansible installed, make sure you're using version 2.9 or higher. Older versions haven't been tested and they might not work.

4. Create and configure a server

SSH key pair

The script assumes you have an SSH key pair on your machine stored at the default location. The public key will be added to your DigitalOcean account, which will then be used to authenticate with the newly created server.

If you don't have an SSH key pair, you can create one in just 4 steps.

If you wish to use a different key pair than the default one, change the do_sshkey_public and do_sshkey_private_path variables in vars/main.yml file.

Node.js version

Node.js 14.x will be installed on the server to run your applications. If your apps need to use a different Node.js version, you can change this with the nodejs_version variable.

All applications will use the same Node.js version, so make sure you choose a version that works with all of them. I might add support for app specific Node.js versions in the future if there's enough interest. Send me a quick email at [email protected] if you need this feature.

Droplet size and region

By default, the script will create a $5/month server in the Amsterdam region. You can change the size and location in vars/main.yml file with the droplet_size and droplet_region variables, respectively.

Other variables

Other variables in the same file that you might consider changing are:

  • droplet_name (default: "mydroplet") - Name of the droplet
  • server_user (default: "myuser") - User that will be created on the server

To create and configure a server, type in the following command:

ansible-playbook bootstrap-server.yml

It will take a few minutes to complete. Sit back and relax ☕.

After a while you should see a success message with the IP address of your new server together with the SSH command to log into the server if you ever need to.

5. Create a Github token

Before you can deploy your first app, you'll need to create a Github token. This token will grant the server access to your private repositories. It will also be used to create a repository webhook so your app is automatically deployed on every push.

To create a token, go to your Github access tokens and click on "Generate new token". Give the token a name (eg. "server template") and select the following scopes:

  • repo - Full control of private repositories
  • admin:repo_hook - Full control of repository hooks

Click "Generate token" and copy & paste the token in vars/main.yml:

github_token: "your_github_token"

6. Deploy your application

Github username

First, fill in your Github username in vars/main.yml:

github_username: "your_github_user"

Dynamic port

A requirement for your app is that it needs to listen on a dynamic port passed in as the PORT env variable. If your application uses a hardcoded port, I recommend you change it to:

// Use dynamic port from `PORT` env var if it exists, otherwise 3000
const port = process.env.PORT || 3000;

To deploy your application, you need to pass in 3 variables through the command-line:

  • github_repository - You app's repository name on Github
  • branch - Branch name to fetch and deploy. Automated deployments will occur on pushes to this branch
  • entrypoint - Application entry point (eg.: index.js)

For example, to deploy a nodejs-demo application from the main branch with index.js as the entrypoint, you'd run:

ansible-playbook deploy-app.yml --extra-vars "github_repository=nodejs-demo branch=main entrypoint=index.js"

Environment variables

The script will look in the envs folder for a valid YAML file named after the application, and if it finds one, it will pass the environment variables to your app. For example, if you used "github_repository=nodejs-demo ..." during app deployment, then the script will look for a envs/nodejs-demo.yml file.

If all went well, your application is deployed successfully 🚀.

A message will be printed to the console with an URL link to view your app. The link has the form of http://{server-ip}/{github_repository}. To access your application from a custom domain, proceed to the next step "Domain and SSL".

Run this script for each application you wish to add to the server.

Automated deployments

Your application is set to automatically deploy on each push to the branch specified above. Try it out! Make a small change, push to Github, and it'll be live immediately 💫.

7. Domain and SSL

After you have confirmed your application is up and running, you can point your own domain to the server. This allows you to access your application by typing the domain in the browser instead of the server IP.

DNS Configuration

Log in your DNS management tool and make sure the A record points to your server IP address. This is usually where you bought your domain or, if you've changed the nameservers, the owner of those nameservers. If you don't know how to create/change an A record, this Google search query might help "how to set A record <dns_management_tool>".

It can take several hours up to a day for the changes to take effect. You can go to https://dnschecker.org/#A and type in your domain to check if the domain resolves to your server IP address.

Note: if you're using a proxy, say Cloudflare's "yellow cloud", your domain will resolve to Cloudflare's servers to protect your real server IP.

Let's Encrypt email

Under the hood, we use Let's Encrypt to generate a trusted SSL certificate for your application. Let's Encrypt requires an email address to send notifications about the certificate. Before you can generate an SSL certificate for your application, you need to fill in your email in vars/main.yml file:

letsencrypt_email: "your_email"

To generate an SSL certificate, you pass in the name of your application that's installed on the server and the domain, or subdomain, to serve your application from (eg.: mydomain.com or subdomain.mydomain.com).

For example, to generate an SSL certificate for application nodejs-demo with mydomain.com domain, you'd run:

ansible-playbook generate-ssl.yml --extra-vars "github_repository=nodejs-demo domain=mydomain.com"

Note: The script will fail to generate an SSL certificate if your domain isn't pointing to the server. You can wait for the DNS to propagate and retry later.

If the script was successfull, you can navigate to your domain and your application should appear with a green HTTPS lock next to the URL 🔒.

Automated renewal

The SSL certificate is valid for 90 days. When the certificate is close to expiration, it will automatically renew for another 90 days. The certificate will be renewed continuously so you don't have to worry about expiring certificates ever again.

Additional scripts

Update env variables

To update an application's env vars, you simply change its corresponding YAML file in the envs folder and run the update-env.yml script.

To restart an app named nodejs-demo with the latest env variables from envs/nodejs-demo.yml, you'd run:

ansible-playbook update-env.yml --extra-vars "github_repository=nodejs-demo"

Note: If you remove an env variable from the file (or remove the entire file), the env variable will also be removed from the production app. In that sense, the YAML file in the envs folder is the source of truth for your app's env variables.

Remove application

To completely remove an application from the server, run the remove-app.yml script with github_repository variable equal to the application you wish to remove.

To remove an application named nodejs-demo, you'd run:

ansible-playbook remove-app.yml --extra-vars "github_repository=nodejs-demo"

This will stop the application and remove all traces of it on the server. Changes made outside the server, such as the webhook for auto-deployments on Github, are undone as well.

Get in touch

  • Were the instructions clear enough for you to follow along?
  • Did you bump against some issues, or was it a smooth process?
  • Are you missing a feature that would make your life so much easier?
  • Perhaps you're so thrilled with your new setup, that you just want to share your excitement

I'd like to know! Feel free to send me an email at [email protected]. You can also reach out to me on Twitter, my handle is @_maximization.

@naliferov
Copy link

Многовато шагов бро.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment