Skip to content

Instantly share code, notes, and snippets.

@whilei
Forked from robinmonjo/minibian-setup.md
Last active December 25, 2017 02:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whilei/a8c6409f6d85fa74607cc2e322c2d883 to your computer and use it in GitHub Desktop.
Save whilei/a8c6409f6d85fa74607cc2e322c2d883 to your computer and use it in GitHub Desktop.
Install + configure Minibian from Mac for use with Geth Classic

The raspberry pi and all components I used are as follows. I made an Amazon idea list with all included here - http://a.co/7WlOZbE

  • Raspberry Pi 3 Model B motherboard (1.2GHz 64-bit quad-core ARMv8 CPU, 1 GB RAM)
  • Samsung 95MB/s (U1) MicroSD EVO Memory Card with Adapter 32 GB (MB-MP32GA/AM)
  • Sandisk CZ48 128GB USB 3.0 Flash memory Drive - SDCZ48-128G-U46
  • Smraza Case for Raspberry Pi 3 with Fan Cooling and Heatsinks, 5V/2.5A Power Supply, Micro USB with On/Off Switch Case for Pi 3B 2 Model B (Not include Raspberry pi board)
  • an ethernet cable

Prepare SD card

Connect to the Pi

  • Disconnect Power from RPi
  • insert SD into your RPi
  • Connect Power
  • Connect Ethernet from Pi to the Router
  • Turn the Pi on
  • Now you need to find out which IP your RPi was assigned (for example: 192.168.0.161)
    • Option 1: Visit 192.168.0.1 in your browser to find the Router web interface
    • Option 2: ping 192.168.0.255 to look for a new IP to show up
  • login with SSH ssh root@192.168.0.161 (default password: raspberry)
ssh root@<pi.ip.address>
# Change root's password
passwd

apt-get update
# Note: gcc is required if you want to compile geth
# build-essential required to build c 
apt-get install sudo raspi-config vim sudo gcc git usbutils rpi-update wpasupplicant build-essential less -y
raspi-config
# * Set host name if you're into that kind of thing
# * Set timezone
# * Expand the FS (this actually makes a difference)

[Optional] Add a user

adduser gethrunner
sudo vim /etc/sudoers
# copy and paste the 'root ALL=(ALL:ALL)' or whatever line, replacing 'root' with the new user's name
# # root ALL=(ALL:ALL)
# This allows gethrunner to use the /usr/bin/geth
# This won't be the default go bin install path, so we'll move it there once it's built
# to make it available for all system users.
# # gethrunner ALL=(ALL:ALL) NOPASSWD:/usr/bin/geth

# now logout and you can log back in
exit
ssh isaac@192.162.0.161

Install Go

ssh gethrunner@192.162.0.161

Set up go env vars

/home/gethrunner/.bashrc

export PATH=$PATH:/usr/local/go/bin
export GOARM=6 # pretty sure it's 6 for rpi 3 model b. Thought it was 8, but couldn't get the go armv8(64bit) to work on mine.
# Go install docs say don't set this var unless it isn't the default, ie if you're using go1.x versions or whatever
# export GOROOT=/usr/local/go
export GOPATH=/home/isaac/go
export PATH=$PATH:$GOPATH/bin

And source the new configs . /home/gethrunner/.bashrc

Get go

I tried the arm64 with my pi but it didn't work, even though it should be ARMv8 64bit. I don't know why it didn't work, but the dist below worked.

The latest available go releases are here https://golang.org/dl/#unstable.

wget https://redirector.gvt1.com/edgedl/go/go1.9.2.linux-armv6l.tar.gz
tar -xvf go1.9.2.linux-armv6l.tar.gz --strip-components=1 /usr/local/go

Install geth classic

go get -v github.com/ethereumproject/go-ethereum/...
go install github.com/ethereumproject/go-ethereum/cmd/geth

Set up external storage

The USB flash drive we're going to use to store the chain on. We want the USB drive to always mount automatically on start up and to mount at the same place.

root@freya3:~# mkdir /mnt/usbstorage

sudo chown -R root:root /mnt/usbstorage
sudo chmod -R 775 /mnt/usbstorage

ia@freya2:~$ sudo setfacl -Rdm g:root:rwx /mnt/usbstorage
ia@freya2:~$ sudo setfacl -Rm g:root:rwx /mnt/usbstorage

root@freya3:~# blkid
/dev/mmcblk0: PTTYPE="dos"
/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="BD97-35E6" TYPE="vfat"
/dev/mmcblk0p2: UUID="f55adb7f-6d96-4e27-a51d-a274dfa58214" TYPE="ext4"
/dev/sda1: UUID="62B7-4BEB" TYPE="vfat"

root@freya3:~# sudo mount -o uid=root,gid=root /dev/sdb1 /mnt/usbstorage

root@freya3:~# ls -l /dev/disk/by-uuid
total 0
lrwxrwxrwx 1 root root 10 Dec 11 15:45 62B7-4BEB -> ../../sda1
lrwxrwxrwx 1 root root 15 Dec 11 15:45 BD97-35E6 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 15 Dec 11 15:45 f55adb7f-6d96-4e27-a51d-a274dfa58214 -> ../../mmcblk0p2

