Preparing your server

Spin gives you the power to choose any host that you want. Although the responsibility is on your shoulders to get a server set up, Spin makes it very easy to get this accomplished.

Choose a host

We've run VPS Benchmarks against a number of hosts and have found the following hosts to have great value. The links below are referral links, meaning we get a small kickback if you sign up -- but this doesn't affect our recommendations.

Hetzner

Hetzner is a German-based company with data centers in the EU and the US. Their pricing is very competitive and they have incredible performance.

With the link below, they offer €⁠20 (~$21 USD) credits free which can get you a server for a few months.

Sign Up with Hetzner →

Vultr

Vultr is a US-based company that has a great reputation for performance and value. They have a wide range of data centers around the world and a great API for automation.

With the link below, they are offering $100 in credits -- which can get you quite a bit for a few months.

Sign Up with Vultr →

Digital Ocean

Digital Ocean is a US-based company that has data centers all around the world. Although their performance generally lacks compared to other providers, there are so many resources that natively support their offerings.

With the link below, they are offering $200 in credits over 60 days.

Sign Up with Digital Ocean →

Any other host

Spin is host-agnostic, meaning you can run Spin anywhere. If you have a preferred host, you can use them as well. Just make sure that your host meets the following requirements below.

Hardware specs largely depend on your project, but even for simple apps, we recommend the following:

  • CPU: 1 CPU core
  • RAM: 1GB
  • Storage: >25GB SSD
  • Architecture: x86_64 (64-bit) [request ARM64 support]
  • Operating System: Ubuntu 22.04 LTS or newer
  • Snapshots/Backups: Highly recommended
  • Firewall: Configured to allow SSH and HTTPS traffic (22/tcp, 80/tcp, 443/tcp)
  • Access: Root SSH access

Prepare your DNS

Once you have a server running with the host of your choice, it's recommended to configure your DNS to have two A records created pointing to the IP address of your server.

Two records should be created:

  1. Application Domain Name (example: myapp.example.com)
  2. Server Hostname (example: server01.example.com)
Configure your DNS

Validate your SSH connection

Before you start, make sure you can SSH into your server using an SSH key pair. Many hosts do this by default, but you need to follow your hosts instructions for adding a trusted public key that can connect to your server. If you need help generating an SSH key, you can follow our guide on Generating a Secure SSH Key.

You can do this by running the following command:

SSH into your server

ssh root@myserver01.example.com

Ensure your server is up to date

On your server, it's good practice to ensure everything is updated. Run this command below to update all packages on your server. Restarting the server is a good idea too to ensure everything is up to date.

Update your server

apt -y update && apt -y upgrade && apt -y autoremove && apt -y autoclean && reboot

Configure server inventory and settings

Assuming you've already ran spin new or spin init in your project, there are two files that will need to be configured:

  • .spin-inventory.ini
  • .spin.yml

Inventory

We call the list of our servers "inventory". This follows the Ansible Inventory format. For example, if you wanted to add server01.example.com as the production server, we would configure our file to look like this and add this server to go underneath the production_manager_servers group:

.spin-inventory.ini: Add `server01.example.com` to Production

####################
# Host Types
####################

[production_manager_servers]
server01.example.com

[staging_manager_servers]
# server02.example.com

####################
# Swarm Roles
####################
[swarm_managers:children]
production_manager_servers
staging_manager_servers

####################
# Environment
####################
[production:children]
production_manager_servers

[staging:children]
staging_manager_servers

[all_servers:children]
production
staging

Configure server settings

In the .spin.yml file, you will find many other settings. These are required for you to change so you can connect to your server.

👉 Required to be changed

