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) , Redis 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 Redis

bash
sudo apt install redis-server
sudo apt install redis-server

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.

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

Install local dependencies

The archive does not contain the whole dependencies, let's install it

bash
npm install
npm install

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

create upload directory

bash
mkdir upload
mkdir upload

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

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

Create an administrator

bash
./blob.mjs user create admin password
./blob.mjs user create admin password

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

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
no
no

Ready to try?

bash
sudo ln -s /etc/nginx/sites-available/<yourdomain>.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo nginx -s reload
sudo ln -s /etc/nginx/sites-available/<yourdomain>.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo nginx -s reload
bash
no
no

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

View logs

bash
journalctl -xeu $blobServiceName
journalctl -xeu $blobServiceName-worker
journalctl -xeu $blobServiceName
journalctl -xeu $blobServiceName-worker

Upgrade

before upgrading, backup your .env file if needed

bash
wget https://blob.news/releases/blob-latest.tgz
tar xvzf blob-latest.tgz

## install new dependencies
npm install

## restart worker and web ui
sudo systemctl restart blob
sudo systemctl restart blob-worker
wget https://blob.news/releases/blob-latest.tgz
tar xvzf blob-latest.tgz

## install new dependencies
npm install

## restart worker and web ui
sudo systemctl restart blob
sudo systemctl restart blob-worker