root@freya3:~# vim /etc/fstab

root@freya3:~# cat /etc/fstab
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 errors=remount-ro,noatime,nodiratime,commit=120 0 1
UUID=62B7-4BEB /mnt/usbstorage vfat nofail,uid=root,gid=root 0 0
tmpfs /tmp tmpfs defaults,nodev,nosuid 0 0

root@freya3:~# reboot

[Optional] Set up swap

USB swap file

Will be sloooow. And may break your USB flash drive.

root@freya3:~# free -m
             total       used       free     shared    buffers     cached
Mem:           973        111        861          6          2         52
-/+ buffers/cache:         57        916
Swap:            0          0          0

# swap size = mem size is very reasonable
# so you'll have 2GB of virtual memory
# note here that i'm using a DIFFERENT USB flash drive. a shitty old one.
root@freya3:~# dd if=/dev/zero of=/mtn/usbswap/swapfile bs=1M count=850
850+0 records in
850+0 records out
891289600 bytes (891 MB) copied, 71.2592 s, 12.5 MB/s

root@freya3:~# mkswap /mnt/usbswap/swapfile
Setting up swapspace version 1, size = 870396 KiB
no label, UUID=7787e015-56e2-4e96-bca5-7a0fbdacaaac

root@freya3:~# swapon /mnt/usbswap/swapfile
swapon: /mnt/usbswap/swapfile: insecure permissions 0755, 0600 suggested.

root@freya3:~# chown root:root /mnt/usbswap/swapfile

root@freya3:~# chmod 0600 /mnt/usbswap/swapfile

root@freya3:~# vim /etc/fstab

root@freya3:~# cat /etc/fstab
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 errors=remount-ro,noatime,nodiratime,commit=120 0 1
UUID=62B7-4BEB /mnt/usbstorage vfat nofail 0 0
UUID=748C-11FC /mnt/usbswap vfat nofail 0 0
tmpfs /tmp tmpfs defaults,nodev,nosuid 0 0
/mnt/usbswap/swapfile none swap sw 0 0

root@freya3:~# free -m
             total       used       free     shared    buffers     cached
Mem:           973        967          6          6          9        821
-/+ buffers/cache:        135        837
Swap:          849          0        849

zram

Uses swap on the boot SD card. May also be slow. May also kill your SD card.

root@freya3:~# wget -O /usr/bin/zram.sh https://raw.githubusercontent.com/novaspirit/rpi_zram/master/zram.sh
--2017-12-13 19:19:11--  https://raw.githubusercontent.com/novaspirit/rpi_zram/master/zram.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.184.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.184.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 445 [text/plain]
Saving to: ‘/usr/bin/zram.sh’

/usr/bin/zram.sh                                                    100%[=====================================================================================================================================================================>]     445  --.-KB/s   in 0s

2017-12-13 19:19:11 (2.94 MB/s) - ‘/usr/bin/zram.sh’ saved [445/445]

root@freya3:~# chmod +x /usr/bin/zram.sh

root@freya3:~# vim /etc/rc.local

root@freya3:~# cat /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

/usr/bin/printf "         My IP address is\033[0;31m `/sbin/ifconfig | grep "inet addr" | grep -v "127.0.0.1" | awk '{ print $2 }' | awk -F: '{ print $2 }'` \033[0m\n" > /dev/console

/usr/bin/zram.sh &
exit 0

root@freya3:~# reboot

~  ⟠ ssh f2w

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Dec 13 19:01:31 2017 from 192.168.0.137
root@freya3:~# free -m
             total       used       free     shared    buffers     cached
Mem:           973         85        888          6          7         36
-/+ buffers/cache:         40        933
Swap:         1823          0       1823

Set up systemd service for geth

root@freya3:~# cat /etc/systemd/system/geth.service
[Unit]
Description=Ethereum Classic Mainnet

[Service]
Type=simple
User=gethrunner
Restart=always
RestartSec=3
TimeoutStopSec=10min
ExecStart=/bin/sh -c 'GOGC=50 GOMAXPROCS=2 /root/go/bin/geth --datadir /mnt/usbstorage/geth --cache=100 --fast --log-dir /mnt/usbstorage/geth/mainnet/log --mlog=json --verbosity 3 --ipc-disable --rpc --rpc-addr=192.168.0.161 2>>/dev/null'

[Install]
WantedBy=default.target

Note that I'm using GOGC=50 and GOMAXPROCS=2 env vars for the geth command. Initially run without them, I was finding geth getting killed and restarted every 5-15 minutes. Investigating that looked like this:

