Appearance
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