These instructions guide you through setting up an Ibex Farm instance on a Linode running CentOS 8. Unlike the earlier version of these instructions at https://adrummond.net/posts/ibexfarmdocker, these instructions assume that you have a domain and want to use Caddy's automatic SSL cert management via Letsencrypt.
For simplicity, these instructions assume that you will be logging in using a username and password. It is advisible to disable the option to log in via a username and password over ssh (and use keys instead).
Linode is one of many cloud hosting providers. It's cheap and easy to use compared to more sophisticated options like AWS.
If you anticipate hosting large number of experiments (more than a few hundred), then check out the ‘Storage Space’ section below.
After creating a linode account, create a linode running CoreOS Container Linux. Note that the Apache and Docker configuration is quite tricky, so don't expect these exact instructions to work on other distros without significant modification.
If the IP address of your linode is e.g. 192.192.192.192, you can ssh in as
follows:
ssh root@192.192.192.192Ssh in as root (as in the example above). Execute the following commands:
adduser ibex
passwd ibex
usermod -aG wheel ibex
dnf update -y
dnf install -y firewalld git wget
systemctl enable firewalld
rm -f /etc/firewalld/zones/public.xml
firewall-cmd --complete-reload
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=https --permanent
firewall-cmd --zone=public --add-service=ssh --permanent # may show 'already enabled' warning
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --reload
ulimit -n 8192 # for caddy
shutdown -r nowThe linode will now reboot, terminating your ssh session. In a couple of
minutes, ssh in again as user ibex (e.g. ssh ibex@192.192.192.192). Install
docker and docker-compose:
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y --nobest docker-ce
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo usermod -aG docker ibexWe can now start the docker daemon:
sudo systemctl enable docker
sudo systemctl start dockerAllow the ibex user to do Docker stuff by adding it to the docker group:
sudo usermod -aG docker ibex
logout # you have to log out and log in again for the new group perms to take effectSsh in again as ibex. Create directory called ibexdata to hold the Ibex Farm data:
mkdir ~/ibexdataBuild the Ibex Farm Docker container:
cd ~
git clone https://github.com/addrummond/ibexfarm
cd ibexfarm/docker
docker build .Configure the webmaster email address and webmaster name for this instance, together with some other configuration options:
sudo touch /etc/ibexenv.sh
sudo chown ibex:ibex /etc/ibexenv.sh
echo 'IBEXFARM_webmaster_email="example@example.com"' >> /etc/ibexenv.sh
echo 'IBEXFARM_webmaster_name="Some person"' >> /etc/ibexenv.sh
echo 'IBEXFARM_url_prefix="/"' >> /etc/ibexenv.sh
echo 'IBEXFARM_experiment_base_url="/ibexexps"' >> /etc/ibexenv.shYou may want to add the following definition
to ibexenv.sh to make the Ibex Farm use the Perl code in ~/ibexfarm/docker
rather than the code inside the Docker container:
echo 'IBEXFARM_src_dir=/code' >> /etc/ibexenv.shSource the preceding definitions and add them to the system profile:
set -o allexport ; source /etc/ibexenv.sh ; set +o allexport
sudo bash -c 'echo "set -o allexport ; source /etc/ibexenv.sh ; set +o allexport" > /etc/profile.d/ibex.sh'Allow systemd to manage Docker containers:
sudo setsebool -P container_manage_cgroup onCreate a systemd service called ibexfarm-server to run the docker container:
printf "[Unit]\nDescription=Ibex Farm server\nWants=docker.service\nAfter=docker.service\n[Service]\nLimitNOFILE=8192\nEnvironmentFile=/etc/ibexenv.sh\nUser=ibex\nRestart=always\nRestartSec=10\nExecStartPre=/usr/bin/bash -c 'cat /etc/ibexenv.sh | xargs -n 1 echo > /tmp/ibexenv_docker'\nExecStart=/usr/local/bin/docker-compose -f /home/ibex/ibexfarm/docker/docker-compose.yml up\nExecStop=/usr/local/bin/docker-compose -f /home/ibex/ibexfarm/docker/docker-compose.yml down\n[Install]\nWantedBy=multi-user.target\n" | sudo bash -c 'tee > /etc/systemd/system/ibexfarm-server.service'
sudo systemctl daemon-reloadFinally, start Ibex Farm using the following commands:
sudo systemctl start ibexfarm-server.service
sudo systemctl enable ibexfarm-server.serviceAt this point, if the server is up and running, you should be able to retrieve
index.html by running wget http://localhost:8888.
If you anticipate hosting lots of experiments on your Ibex Farm instance, you
should store the ibexdata volume on a linode volume rather than on the root
filesystem of the linode. Whereas there's no straightforward way to enlarge a
linode's root filesystem, it's easy to enlarge a linode volume. See the docker
documentation
(and in particular the --opt device option to docker volume create) for more
info.
You'll need to get a domain name pointing to the IP of your linode before following these instructions.
Remember that DNS propagation can take a while, so wait for a few hours after you've associated your domain name with your linode's IP address.
This section steps through the process of setting up https using a free letsencrypt certificate.
First, define your hostname:
echo 'IBEXFARM_host="my.domain.name"' >> /etc/ibexenv.sh
set -o allexport ; source /etc/ibexenv.sh ; set +o allexportInstall Caddy:
cd ~
wget https://github.com/caddyserver/caddy/releases/download/v1.0.3/caddy_v1.0.3_linux_amd64.tar.gz
sudo mkdir /caddy
sudo useradd -r -d /caddy -M -s /sbin/nologin caddy
sudo chown caddy:caddy /caddy
sudo tar -xzf caddy_v1.0.3_linux_amd64.tar.gz -C /caddy
sudo chown -R caddy:caddy /caddy
rm ~/caddy_v1.0.3_linux_amd64.tar.gz
sudo -u caddy mkdir /caddy/ssl
sudo setcap CAP_NET_BIND_SERVICE=+eip /caddy/caddyCreate a systemd service for Caddy:
printf "[Unit]\nDescription=Caddy HTTP/2 web server\nDocumentation=https://caddyserver.com/docs\nAfter=network-online.target\nWants=network-online.target systemd-networkd-wait-online.service\n[Service]\nRestart=on-abnormal\nUser=caddy\nGroup=caddy\nEnvironment=CADDYPATH=/caddy/ssl\nEnvironmentFile=/etc/ibexenv.sh\nExecStartPre=/bin/bash -c 'env > /caddy/env_on_startup'\nExecStart=/caddy/caddy -log stdout -agree=true -conf=/caddy/caddy.conf\nExecReload=/bin/kill -USR1 \$MAINPID\nKillMode=mixed\nKillSignal=SIGQUIT\nTimeoutStopSec=5s\nLimitNOFILE=1048576\nLimitNPROC=512\nPrivateTmp=true\nPrivateDevices=true\nReadWriteDirectories=/caddy/ssl\nCapabilityBoundingSet=CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_BIND_SERVICE\nNoNewPrivileges=true\n[Install]\nWantedBy=multi-user.target\n" | sudo bash -c 'tee > /etc/systemd/system/caddy.service'
sudo systemctl daemon-reloadSet up Caddy with automatic SSL cert management:
sudo -u caddy bash -c 'printf "{\$IBEXFARM_host} {\n log syslog\n proxy {\$IBEXFARM_url_prefix} http://127.0.0.1:8888 { without {\$IBEXFARM_url_prefix} }\n proxy {\$IBEXFARM_experiment_base_url} http://127.0.0.1:8888\n tls {\$IBEXFARM_webmaster_email}\n}\n" > /caddy/caddy.conf'Make sure that you've set IBEXFARM_webmaster_email to a real
email address in /etc/ibexenv.sh. This email address will be associated
with your SSL cert.
Finally, start and enable the Caddy systemd service:
sudo setenforce 0
sudo systemctl start caddy.service
sudo systemctl enable caddy.serviceUnfortunately, it appears to be necessary to disable SELinux for Caddy to start. I haven't yet been able to find a resolution for this issue. You could try looking here, which seems to have been updated since last I looked.
You should now have access to your Ibex Farm instance over https. Caddy has been configured to redirect any http requests to https.
You may wish to create an example user with an example experiment, so that
the link on the homepage isn't broken.
It can be useful to create a dapache user and group with the ids of the
apache user and group inside the Docker container:
sudo groupadd dapache -g 987654
sudo useradd -g dapache -u 987654 -s /sbin/nologin dapacheYou can then e.g. chown a file to dapache:dapache to have it owned by the
Docker apache user.
If you have a large set of existing experiments, you may find that the
ibexfarm-server process takes a long time to start up. (It takes about 10
minutes on spellout.net.) This is due to a recursive chown executed in the
entrypoint. After the server has been started for the first time, it is no
longer necessary to run this command. You can set
IBEXFARM_dont_chown_data_volume=1 to prevent the chown from executing and
reduce startup times.
To reset the password for a user, use the reset_password.sh script:
~/ibexfarm/script/reset_password.sh username # generates new random password for user (and prints it to console)
~/ibexfarm/script/reset_password.sh username newpassword # resets the password for the user to the one specified