root@freya3:~#  tail -n 400 /var/log/messages | grep geth
Dec 11 19:17:04 freya3 kernel: [12684.396578] [ 1749]     0  1749   411421   235911     507       0        0             0 geth
Dec 11 19:22:41 freya3 kernel: [13020.490163] geth invoked oom-killer: gfp_mask=0x200da, order=0, oom_score_adj=0
Dec 11 19:22:41 freya3 kernel: [13020.498354] geth cpuset=/ mems_allowed=0
Dec 11 19:22:41 freya3 kernel: [13020.503091] CPU: 2 PID: 1807 Comm: geth Not tainted 4.1.18-v7+ #846
Dec 11 19:22:41 freya3 kernel: [13020.948752] [ 1804]     0  1804   403565   234815     509       0        0             0 geth
Dec 11 19:22:41 freya3 kernel: [13021.469523] [ 1805]     0  1804   403565   234997     509       0        0             0 geth
Dec 11 19:28:31 freya3 kernel: [13371.161028] geth invoked oom-killer: gfp_mask=0x200da, order=0, oom_score_adj=0
Dec 11 19:28:31 freya3 kernel: [13371.169255] geth cpuset=/ mems_allowed=0
Dec 11 19:28:31 freya3 kernel: [13371.174008] CPU: 3 PID: 1863 Comm: geth Not tainted 4.1.18-v7+ #846
Dec 11 19:28:31 freya3 kernel: [13371.621217] [ 1837]     0  1837   406205   235611     509       0        0             0 geth
Dec 11 19:38:04 freya3 kernel: [13943.773353] geth invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
Dec 11 19:38:04 freya3 kernel: [13943.786736] geth cpuset=/ mems_allowed=0
Dec 11 19:38:04 freya3 kernel: [13943.794620] CPU: 3 PID: 1884 Comm: geth Not tainted 4.1.18-v7+ #846
Dec 11 19:38:04 freya3 kernel: [13944.284919] [ 1870]     0  1870   435725   234687     518       0        0             0 geth
Dec 11 19:46:15 freya3 kernel: [14434.691618] geth invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
Dec 11 19:46:15 freya3 kernel: [14434.699809] geth cpuset=/ mems_allowed=0
Dec 11 19:46:15 freya3 kernel: [14434.704600] CPU: 3 PID: 1969 Comm: geth Not tainted 4.1.18-v7+ #846
Dec 11 19:46:15 freya3 kernel: [14435.172558] [ 1952]     0  1952   408621   233181     504       0        0             0 geth
Dec 11 20:05:41 freya3 kernel: [15601.225677] [ 2033]     0  2033   413901   233764     506       0        0             0 geth

So knocking down these is just a simple way to adjust go's runtime allowances to be less greedy/ambitious, and I have not fine-tuned them at all. See https://dave.cheney.net/tag/gomaxprocs for a quick explanation about these vars. Also geth's --cache=100 is probably overkill (or is it underkill?), but I just wanted to start with an extremely lowball estimation the RPi's strength to make sure geth can operate consistently.

Enable, start, and check the geth.service

systemctl daemon-reload
systemctl enable geth.service
systemctl start geth.service

root@freya3:~# systemctl status geth.service
● geth.service - Ethereum Mainnet
   Loaded: loaded (/etc/systemd/system/geth.service; enabled)
   Active: active (running) since Mon 2017-12-11 20:10:20 CST; 12h ago
 Main PID: 2364 (sh)
   CGroup: /system.slice/geth.service
           ├─2364 /bin/sh -c GOGC=50 GOMAXPROCS=2 /root/go/bin/geth --datadir /mnt/usbstorage/geth --cache=100 --fast --log-dir /mnt/usbstorage/geth/mainnet/log --mlog=json --verbosity 3 --ipc-disable ...
           └─2371 /root/go/bin/geth --datadir /mnt/usbstorage/geth --cache=100 --fast --log-dir /mnt/usbstorage/geth/mainnet/log --mlog=json --verbosity 3 --ipc-disable

Dec 11 20:10:20 freya3 systemd[1]: Started Ethereum Mainnet.

Monitor geth via RPC

With curl

~  ⟠ curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_blockNumber", "params": [], "id": 1}' http://192.168.0.161:8545
{"jsonrpc":"2.0","id":1,"result":"0x281f38"}

With the geth JS console

⟠ geth attach http://192.168.0.161:8545
Welcome to the Geth JavaScript console!

instance: Geth/source/linux/go1.9.2
 modules: eth:1.0 net:1.0 rpc:1.0 web3:1.0

> eth.syncing
{
  currentBlock: 2716124,
  highestBlock: 5005352,
  knownStates: 803,
  pulledStates: 18,
  startingBlock: 2716111
}

[Optional]

Set up wifi

ia@freya2:~$ sudo apt-get install firmware-brcm80211 wpasupplicant
sudo reboot
sudo ifconfig

ia@freya2:~$ cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

ia@freya2:~$ cat /etc/wpa_supplicant/wpa_supplicant.conf
network={
	ssid="HotelPlumeria-2G"
	psk="allthethings"
}

Set up a VPN

curl -L https://install.pivpn.io | bash

# port forwarding
sudo upnpc -l
sudo upncp -e 'SSH on RPi' -r 22 TCP
sudo upnpc -l
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment