Skip to content

Starting with blob

Pre-requisites

You can self-host a blob instance on a Linux machine with root access (a VPS with 500MB of RAM and a cpu should be enough but do not use docker on a small machine 😜), a domain name or subdomain is needed too. This guide assume a debian-like linux distribution and some sysadmin knowledge.

Requirements

To properly install Blob on Linux, we need NodeJS (>=16 <=20) to be installed on our system.

N.B.: If you do not want to install node wide on the system, or you dont' have a root access and you can't add apt sources, consider installing a nodejs manager in order to manage different versions of node, nvm could be a good choice.

⚠️

sudo (i.e. Super-user do) allows some users to execute some commands as root (or another user). Using sudo is safer than opening a session as root for a number of reasons (nobody needs to know the root password, it's easy to only run the commands that require special privileges).

bash
su root
apt-get install sudo
adduser <yourusername> sudo
exit
su root
apt-get install sudo
adduser <yourusername> sudo
exit

Install global dependencies

Install NodeJS

NodeJS installation is a bit longer in some cases but if you have clean and recent machine you can install using:

bash
sudo apt install nodejs
sudo apt install nodejs

Blob is compatible with nodejs version >=16 <=20, you can check if you have a compatible version using node --version.

What if I do not have a compatibile version installed ?

In case your linux distribution does not include nodejs or includes an incompatible version I suggest you to enable nodesource repositories:

bash
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update
sudo apt-get install nodejs -y
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update
sudo apt-get install nodejs -y

This will install a compatible nodejs release. Note that if you have an old nodejs release you probably need to restart your current terminal session to make sure the new npm and node binary are used.

If you don't have a root access or you prefer not to install nodejs system wide you can go with nvm.

⚠️ This could go wrong

Installing a new release of nodejs could break your old project running on other releases.

Create a new blob user

Like any service running on a production server, blob should run under its own user context. By doing so we eliminate a large security hole and minimize the amount of damage an attacker can do via a vulnerability.

When services running as root become compromised, an attacker will have full access to the server. They obtain root level privileges that permit them to do anything.

On the other hand, by running your service with an unprivileged user account, we significantly decrease our security footprint and the amount of damage that can be done.

The following command creates a service account named as your project.

bash
sudo adduser <yourBlobService>
sudo su - <yourBlobService>
cd
sudo adduser <yourBlobService>
sudo su - <yourBlobService>
cd

Download

You are ready now to download the last blob release and extract it in the right place.

Where is the "right place" for blob?

The "right place" for blob, as for any other webservice, may vary based on your server/environment/system and depends on what you want to achieve. Below configurations we've successfully deployed. Many other are possible!

bash
pwd # the bash will return /home/<yourBlobService>
# proceed with the download
pwd # the bash will return /home/<yourBlobService>
# proceed with the download
bash
cd /var/www 
mkdir blob #create a folder for blob. you may need to change user
chown -R blob:www-data blob/ #change the ownership to the newly created folder to blob/www-data group
sudo su - <yourBlobService> # revert to the <yourBlobService> user
cd /var/www/blob # enter the folder previously created
# proceed with the download
cd /var/www 
mkdir blob #create a folder for blob. you may need to change user
chown -R blob:www-data blob/ #change the ownership to the newly created folder to blob/www-data group
sudo su - <yourBlobService> # revert to the <yourBlobService> user
cd /var/www/blob # enter the folder previously created
# proceed with the download
bash
wget https://blob.news/releases/blob-latest.tgz
tar xvzf blob-latest.tgz
wget https://blob.news/releases/blob-latest.tgz
tar xvzf blob-latest.tgz

Setup your environment

bash
cp .env.example .env
cp .env.example .env

Now edit .env file and modify your base url and your secret tokens following the instructions. Set also your DATABASE_URL and your NITRO_PORT - this port has to be the same specified in NUXT_PUBLIC_BASE_URL

Install services

now from your user rename and edit service files:

bash
blobServiceName=YOURBLOBSERVICE
mv blob.service $blobServiceName.service
blobServiceName=YOURBLOBSERVICE
mv blob.service $blobServiceName.service

then copy and reload the systemd daemon

bash
sudo cp *.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo cp *.service /etc/systemd/system/
sudo systemctl daemon-reload

N.B.: remember to check the ownership of services, the corresponding files should have the permissions root:root

Start web UI

Ready to start the web interface.

bash
sudo systemctl start $blobServiceName
sudo systemctl enable $blobServiceName
sudo systemctl start $blobServiceName
sudo systemctl enable $blobServiceName

Setup http proxy

Blob is now listening to the port you specified in .env file (default 4000), usually we put an http proxy in front of web services, usually nginx or apache2, here's the configuration you'll need to add. N.B.: if you install more than one blob you havo to create different cache folders, accessible by nginx.

nginx
map $sent_http_content_type $expires {
    "text/html"                 1h;
    "text/html; charset=utf-8"  1h;
    default                     7d; # set this to your needs
}

proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=blob_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    listen          80;             # the port nginx is listening on
    server_name     <YOUR-DOMAIN>;    # setup your domain here

    gzip            on;
    gzip_types      text/plain application/xml text/css application/javascript;
    gzip_min_length 1000;

    location / {
        expires $expires;

        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          1m;
        proxy_connect_timeout       1m;
        proxy_pass                          http://127.0.0.1:4000; # set the address of the Node.js instance here
        proxy_cache blob_cache;
        proxy_cache_revalidate on;
        proxy_cache_use_stale error timeout updating http_500 http_502
                              http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
    }
}
map $sent_http_content_type $expires {
    "text/html"                 1h;
    "text/html; charset=utf-8"  1h;
    default                     7d; # set this to your needs
}

proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=blob_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    listen          80;             # the port nginx is listening on
    server_name     <YOUR-DOMAIN>;    # setup your domain here

    gzip            on;
    gzip_types      text/plain application/xml text/css application/javascript;
    gzip_min_length 1000;

    location / {
        expires $expires;

        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          1m;
        proxy_connect_timeout       1m;
        proxy_pass                          http://127.0.0.1:4000; # set the address of the Node.js instance here
        proxy_cache blob_cache;
        proxy_cache_revalidate on;
        proxy_cache_use_stale error timeout updating http_500 http_502
                              http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
    }
}
apache
NOT TO BE USED IN PRODUCTION- THIS IS AN ONGOING CONFIGURATION TO BE FURTHER DEVELOPED 

<VirtualHost *:80> # the port apache is listening on
ServerName YOUR-DOMAIN # setup your domain here
DocumentRoot /
</VirtualHost>
NOT TO BE USED IN PRODUCTION- THIS IS AN ONGOING CONFIGURATION TO BE FURTHER DEVELOPED 

<VirtualHost *:80> # the port apache is listening on
ServerName YOUR-DOMAIN # setup your domain here
DocumentRoot /
</VirtualHost>

Ready to try?

bash
sudo ln -s /etc/nginx/sites-available/<yourdomain>.conf /etc/nginx/sites-enabled/
sudo nginx -t # test current nginx conf
sudo nginx -s reload # reload the modified tested nginx conf
sudo ln -s /etc/nginx/sites-available/<yourdomain>.conf /etc/nginx/sites-enabled/
sudo nginx -t # test current nginx conf
sudo nginx -s reload # reload the modified tested nginx conf
bash
sudo a2ensite /etc/apache2/sites-available/<yourdomain>.conf # enable yourdomain conf
sudo apachectl configtest # test current apache conf
sudo systemctl reload apache2 # reload the modified tested apache conf
sudo a2ensite /etc/apache2/sites-available/<yourdomain>.conf # enable yourdomain conf
sudo apachectl configtest # test current apache conf
sudo systemctl reload apache2 # reload the modified tested apache conf

Install and enable certbot

bash
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx -d your-domain.com
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx -d your-domain.com
bash
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -your-domain.com
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -your-domain.com

View logs

bash
journalctl -xeu $blobServiceName
journalctl -xeu $blobServiceName

Upgrade

before upgrading, backup your .env file if needed. It should not be overridden, but a backup is better than no backup.

bash
rm blob-latest.tgz #remove previously downloaded blob packages, if exist
wget https://blob.news/releases/blob-latest.tgz
tar xvzf blob-latest.tgz

## restart service
sudo systemctl restart blob
rm blob-latest.tgz #remove previously downloaded blob packages, if exist
wget https://blob.news/releases/blob-latest.tgz
tar xvzf blob-latest.tgz

## restart service
sudo systemctl restart blob

Troubleshooting

Q.: How to test if blob is able to start?

A: Manually run: ./blob.mjs start from the install path, with the corresponding user, as in the following

# blob.mjs start for testing
<yourBlobService>:/<yourinstallpath>$ ./blob.mjs start
# blob.mjs start for testing
<yourBlobService>:/<yourinstallpath>$ ./blob.mjs start

if everything's OK, blob will start up by:

  • loading variables from .env file
  • establishing a connection to the DB specified in the .env file
  • looking for prisma/migrations and applying them if needed
  • launching the worker
  • listening on the IP:port specified in the .env

Q.: I have many nodejs versions installed, how can I configure blob to pick up the right one / a specific one?

A.: After checking your current user nodejs version with a node --version, there are many possible configurations. An easy one is to add a line to your .env file, specifying the nodejs version in the variable NODE_VERSION. As in the following:

# specify node version to avoid nodejs path errors
NODE_VERSION=20
# specify node version to avoid nodejs path errors
NODE_VERSION=20

Q.: my blob install is behind a reverse proxy. What's the right value for the NITRO_HOST variable in the .env configuration file?

A.: You can 1. bind the NITRO_HOST to all available network interfaces by setting the IP address at 0.0.0.0, or 2. you can set it to the IP of the machine where the reverse proxy is running, as in the following:

# if behind a reverse proxy
# 0.0.0.0 to bind to all available net interfaces
# YOUR-REVERSE-PROXY-IP to bind exactly to reverse proxy net interface
NITRO_HOST=0.0.0.0
# if behind a reverse proxy
# 0.0.0.0 to bind to all available net interfaces
# YOUR-REVERSE-PROXY-IP to bind exactly to reverse proxy net interface
NITRO_HOST=0.0.0.0