Created
June 14, 2022 05:21
-
-
Save Utopiah/649403cfe518f3bd30d30694eb6a8a88 to your computer and use it in GitHub Desktop.
doctl-scaling-immers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#cloud-config | |
package_update: true | |
packages: | |
- ca-certificates | |
- curl | |
- gnupg | |
- lsb-release | |
- git | |
write_files: | |
- content: | | |
port=8081 | |
domain=immers.ovh | |
hub=immers.benetou.fr | |
homepage= | |
name=Utopiah Immers Space | |
dbHost=mongodb | |
dbPort=27017 | |
dbName=immers | |
smtpHost=smtp.example.com | |
smtpPort=587 | |
[email protected] | |
smtpUser=apikey | |
smtpPassword=1234 | |
monetizationPointer='$ilp.uphold.com/BYR4KPxJD6ey' | |
googleFont=Monoton | |
backgroundColor=#a6549d | |
backgroundImage=vapor.png | |
customCSS= | |
icon=vaporwave-icon.png | |
imageAttributionText=Vectors by Vecteezy | |
imageAttributionUrl=https://www.vecteezy.com/free-vector/vector | |
sessionSecret= | |
easySecret= | |
path: /root/immers-env | |
runcmd: | |
- sudo mkdir -p /etc/apt/keyrings | |
- curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg | |
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null | |
- sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin | |
- cd /root && git clone https://github.com/immers-space/immers-app.git | |
- mv /root/immers-env /root/immers-app/immers/.env | |
- cd /root/immers-app/immers && docker compose up -d | |
# see result in /var/log/cloud-init-output.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SIMULATION=yes | |
#NAME=immers-via-doctl-with-cloudinit3 | |
# could use numbers or list e.g Greek gods (had a link for it few weeks ago...) | |
# same for subdomains | |
# could use full domain as NAME | |
IMAGE=ubuntu-20-04-x64 | |
SIZE=s-1vcpu-1gb | |
REGION=ams3 | |
# some of the hardcoded ID (e.g ssh-key and domain record) could instead be picked dynamically | |
# relying on the JSON output, easier to parse safely with jq | |
SSHKEYs=29367540 | |
USERDATAFILE=./cloud-init | |
#DOMAIN=testsubdomain3.fosdem-metaverse.ovh | |
ROOTDOMAIN=fosdem-metaverse.ovh | |
#SUBDOMAIN=testsubdomain3 | |
# should match cloud-init | |
TAG=batchcreationtest | |
ENDPOINT=https://CHANGEME.ngrok.io | |
SERVERS="immers1 immers2 immers3" | |
if [ -z "$SIMULATION" ]; then | |
# should insure ngrok is running e.g | |
if [ -n "$(curl --silent $ENDPOINT/ready | grep ERR_NGROK_3200)" ]; | |
then | |
echo ngrok endpoint unreachable, stopping | |
exit # could instead start it but would need the URL back | |
fi | |
fi | |
# should check on root domain | |
#ROOTDOMAIN=$(echo $DOMAIN | sed "s/\([A-Za-z0-9-]\+\.[A-Za-z0-9-]\+\)$/\1/") | |
#SUBDOMAIN=$(echo $DOMAIN | sed "s/\.$ROOTDOMAIN//") | |
for SERVER in $SERVERS; do | |
echo $SERVER.$ROOTDOMAIN | |
DOMAIN=$SERVER.$ROOTDOMAIN | |
NAME=$DOMAIN | |
SUBDOMAIN=$SERVER | |
if [ -z "$SUBDOMAIN" ]; | |
then | |
RECORDID=$(doctl compute domain records list $ROOTDOMAIN -o json | jq '.[] | select (.type == "A").id') | |
else | |
RECORDID=$(doctl compute domain records list $ROOTDOMAIN -o json | jq '.[] | select (.type == "A" and .name == "'$SUBDOMAIN'").id') | |
fi | |
cat cloud-init-template | sed "s/immers.ovh/$DOMAIN/" > $USERDATAFILE | |
echo " - curl https://$DOMAIN" >> $USERDATAFILE # used to active HTTPS certificate registration from the Immers specific process | |
# might be too fast if the DNS propagation isn't ready at this point | |
echo " - curl $ENDPOINT/cloudinitready?servername=$NAME" >> $USERDATAFILE | |
# ping back home when done, e.g email or curl to ngrok then notify-send | |
sed -e "s|sessionSecret=|sessionSecret=$(openssl rand -base64 32)|" -i $USERDATAFILE | |
sed -e "s|easySecret=|easySecret=$(openssl rand -base64 32)|" -i $USERDATAFILE | |
# easySecret=$(openssl rand -base64 32) | |
cp $USERDATAFILE $(date +%s) | |
echo creating droplet | |
if [ $SIMULATION ]; then | |
echo doctl compute droplet create $NAME --image $IMAGE --size $SIZE --region $REGION --ssh-keys $SSHKEYs --user-data-file $USERDATAFILE --tag-name $TAG --wait # to drop for parallel creation | |
else | |
doctl compute droplet create $NAME --image $IMAGE --size $SIZE --region $REGION --ssh-keys $SSHKEYs --user-data-file $USERDATAFILE --tag-name $TAG --wait # to drop for parallel creation | |
fi | |
echo adding new IP to domain | |
SERVERIP=$(doctl compute droplet get $NAME --template {{.PublicIPv4}}) | |
if [ -z "$SUBDOMAIN" ]; | |
then | |
if [ "$RECORDID" != "" ]; # note that it would become a different logic when doing N servers and using subdomains | |
then | |
echo "A record existing, will update (no subdomain)" | |
CMD="doctl compute domain records update $DOMAIN --record-id $RECORDID --record-type A --record-data $SERVERIP" | |
else | |
echo "no A record existing, will create (no subdomain)" | |
CMD="doctl compute domain records create $DOMAIN --record-type A --record-data $SERVERIP --record-name @" | |
fi | |
else | |
if [ "$RECORDID" != "" ]; # note that it would become a different logic when doing N servers and using subdomains | |
then | |
echo A record existing, will update | |
CMD="doctl compute domain records update $ROOTDOMAIN --record-id $RECORDID --record-type A --record-data $SERVERIP" | |
else | |
echo no A record existing, will create | |
CMD="doctl compute domain records create $ROOTDOMAIN --record-type A --record-data $SERVERIP --record-name $SUBDOMAIN" | |
fi | |
fi | |
if [ $SIMULATION ]; then | |
echo $CMD | |
else | |
$CMD | |
fi | |
done | |
# if domain not available then should drop with error message | |
# clean up droplets (but not DNS records, could log those based on records in the current directory, could be useful anyway for a next step e.g load balancer) | |
# doctl compute droplet delete -f $(doctl compute droplet list -o json | jq '.[] | select(.tags) | select(.tags[] == "batchcreationtest").id') | |
# provide a number N to start | |
# consider doing in parallel to avoid waiting too long for N servers to start sequentially | |
# check resizing, including with period based logs with a threshold and metric (note that it needs rebooting) | |
# option of specifying region or making it distributed accross | |
# add subdomain rather than A record | |
# check tags for batch operations | |
# trigger action once payment received (see past Tweets on Hubs via Stripe hook) | |
# take about 3min in total |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// nodejs server to notify when cloud server spawned and ready to be used | |
const fs = require('fs'); | |
const express = require('express') | |
const cors = require('cors') | |
const https = require('https') | |
const path = require('path') | |
const {execSync} = require('child_process'); | |
const app = express() | |
app.use(cors()) | |
app.get('/ready', function(req, res){ | |
res.json({"res":"yes"}) | |
}); | |
app.get('/cloudinitready', function(req, res){ | |
execSync("notify-send "+req.query.servername+" ready") | |
res.json({"res":"notification sent"}) | |
}); | |
const port = 3456 | |
app.listen(port, () => | |
console.log('listening on port', port) | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment