This directory contains a setup guide and scripts that will install and configure some basic requirements for running a Skynet Portal. The assumption is that we are working with a Debian Buster Minimal system or similar.
You may want to fork this repository and replace ssh keys in
setup-scripts/support/authorized_keys
and optionally edit the setup-scripts/support/tmux.conf
and setup-scripts/support/bashrc
configurations to fit your needs.
- dockerized services inside
docker-compose.yml
- sia (docker hub): storage provider, heart of the portal setup
- caddy (docker hub): reverse proxy (similar to nginx) that handles ssl out of a box and acts as a transparent entry point
- openresty (docker hub): nginx custom build, acts as a cached proxy to siad and exposes all api endpoints
- health-check: simple service that runs periodically and collects health data about the server (status and response times) - read more
- handshake (github): full handshake node
- handshake-api: simple API talking to the handshake node - read more
- webapp: portal frontend application - read more
- kratos: user account management system
- oathkeeper: identity and access proxy
- discord integration
- funds-checker: script that checks wallet balance and sends status messages to discord periodically
- health-checker: script that monitors health-check service for server health issues and reports them to discord periodically
- log-checker: script that scans siad logs for critical errors and reports them to discord periodically
- blocklist-skylink: script that can be run locally from a machine that has access to all your skynet portal servers that blocklists provided skylink and prunes nginx cache to ensure it's not available any more (that is a bit much but that's the best we can do right now without paid nginx version) - if you want to use it, make sure to adjust the server addresses
- SSH in a freshly installed Debian machine on a user with sudo access (can be root)
apt-get update && apt-get install sudo -y
to make suresudo
is availableadduser user
to create user calleduser
(creates/home/user
directory)usermod -aG sudo user
to add this new user to sudo group- Quit the ssh session with
exit
command
You a can now ssh into your machine as the user user
.
- On your local machine:
ssh-copy-id user@ip-addr
to copy over your ssh key to server - On your local machine:
ssh user@ip-addr
to log in to server as useruser
- You are now logged in as
user
Following step will be executed on remote host logged in as a user
:
sudo apt-get install git -y
to install gitgit clone https://github.com/NebulousLabs/skynet-webportal
- run setup scripts in the exact order and provide sudo password when asked (if one of them fails, you can retry just this one before proceeding further)
/home/user/skynet-webportal/setup-scripts/setup-server.sh
/home/user/skynet-webportal/setup-scripts/setup-docker-services.sh
/home/user/skynet-webportal/setup-scripts/setup-health-check-scripts.sh
(optional)
At this point we have almost everything running, we just need to set up your wallet and allowance:
- Create new wallet (remember to save the seeds)
docker exec -it sia siac wallet init
- Unlock wallet (use seed as password)
docker exec -it sia siac wallet unlock
- Generate wallet addresse (save them for later to transfer the funds)
docker exec -it sia siac wallet address
- Set up allowance
docker exec -it sia siac renter setallowance
- 10 KS (keep 25 KS in your wallet)
- default period
- default number of hosts
- 4 week renewal time
- 500 GB expected storage
- 500 GB expected upload
- 5 TB expected download
- default redundancy
- Instruct siad to start making 10 contracts per block with many hosts to potentially view the whole network's files
docker exec -it sia siac renter setallowance --payment-contract-initial-funding 10SC
-
edit
/home/user/skynet-webportal/.env
and configure following environment variablesDOMAIN_NAME
(optional) is your domain name if you have itEMAIL_ADDRESS
(required) is your email address used for communication regarding SSL certification (required)SIA_WALLET_PASSWORD
(required) is your wallet password (or seed if you did not set a password)HSD_API_KEY
(optional) this is a random security key for a handshake integration that gets generated automaticallyCLOUDFLARE_AUTH_TOKEN
(optional) if using cloudflare as dns loadbalancer (need to change it in Caddyfile too)AWS_ACCESS_KEY_ID
(optional) if using route53 as a dns loadbalancerAWS_SECRET_ACCESS_KEY
(optional) if using route53 as a dns loadbalancerPORTAL_NAME
(optional) e.g.siasky.xyz
DISCORD_BOT_TOKEN
(optional) if you're using Discord notifications for health checks and suchSKYNET_DB_USER
(optional) if usingaccounts
this is the MongoDB usernameSKYNET_DB_PASS
(optional) if usingaccounts
this is the MongoDB passwordSKYNET_DB_HOST
(optional) if usingaccounts
this is the MongoDB address or container nameSKYNET_DB_PORT
(optional) if usingaccounts
this is the MongoDB portCOOKIE_DOMAIN
(optional) if usingaccounts
this is the domain to which your cookies will be issuedCOOKIE_HASH_KEY
(optional) if usingaccounts
hashing secret, at least 32 bytesCOOKIE_ENC_KEY
(optional) if usingaccounts
encryption key, at least 32 bytes
-
if you have a custom domain and you configured it in
DOMAIN_NAME
, edit/home/user/skynet-webportal/docker/caddy/Caddyfile
and uncommentimport custom.domain
-
only for siasky.net domain instances: edit
/home/user/skynet-webportal/docker/caddy/Caddyfile
, uncommentimport siasky.net
-
docker-compose up -d
to restart the services so they pick up new env variables -
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
to reload Caddyfile configuration -
add your custom Kratos configuration to
/home/user/skynet-webportal/docker/kratos/config/kratos.yml
(in particular, the credentials for your mail server should be here, rather than in your source control). For a starting point you can takedocker/kratos/config/kratos.yml.sample
.
It might prove useful for certain skapps to be accessible through a custom subdomain. So instead of being accessed through https://portal.com/[skylink]
, it would be accessible through https://[skylink_base32].portal.com
. We call this "subdomain access" and it is made possible by encoding Skylinks using a base32 encoding. We have to use a base32 encoding scheme because subdomains have to be all lower case and the base64 encoded Skylink is case sensitive and thus might contain uppercase characters.
You can convert Skylinks using this converter skapp. To see how the encoding and decoding works, please follow the link to the repo in the application itself.
There is also an option to access handshake domain through the subdomain using https://[domain_name].hns.portal.com
.
To configure this on your portal, you have to make sure to configure the following:
We need to ensure SSL encryption for skapps that are accessed through their subdomain, therefore we need to have a wildcard certificate. This is very easily achieved using Caddy.
(siasky.net) {
siasky.net, *.siasky.net, *.hns.siasky.net {
...
}
}
(see docker/caddy/Caddyfile)
In Nginx two things need to happen:
# understand the regex https://regex101.com/r/BGQvi6/6
server_name "~^(((?<base32_subdomain>([a-z0-9]{55}))|(?<hns_domain>[^\.]+)\.hns)\.)?((?<portal_domain>[^.]+)\.)?(?<domain>[^.]+)\.(?<tld>[^.]+)$";
First you need to redirect the requests based on the regex above matching either base32_subdomain
or hns_domain
.
location / {
# This is the only safe workaround to reroute based on some conditions
# See https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
recursive_error_pages on;
# redirect links with base32 encoded skylink in subdomain
error_page 418 = @base32_subdomain;
if ($base32_subdomain != "") {
return 418;
}
# redirect links with handshake domain on hns subdomain
error_page 419 = @hns_domain;
if ($hns_domain != "") {
return 419;
}
...
}
Define locations for @base32_subdomain
and @hns_domain
redirects.
location @base32_subdomain {
include /etc/nginx/conf.d/include/proxy-buffer;
proxy_pass http://127.0.0.1/$base32_subdomain/$request_uri;
}
location @hns_domain {
include /etc/nginx/conf.d/include/proxy-buffer;
proxy_pass http://127.0.0.1/hns/$hns_domain/$request_uri;
}
(see docker/nginx/nginx.conf)
- Starting the whole stack
docker-compose up -d
- Stopping the whole stack
docker-compose down
- Accessing siac
docker exec -it sia siac
- Portal maintenance
- Pulling portal out for maintenance
scripts/portal-down.sh
- Putting portal back into place after maintenance
scripts/portal-up.sh
- Upgrading portal containers (takes care of pulling it and putting it back)
scripts/portal-upgrade.sh
- Pulling portal out for maintenance
- Restarting caddy gracefully after making changes to Caddyfile (no downtime)
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
- Restarting nginx gracefully after making changes to nginx configs (no downtime)
docker exec nginx openresty -s reload
- Checking siad service logs (since last hour)
docker logs --since 1h $(docker ps -q --filter "name=^sia$")
- Checking caddy logs (for example in case ssl certificate fails)
docker logs caddy -f
- Checking nginx logs (nginx handles all communication to siad instances)
tail -n 50 docker/data/nginx/logs/access.log
to follow last 50 lines of access logtail -n 50 docker/data/nginx/logs/error.log
to follow last 50 lines of error log