Hello everyone. I deployed IPFS daemons on the several low-end machines, including OrangePI (4x ARM cores CPU, 1GB RAM) and Debian-equipped server (Pentium IV 1.8 GHz single-core CPU, 2 GB RAM), running as systemd services. These machines require strong limits on CPU resources, memory consumption, kernel requests. To enforce the limitations I use systemd for running IPFS daemon. The daemon itself is wrapped with the following script:
#!/usr/bin/env bash
export IPFS_PATH="/util/ipfs"
PID_FILE="${IPFS_PATH}/daemon.pid"
export GOMAXPROCS=1
export IPFS_LOGGING="info"
if [[ "$1" == "stop" && -f "${PID_FILE}" ]]
then
/bin/kill -s SIGINT `cat "${PID_FILE}"`
sleep 5
if grep -qs "${IPFS_PATH}/mount/ipfs" /proc/mounts
then
umount "${IPFS_PATH}/mount/ipfs"
fi
if grep -qs "${IPFS_PATH}/mount/ipns" /proc/mounts
then
umount "${IPFS_PATH}/mount/ipns"
fi
exit 0
fi
/util/bin/ipfs daemon --mount --enable-gc &
echo -e "$!" > ${PID_FILE}
systemd unit file for the daemon limits resource consumption with accounting directives:
[Unit]
Description=IPFS single node control service - P2P distributed content-based CDN with file frontend
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/util/ipfs/ipfs-service.daemon
ExecStop=/util/ipfs/ipfs-service.daemon stop
PIDFile=/util/ipfs/daemon.pid
TimeoutSec=60
User=ipfs
Group=ipfs
MemoryAccounting=true
MemoryHigh=134217728
MemoryMax=402653184
Restart=on-failure
RestartSec=10s
CPUAccounting=true
CPUQuota=30%
[Install]
WantedBy=multi-user.target
The daemons operate slow, but this kind of setup allows to prevent memory leaks and CPU hangups. The limitation for the number of processes is available through systemd but it can produce strange crashes of the daemon because of process management algorithm in Golang standard library.
I will be appreciated with any comments or reviews.
Note ipfs provides [quite advanced] systemd service files:
It’s important that the service is of type notify as this correctly lets systemd know that IPFS is up at the moment where it is actually up.
Thus, it would be best if your service file was based on the upstream.
Additionally, you can include env vars directly in the service file. You can also configure specific pre and post scripts to be called from it, rather than wrapping the binary on a script itself.
Thanks for this review, @hector! I experienced some problems with the upstream service files (especially, deploying on OrangePI), that’s why I decided to write my own. For example, pre and post scripts weren’t running correctly, After section for my case with Pentium IV machine was unsuccessful.
I will try to customize the upstream files to avoid the problems. If I will be lucky, I will write a report here.
The script now handles the issue when the daemon does not unmount the FUSE mount points when exiting with SIGTERM:
export IPFS_PATH="/media/storage/system/ipfs"
if grep -qs "${IPFS_PATH}/mount/ipfs" /proc/mounts
then
umount "${IPFS_PATH}/mount/ipfs"
fi
if grep -qs "${IPFS_PATH}/mount/ipns" /proc/mounts
then
umount "${IPFS_PATH}/mount/ipns"
fi
exit 0
The daemons are now working in test mode, I will wait for several days to obtain useful stats.