Blockscout

Blockscout v4.1.8-beta: legacy source installation with PostgreSQL and systemd on Ubuntu.

Blockscout

GitHub

Legacy Manual Deployment

Ubuntu 18.04 LTS — Legacy Installation

Install the Blockscout backend and its bundled legacy interface from source, then manage the application with systemd.

This is a revision of the original Ubuntu 18.04 installation notes, pinned to v4.1.8-beta. It is an archival guide for an existing private network. The legacy UI is deprecated; use the current deployment guide for a new installation. Do not apply these commands to the current master branch.

The configuration was checked against the tagged source. A complete installation has not been run for this revision; old package repositories and dependency downloads may require maintenance.

Environment

Component Version or example value
Operating system Ubuntu 18.04.6 LTS, x86_64
Blockscout v4.1.8-beta
Erlang/OTP 24.3.4.1
Elixir 1.13.4-otp-24
Node.js 16.16.0, with npm 8.x
PostgreSQL 10.x from the original Ubuntu environment
Explorer host 192.168.77.64
Geth-compatible node 192.168.77.70
Database Local to the explorer host, 127.0.0.1:5432
Native coin symbol NBAI

The Erlang, Elixir, and Node.js versions match the release’s .tool-versions. Replace the example IP addresses and coin symbol with your network settings. This old stack is not a current production baseline.

Install Build Dependencies

Run the administration commands from your regular sudo-enabled account.

sudo apt update
sudo apt install -y build-essential autoconf automake libtool libncurses5-dev libssl-dev libgmp-dev inotify-tools git curl ca-certificates unzip xz-utils python3 openssl postgresql postgresql-contrib

sudo systemctl enable --now postgresql
sudo -u postgres psql -c 'SELECT version();'

Create the Service Account

Use the same account and directory for downloading, building, and running Blockscout.

sudo adduser --system --group --home /opt/blockscout --shell /bin/bash blockscout
sudo install -d -o blockscout -g blockscout -m 0750 /opt/blockscout

Configure PostgreSQL

Create the database as its owner. Enter a new database password when prompted; use a randomly generated hexadecimal password to avoid URL-encoding issues in DATABASE_URL.

openssl rand -hex 32
sudo -u postgres createuser --pwprompt blockscout
sudo -u postgres createdb --owner=blockscout blockscout
psql -h 127.0.0.1 -U blockscout -d blockscout -W -c 'SELECT current_database();'

The last command must succeed before continuing. This procedure uses a fresh local database, so PostgreSQL does not need a public listening address. If the role or database already exists, inspect it instead of recreating it.

For a separate database server, use its address consistently in DATABASE_URL, allow the explorer host in pg_hba.conf, configure listen_addresses, and verify the connection from the explorer host. Configure PostgreSQL TLS before enabling ECTO_USE_SSL=true for that connection.

Check the Blockchain Node

The node must provide historical data and the tracing methods required by this Blockscout release. A successful eth_blockNumber request alone does not establish tracing or archive-data support. Check the client requirements for your node.

curl --fail --silent --show-error http://192.168.77.70:8545 -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

curl --fail --silent --show-error http://192.168.77.70:8545 -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":2}'

Check the JSON response for an RPC error. The block number should be returned as a hexadecimal value; eth_syncing normally returns false after synchronization. Permit RPC access from the explorer host on the private network.

Install the Versioned Toolchain

Switch to the service account. The following commands, through the build section, run as blockscout.

sudo -iu blockscout

git clone --branch v0.10.2 --depth 1 https://github.com/asdf-vm/asdf.git "$HOME/.asdf"
. "$HOME/.asdf/asdf.sh"

asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
asdf plugin add elixir https://github.com/asdf-vm/asdf-elixir.git
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git

git clone --branch v4.1.8-beta --depth 1 https://github.com/blockscout/blockscout.git "$HOME/app"
cd "$HOME/app"

export KERL_CONFIGURE_OPTIONS='--without-javac --without-wx'
asdf install

elixir --version
node --version
npm --version

This uses the historical asdf shell interface. If an updated plugin no longer supports it, use an archived compatible plugin revision; do not silently replace the application’s required runtimes.

This release also builds Rust dependencies. Install Rust and Cargo together under the service account, without sudo:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/blockscout-rustup.sh
sh /tmp/blockscout-rustup.sh -y --profile minimal
. "$HOME/.cargo/env"

rustc --version
cargo --version

The release does not pin Rust in .tool-versions. If the old native dependencies fail with a current Rust compiler, use a toolchain compatible with the locked dependencies and record its version. Do not install a second Cargo package with apt.

Configure the Environment

Create one environment file for both the build shell and systemd. These values follow the tagged production runtime configuration.

umask 077
cat > "$HOME/blockscout.env" <<'EOF'
MIX_ENV=prod
PORT=4000
BLOCKSCOUT_HOST=192.168.77.64
BLOCKSCOUT_PROTOCOL=http
ETHEREUM_JSONRPC_VARIANT=geth
ETHEREUM_JSONRPC_HTTP_URL=http://192.168.77.70:8545
ETHEREUM_JSONRPC_TRACE_URL=http://192.168.77.70:8545
ETHEREUM_JSONRPC_WS_URL=ws://192.168.77.70:8546
DATABASE_URL=postgresql://blockscout:REPLACE_WITH_DATABASE_PASSWORD@127.0.0.1:5432/blockscout
ECTO_USE_SSL=false
POOL_SIZE=40
POOL_SIZE_API=10
COIN=NBAI
EOF

printf 'SECRET_KEY_BASE=%s\n' "$(openssl rand -hex 64)" >> "$HOME/blockscout.env"
chmod 600 "$HOME/blockscout.env"
nano "$HOME/blockscout.env"

Replace the database password before proceeding. Install nano from the administration account if needed, or use an available editor. The local database connection explicitly disables TLS; do not copy that setting to an untrusted network.

Set ETHEREUM_JSONRPC_VARIANT to match the actual node client. Keep the WebSocket URL only when that endpoint is enabled; otherwise remove the line. HTTP and trace URLs may be identical when one node serves both APIs.

Do not put export before assignments in this file. Load it into the build shell:

set -a
. "$HOME/blockscout.env"
set +a

Compile Blockscout

Run all commands from the pinned checkout with MIX_ENV=prod loaded.

cd "$HOME/app"
mix local.hex --force
mix local.rebar --force
mix deps.get
mix deps.compile
mix compile

mix ecto.migrate

cd "$HOME/app/apps/block_scout_web/assets"
npm ci
npm run deploy

cd "$HOME/app/apps/explorer"
npm ci

cd "$HOME/app"
mix phx.digest
asdf reshim

The database was already created by the PostgreSQL administrator, so only migrations are needed here. Preserve the repository lockfiles; do not run npm audit fix or update dependencies as part of reproducing this build. If current Hex or Rebar tooling rejects the old runtime, select a compatible tooling release before continuing.

The asset build and digest steps follow the release’s Dockerfile and frontend scripts.

Test the application in the foreground:

mix phx.server

Open http://192.168.77.64:4000 from a host that can reach the explorer. After checking the page and logs, press Ctrl+C and finish stopping the Erlang process before starting the service. Leave the service-account shell:

exit

Create the systemd Service

Back in your regular sudo-enabled account:

sudo tee /etc/systemd/system/blockscout.service > /dev/null <<'EOF'
[Unit]
Description=Blockscout Blockchain Explorer
Wants=network-online.target
After=network-online.target postgresql.service

[Service]
Type=simple
User=blockscout
Group=blockscout
WorkingDirectory=/opt/blockscout/app
Environment=HOME=/opt/blockscout
Environment=PATH=/opt/blockscout/.asdf/shims:/opt/blockscout/.asdf/bin:/opt/blockscout/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
EnvironmentFile=/opt/blockscout/blockscout.env
ExecStart=/opt/blockscout/.asdf/shims/mix phx.server
Restart=on-failure
RestartSec=10
TimeoutStopSec=60
UMask=0077
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

sudo systemd-analyze verify /etc/systemd/system/blockscout.service
sudo systemctl daemon-reload
sudo systemctl enable --now blockscout.service

The explicit PATH lets systemd find the same runtimes used during compilation. systemd handles restarts; a HEART_COMMAND that calls systemctl is unnecessary.

Verify the Installation

sudo systemctl status blockscout.service --no-pager
sudo journalctl -u blockscout.service -n 100 --no-pager
sudo ss -ltnp
curl -I http://127.0.0.1:4000/

Confirm that the explorer shows the intended chain, new blocks appear, and the logs contain no repeating RPC, tracing, or database errors. Indexing historical blocks can take a long time.

This configuration serves HTTP on port 4000. It does not create an HTTPS listener on port 4001. HTTPS requires a separately configured TLS reverse proxy and matching public host/protocol settings.

If UFW is already active, allow HTTP only from the required private subnet:

sudo ufw allow from 192.168.77.0/24 to any port 4000 proto tcp
sudo ufw status

Service Management

sudo systemctl restart blockscout.service
sudo systemctl stop blockscout.service
sudo systemctl start blockscout.service
sudo journalctl -u blockscout.service -f

After changing the environment file, restart the service. Rebuild with the same environment when changing a compile-time setting. Run daemon-reload only when the service unit changes.

Troubleshooting

Symptom Check
Database connection fails Use postgresql://, verify the password, and test the exact host with psql.
Database SSL error Match ECTO_USE_SSL to the database’s TLS configuration.
mix or erl is not found by systemd Check the service account, asdf shims, and unit PATH.
Frontend assets are missing Run npm ci, npm run deploy, and mix phx.digest under the production environment.
Blocks or internal transactions are missing Check RPC reachability, archive data, trace support, and the configured client variant.
Port 4000 is already in use Stop the foreground test process and inspect sudo ss -ltnp.
HTTPS on port 4001 fails This guide configures HTTP only; add a TLS reverse proxy separately.

Inotify Limit

Only change this setting if a development file watcher reports an inotify limit error. It is not a routine requirement for the production service.

cat /proc/sys/fs/inotify/max_user_watches

echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/99-blockscout-inotify.conf
sudo sysctl -p /etc/sysctl.d/99-blockscout-inotify.conf
Licensed under CC BY-NC-SA 4.0
Last updated on Wednesday, September 23, 2026
comments powered by Disqus