KeyDescription
server_contactChange this to a valid email. If you're using our Traefik templates, you'll also need to change the letsencryptresolver.acme.email key under the .infrastructure/conf/traefik/prod/traefik.yml file.
docker_user.authorized_ssh_keysOPTIONAL: Use this only if you're having something like GItHub Actions connect as the Docker User. This must be the public key of the your DEPLOY user SSH keypair that you generated.
users.usernameSet this to a username that you'll remember. Be sure to not use any weird characters. It might be in your best interest to match the username of your local machine. You can find this by running whoami in a new terminal.
users.passwordSet this to the secure hash of the password you'd like to use. All users will be prompted to change on first login. Use spin mkpasswd to quickly generate a hash.
users.username.authorized_ssh_keysSet this to your USER public SSH key value. ⚠️ The key pair must be accessible under ~/.ssh on your host. Most of the time the file ends in *.pub.

.spin.yml

---
###########################################
# Basic Server Configuration
###########################################
server_timezone: "Etc/UTC"
server_contact: changeme@example.com # 👈 Change this

# SSH
ssh_port: "22"

## Email Notifications
postfix_hostname: "{{ inventory_hostname }}" # ✅ Set automatically

## Set variables below to enable external SMTP relay
# postfix_relayhost: "smtp.example.com"
# postfix_relayhost_port: "587"
# postfix_relayhost_username: "myusername"
# postfix_relayhost_password: "mysupersecretpassword"

##############################################################
# Deploy User
##############################################################
docker_user:
  username: deploy
  uid: 9999
  group: deploy
  secondary_groups: "docker"
  gid: 9999
  ## Uncomment to set authorized SSH keys for the docker user.
  # authorized_ssh_keys: 
  #   - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKNJGtd7a4DBHsQi7HGrC5xz0eAEFHZ3Ogh3FEFI2345 deploy" # 👈 Change this
  #   - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFRfXxUZ8q9vHRcQZ6tLb0KwGHu8xjQHfYopZKLmnopQ anotherfake@key"

##############################################################
# Users
##############################################################

### Use the template below to set users and their authorized keys
## Passwords must be set with an encrypted hash. To do this, see the Ansible FAQ.
## Your best bet is probably using the `mkpasswd` on a Linux machine.
## https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#how-do-i-generate-encrypted-passwords-for-the-user-module

users:
  - username: alice # 👈 Change this
    name: Alice Smith  # 👈 Change this
    state: present
    groups: ['adm','sudo']
    password: "$6$mysecretsalt$qJbapG68nyRab3gxvKWPUcs2g3t0oMHSHMnSKecYNpSi3CuZm.GbBqXO8BE6EI6P1JUefhA0qvD7b5LSh./PU1" # 👈 Change this
    shell: "/bin/bash"
    authorized_keys:
      - public_key: "ssh-ed25519 AAAAC3NzaC1lmyfakeublickeyMVIzwQXBzxxD9b8Erd1FKVvu alice" # 👈 Change this

#   - username: bob
#     name: Bob Smith
#     state: present
#     password: "$6$mysecretsalt$qJbapG68nyRab3gxvKWPUcs2g3t0oMHSHMnSKecYNpSi3CuZm.GbBqXO8BE6EI6P1JUefhA0qvD7b5LSh./PU1"
#     groups: ['adm','sudo']
#     shell: "/bin/bash"
#     authorized_keys:
#       - public_key: "ssh-ed25519 AAAAC3NzaC1anotherfakekeyIMVIzwQXBzxxD9b8Erd1FKVvu bob"

Run spin provison

Once you have .spin.yml and .spin-inventory.ini configure, you're ready to provision your server(s).

Provision your server(s)

spin provision --user root

This process will automatically download our Ansible collection and apply the changes on your server.

Confirm everything works

To confirm everything works as expected, try to SSH into your server using the username you created before. You will be prompted to change your password to a new password as soon as you login.

Connect to your server via SSH

ssh myuser@server01.example.com

If you get a connection, you should be ready to receive deployments to Docker Swarm via SSH 🥳

Next Steps

If you're using the spin deploy deployment strategy, then take a look at our guide on how to run a simple deployment.

Deploy Your Project with spin deploy