«home
These instructions are now out of date. See this readme for the most recent instructions.
Ibex is a tool for running psycholinguistic experiments online. It was designed to be easy to run on the shared hosting solutions cheaply available in 2007. This was achieved by implementing the backend as a single Python CGI script.
The Ibex Farm, introduced around 2010, lowered the barrier to entry by providing a web interface for creating Ibex experiments. The Ibex Farm is written in Perl using the Catalyst framework.
Hosting an Ibex Farm instance used to be much more complicated than hosting a single Ibex experiment. I've now built a Docker image to make it easier. If you're already hosting Ibex experiments yourself, you might want to consider hosting your own Ibex Farm instance instead.
This guide assumes that you'll run your Ibex Farm instance on a linode running CentOS 7. As Docker does most of the heavy lifting, the instructions below should be easy to adapt to other environments. That being said, you can run a suitable linode for just $5/month, so I'd go with a linode unless you have a good reason not to.
I have increasingly less time to dedicate to maintaining the Ibex Farm. I don't have any plans to shut it down in the near future, but it would be useful if others could step in and provide alternative hosting options.
The configuration described below makes it easy to run the Ibex Farm over https. I haven't yet got round to upgrading the Ibex Farm to use https.
If the server goes down, you can fix it. I can't always respond quickly if the Ibex Farm server goes down.
This is a question I've had more often than I've expected. The Ibex Farm is open source software. You don't need my permission to run your own instance of it. I request that
you do not list my email address as a point of contact on your own instance;
you do not contact me directly for technical support setting up your own instance.
You should, however, feel free to post questions to the Google group.
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, go through the following steps:
Go to the ‘linodes’ tab and click ‘Add a Linode’ on the bottom right of the page.
Select the ‘Nanode’ option (or something beefier if money is no object).
Click the ‘Add this Linode!’ button. You'll be taken back to the ‘linodes’ tab.
Click on the link for your new linode.
Click ‘Deploy an image’.
Select ‘CentOS 7’ from the dropdown menu.
Choose a root password and click ‘Deploy’.
Once the jobs in the job queue have finished running, click the ‘Boot’ button.
Go back to the ‘linodes’ tab to find the IP address of your linode.
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.192
Ssh in as root (as in the example above). Execute the following commands:
adduser ibex
passwd ibex
usermod -aG wheel ibex
yum update -y
yum install -y firewalld
systemctl enable firewalld
shutdown -r now
The 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 the following packages:
sudo yum install -y git docker
sudo yum install -y epel-release
sudo yum install -y tinyproxy jq
Note that the use of a separate invocation of yum
to install epel-release
is necessary. We can now start the firewall, start the docker daemon, and
configure tinyproxy:
sudo systemctl start docker
sudo systemctl enable docker.service
sudo sed -i 's/^Port[ \t]*[0-9][0-9]*$/Port 80/' /etc/tinyproxy/tinyproxy.conf
sudo sed -i 's/^Allow[ \t].*$//g' /etc/tinyproxy/tinyproxy.conf
sudo bash -c 'printf "\nReverseOnly Yes\nReverseMagic Yes\nReversePath \"/\" \"http://localhost:8888/\"\n" >> /etc/tinyproxy/tinyproxy.conf'
The Ibex Farm's data will be stored in a separate container. The data is
manipulated by the apache
user, since the Ibex Farm runs inside apache using
mod_perl. The apache
user and apache
group both have id 987654
within the
container. We can create a dapache
(‘docker apache’) user and group in the
host CentOS system with the same id:
sudo groupadd dapache -g 987654
sudo useradd -g dapache -u 987654 -s /sbin/nologin dapache
Create a volume called ibexdata
to hold the Ibex Farm data:
sudo docker volume create ibexdata
Create /deploy
and /ibexexps
directories within the volume and
chown everything to dapache:dapache
:
sudo mkdir `sudo docker volume inspect ibexdata | jq -r .[0].Mountpoint`/ibexexps
sudo mkdir `sudo docker volume inspect ibexdata | jq -r .[0].Mountpoint`/deploy
sudo chown -R dapache:dapache `sudo docker volume inspect ibexdata | jq -r .[0].Mountpoint`
The next steps are to open port 80 and start tinyproxy:
sudo firewall-cmd --zone=public --permanent --add-service=http
sudo firewall-cmd --reload
sudo systemctl restart docker
sudo service tinyproxy start
Pull the Ibex Farm Docker container:
sudo docker pull alexdrummond/ibexfarm
Configure the webmaster email address and webmaster name for this instance:
echo 'IBEXFARM_webmaster_email="example@example.com"' >> ~/ibexenv.sh
echo 'IBEXFARM_webmaster_name="Some person"' >> ~/ibexenv.sh
Source the preceding definitions and add them to the system profile:
set -o allexport ; source ~/ibexenv.sh ; set +o allexport
sudo bash -c 'echo "set -o allexport ; source /home/ibex/ibexenv.sh ; set +o allexport" > /etc/profile.d/ibex.sh'
Allow systemd to manage Docker containers:
sudo setsebool -P container_manage_cgroup on
Create 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=/home/ibex/ibexenv.sh\nUser=root\nRestart=always\nRestartSec=10\nExecStartPre=-/usr/bin/bash /usr/bin/docker stop ibexfarm_server\nExecStartPre=-/usr/bin/docker rm ibexfarm_server\nExecStartPre=/usr/bin/bash -c 'cat /home/ibex/ibexenv.sh | xargs -n 1 echo > /tmp/ibexenv_docker'\nExecStart=/usr/bin/docker run --name ibexfarm_server --restart no -p 127.0.0.1:8888:80 -e IBEXFARM_url_prefix=/ -e IBEXFARM_port=80 -e IBEXFARM_config_url_envvar=IBEXFARM_config_url -e IBEXFARM_config_url=http://localhost/ajax/config --env-file /tmp/ibexenv_docker -v ibexdata:/ibexdata docker.io/alexdrummond/ibexfarm\nExecStop=/usr/bin/docker stop -t 2 ibexfarm_server\n[Install]\nWantedBy=multi-user.target\n" | sudo bash -c 'tee > /etc/systemd/system/ibexfarm-server.service'
sudo systemctl daemon-reload
Finally, start Ibex Farm using the following commands:
sudo systemctl start ibexfarm-server.service
sudo systemctl enable ibexfarm-server.service
At this point, you should be able to see the Ibex Farm homepage. For example,
if the IP address of your linode is 192.192.192.192
, go to:
http://192.192.192.192/
You may wish to create an example
user with an example
experiment, so that
the link on the homepage isn't broken.
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. Be sure to add /ibexexps
and /deploy
dirs to your volume before
running the docker container, and then chown -R
everything to
dapache:dapache
.
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. You can either create and manage this certificate automatically via Caddy, or create the certificate manually — in which case you'll be responsible for renewing it when it expires. There's little reason to choose the manual option if you're using letsencrypt, but you might find the relevant instructions useful if you have another SSL certificate that you'd like to use.
Begin by halting tinyproxy and disabling its service:
sudo service tinyproxy stop
sudo systemctl disable tinyproxy
Open port 443, restart Docker, and ensure that the ibexfarm container is still up:
sudo firewall-cmd --zone=public --permanent --add-service=https
sudo firewall-cmd --reload
sudo systemctl restart docker
sudo systemctl start ibexfarm-server.service
Define your hostname:
echo 'IBEXFARM_host="my.domain.name"' >> ~/ibexenv.sh
set -o allexport ; source ~/ibexenv.sh ; set +o allexport
Install caddy:
cd ~
curl -o caddy.tar.gz https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
sudo mkdir /caddy
sudo useradd -r -d /caddy -M -s /sbin/nologin caddy
sudo chown caddy:caddy /caddy
sudo tar -xzf caddy.tar.gz -C /caddy
sudo chown -R caddy:caddy /caddy
rm ~/caddy.tar.gz
sudo -u caddy mkdir /caddy/ssl
sudo setcap CAP_NET_BIND_SERVICE=+eip /caddy/caddy
Create 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=/home/ibex/ibexenv.sh\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-reload
You can now choose either ‘Option 1’ or ‘Option 2’ below, then follow the instructions in the ‘Start Caddy’ section.
Make sure that you've set IBEXFARM_webmaster_email
to a real
email address in ~/ibexenv.sh
. This email address will be associated
with your SSL cert.
Configure Caddy as follows:
sudo -u caddy bash -c 'printf "{\$IBEXFARM_host} {\n log syslog\n proxy / http://127.0.0.1:8888\n tls {\$IBEXFARM_webmaster_email}\n}\n" > /caddy/caddy.conf'
Obtain a letsencrypt certificate:
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
cd /opt/letsencrypt
sudo -H ./letsencrypt-auto certonly --standalone -d "$IBEXFARM_host"
After answering some questions at the prompt, you should see output like the following:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/my.domain.name/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/my.domain.name/privkey.pem
...
...
Configure Caddy as follows:
sudo -u caddy bash -c 'printf "http://{\$IBEXFARM_host} {\n log syslog\n redir https://{\$IBEXFARM_host}{uri}\n}\n\nhttps://{\$IBEXFARM_host} {\n log syslog\n proxy / http://127.0.0.1:8888\n tls /caddy/ssl/fullchain.pem /caddy/ssl/privkey.pem\n}\n" > /caddy/caddy.conf'
Copy the cert files to the location where Caddy expects them:
sudo find "/etc/letsencrypt/live/$IBEXFARM_host" -name '*.pem' -exec cp {} /caddy/ssl \;
sudo chown -R caddy:caddy /caddy/ssl
sudo chmod 600 /caddy/ssl/*.pem
Finally, start and enable the Caddy systemd service:
sudo systemctl start caddy.service
sudo systemctl enable caddy.service
You should now have access to your Ibex Farm instance over https. Caddy has been configured to redirect any http requests to https.
To update to the latest Docker image, run the following commands:
sudo systemctl stop ibexfarm-server
sudo docker rmi -f docker.io/alexdrummond/ibexfarm
sudo docker pull alexdrummond/ibexfarm
sudo systemctl start ibexfarm-server