# Server configuration for imaging-neuroscience.org
**The imaging neuroscience server was shut down on 26th September 2024.**
Both https://imaging-neuroscience.org and https://janeway.imaging-neuroscience.org run on a single Amazon EC2 instance, provisioned through the FSL AWS account:
- Name: Imaging Neuroscience Janeway Web Server
- Type: t3.xlarge
- Zone: eu-west-2 (London)
- Elastic IP: 13.41.96.240
- OS: Ubuntu 22.04
- Username: `ubuntu`
The instance is SSH-accessible with a private key available to both Taylor and Paul.
The imaging-neuroscience.org and janeway.imaging-neuroscience.org domains and associated SSL certificates are managed by Steve through an ionos.co.uk account. Both domains point to 13.41.96.240
Until 1st August 2023, outgoing email was provided by a https://postmarkapp.com/ account. Paul and Steve are both admins on this account. On the 1st of August, we switched over to using an IONOS email account for outgoing email.
## Pre-requisites
- SSH private key for login
- `imaging-neuroscience.org` SSL certificate and key file
- `ubuntu` UNIX account password
- `janeway` UNIX account password
- `janeway` PostgreSQL account password
- PostgreSQL database dump from a testing server, to initialise the new database
- IONOS SMTP settings for outgoing emails
- Django `SECRET_KEY` (used for password salting/hashing)
## System installation and configuration
```bash
# Logged in as ubuntu
cd ~
```
### Paul's personal config files
```bash
wget https://raw.githubusercontent.com/pauldmccarthy/dotfiles/master/.tmux.conf
wget https://raw.githubusercontent.com/pauldmccarthy/dotfiles/master/.gitconfig
```
### System dependencies
```bash
# Janeway v1.4.4 uses a version of Django
# which requires python 3.8, but Ubuntu
# 22.04 uses python 3.10 by default.
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
# Apache, postgresql, python 3.8, compiler
# toolchain and some dev libs for compiling
# mod_wsgi and other janeway dependencies.
sudo apt install -y apache2 apache2-dev emacs postgresql libxml2-dev \
libxslt1-dev python3-dev zlib1g-dev lib32z1-dev libffi-dev \
libssl-dev libjpeg-dev libmysqlclient-dev python3.8 \
python3.8-dev python3.8-venv python3-pip \
build-essential libpq-dev
```
### Firewall
Restrict access to SSH, HTTP and HTTPS. Also ensure that inbound traffic is allowed on these ports (22, 80, 443) in the AWS security group rules.
```bash
sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
sudo ufw enable
```
Install SSL certificate/key - Steve gets these files from ionos.co.uk.
```bash
# enable SSL in apache
sudo a2enmod ssl
sudo systemctl restart apache2
sudo mv <keyfile> /etc/ssl/private/imaging-neuroscience.org.key
sudo mv <certfile> /etc/ssl/certs/imaging-neuroscience.org.cer
sudo chown root:ssl-cert /etc/ssl/private/imaging-neuroscience.org.key
sudo chown root:root /etc/ssl/certs/imaging-neuroscience.org.cer
sudo chmod 640 /etc/ssl/private/imaging-neuroscience.org.key
sudo chmod 644 /etc/ssl/certs/imaging-neuroscience.org.cer
```
### Make a swap file.
The instance has 16GB RAM, but a little swap is good, right?
```bash
sudo dd if=/dev/zero of=/swapfile bs=1024 count=4194304
sudo mkswap /swapfile
sudo chmod 600 /swapfile
sudo swapon /swapfile
sudo emacs /etc/fstab
-> /swapfile none swap sw 0 0
```
### PostgreSQL
We create a PostgreSQL account and database for use by the Janeway system.
```bash
# Create a db user for Janeway
# username: janeway
# permissions: createdb:y, everything else: n
# password: stored in Paul's password manager,
# and also in the janeway settings.py
sudo -u postgres createuser --interactive --pwprompt
# use md5 pw auth, so the db account is distinct
# from the UNIX user account ("peer" tells
# postgresql to use the UNIX account credentials)
# Add a line to this file:
#
# local all janeway md5
sudo emacs /etc/postgresql/14/main/pg_hba.conf
sudo systemctl restart postgresql
# Create a db called janeway, owned by user janeway
sudo -u postgres createdb --username=janeway janeway
```
### User account for Janeway
We use a separate account which does not have `sudo` privileges. Not really necessary, as the site will be executed by `www-data`, but it seems a bit nicer.
```bash
# Password stored in Paul's password manager
sudo useradd -m janeway
sudo chsh janeway -s /bin/bash
sudo passwd janeway
# give apache access to /var/www/*imaging-neuroscience.org/
sudo adduser www-data janeway
```
## Janeway installation
We are using a [fork of Janeway](https://github.com/pauldmccarthy/janeway/tree/mnt/imgneuro) which is based on [Janeway v1.4.4](https://github.com/BirkbeckCTP/janeway/tree/v1.4.4), with a few small tweaks and customisations.
```bash
sudo su janeway
cd ~
python3.8 -m venv janeway.env
. ./janeway.env/bin/activate
pip install --upgrade pip wheel
# https://github.com/pypa/setuptools/issues/3898
pip install "setuptools==57.*"
git clone https://github.com/pauldmccarthy/janeway/
cd janeway
git checkout mnt/imgneuro
# We install mod_wsgi via pip, because the
# Ubuntu mod_wsgi package is compiled against
# python 3.10, but we are using python 3.8.
pip install mod_wsgi
pip install -r requirements.txt
```
### Janeway configuration
Create `src/core/settings.py` and populate it as follows:
```python
# SECURITY WARNING: keep the secret key used in production secret!
#
# Generate your own django secret key by running:
#
# python3.8 -c 'import secrets; print(secrets.token_hex(100))'
SECRET_KEY = '<insert-key-kere>'
# This is the default redirect if no other sites are found.
DEFAULT_HOST = 'https://janeway.imaging-neuroscience.org'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
LOGIN_REDIRECT_URL = '/user/profile/'
# Default Langague
LANGUAGE_CODE = 'en'
URL_CONFIG = 'domain' # path or domain
EMAIL_HOST = 'smtp.postmarkapp.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = '<postmark-user-token>'
EMAIL_HOST_PASSWORD = '<postmark-user-token>'
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
EMAIL_HEADERS = {'X-PM-Message-Stream' : 'outbound'}
DATABASES = {
'default': {
'ENGINE' : 'django.db.backends.postgresql',
'NAME' : 'janeway',
'USER' : 'janeway',
'PASSWORD' : '<janeway-db-password>',
'HOST' : 'localhost',
'PORT' : '5432',
}
}
# CATCHA_TYPE should be either 'simple_math', 'recaptcha' or 'hcaptcha' to enable captcha
#fields, otherwise disabled
CAPTCHA_TYPE = 'simple_math'
# ORCID Settings
ENABLE_ORCID = False
ORCID_API_URL = 'http://pub.orcid.org/v1.2_rc7/'
ORCID_URL = 'https://orcid.org/oauth/authorize'
ORCID_TOKEN_URL = 'https://pub.orcid.org/oauth/token'
ORCID_CLIENT_SECRET = ''
ORCID_CLIENT_ID = ''
# OIDC Settings
ENABLE_OIDC = False
OIDC_SERVICE_NAME = 'OIDC Service Name'
OIDC_RP_CLIENT_ID = ''
OIDC_RP_CLIENT_SECRET = ''
OIDC_RP_SIGN_ALGO = 'RS256'
OIDC_OP_AUTHORIZATION_ENDPOINT = ""
OIDC_OP_TOKEN_ENDPOINT = ""
OIDC_OP_USER_ENDPOINT = ""
OIDC_OP_JWKS_ENDPOINT = ''
ENABLE_FULL_TEXT_SEARCH = False # Read the docs before enabling full text
# Model used for indexing full text files
CORE_FILETEXT_MODEL = "core.FileText" # Use "core.PGFileText" for Postgres
```
### Janeway initialisation and DB migration
Run ```python src/manage.py install_janeway```, and enter the following information (their values will actually be overwritten later, so they don't really matter here):
- press name: `MIT Press`
- press domain: `imaging-neuroscience.org`
- journal code: `imaging-neuroscience`
- journal domain: `janeway.imaging-neuroscience.org`
- journal name: `Imaging Neuroscience`
- journal desc: `an open-access non-profit journal of brain imaging`
Install the `material` theme:
```bash
cp -r src/static/material src/collected-static
```
On the test server, take copies of the following folders, and copy them into the same location on the new server:
- `src/media` - Custom journal images/logos/etc
- `src/files/articles/` - actual article files, if you want to import submitted articles from the test server
- `src/files/journals/` - More custom journal images
Populate the site and database with a DB dump from a test instance (this includes all of the customisations that Steve has made). On the test/source server, run `pg_dump --no-owner -U <dbuser> <dbname> >> <db_dump_file>`. Then on the produciton/destination server, run:
```bash
sudo -u postgres psql
# drop database janeway;
# create database janeway with owner janeway;
# grant create on database janeway to janeway;
# this can be run as the janeway user
psql < <db_dump_file>
```
Update the DB domain entries (as the test server was probably set up with different domains):
```bash
psql
# update journal_journal set domain='janeway.imaging-neuroscience.org' where id=1;
# update press_press set domain='imaging-neuroscience.org' where id=1;
```
Re-run django migrations to ensure that the restored DB schema is up to date:
```bash
sudo su janeway
cd ~/janeway/
. ~/janeway.env/bin/activate
python src/manage.py migrate
```
## Static landing page: https://imaging-neuroscience.org
This website just comprises a few static files, obtained from Steve. Edit `etc/apache2/sites-available/imaging-neuroscience.org.conf`, and insert the following:
```
<VirtualHost *:443>
ServerName imaging-neuroscience.org
ServerAlias www.imaging-neuroscience.org
DocumentRoot /var/www/imaging-neuroscience.org/
SSLEngine on
SSLCertificateFile /etc/ssl/certs/imaging-neuroscience.org.cer
SSLCertificateKeyFile /etc/ssl/private/imaging-neuroscience.org.key
</VirtualHost>
<VirtualHost *:80>
ServerName imaging-neuroscience.org
ServerAlias www.imaging-neuroscience.org
Redirect / https://imaging-neuroscience.org/
# DocumentRoot /var/www/imaging-neuroscience.org/
</VirtualHost>
```
Then install the website files, and turn the site on:
```bash
sudo mkdir /var/www/imaging-neuroscience.org/
sudo mv Announcement.pdf index.html ImgNeuro.png /var/www/imaging-neuroscience.org/
# check that the config is valid
sudo apache2ctl configtest
# turn on the landing page
sudo a2ensite imaging-neuroscience.org
sudo a2dissite 000-default
sudo systemctl reload apache2
```
## Janeway journal submission system: https://janeway.imaging-neuroscience.org
Edit `etc/apache2/sites-available/janeway.imaging-neuroscience.org.conf`, and insert the following. The `LodModule` line comes from running `mod_wsgi-express module-config`:
```
<VirtualHost *:443>
ServerName janeway.imaging-neuroscience.org
ServerAlias www.janeway.imaging-neuroscience.org
Alias /static/ /var/www/janeway.imaging-neuroscience.org/janeway/src/collected-static/
<Directory /var/www/janeway.imaging-neuroscience.org/janeway/src/collected-static>
Require all granted
</Directory>
Alias /media/ /var/www/janeway.imaging-neuroscience.org/janeway/src/media/
<Directory /var/www/janeway.imaging-neuroscience.org/janeway/src/media>
Require all granted
</Directory>
<Directory /var/www/janeway.imaging-neuroscience.org/janeway/src/core/>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
LoadModule wsgi_module "/var/www/janeway.imaging-neuroscience.org/janeway.env/lib/python3.8/site-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so"
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess janeway python-home=/var/www/janeway.imaging-neuroscience.org/janeway.env/ python-path=/var/www/janeway.imaging-neuroscience.org/janeway/src
WSGIProcessGroup janeway
WSGIScriptAlias / /var/www/janeway.imaging-neuroscience.org/janeway/src/core/wsgi.py
SSLEngine on
SSLCertificateFile /etc/ssl/certs/imaging-neuroscience.org.cer
SSLCertificateKeyFile /etc/ssl/private/imaging-neuroscience.org.key
</VirtualHost>
<VirtualHost *:80>
ServerName janeway.imaging-neuroscience.org
ServerAlias www.janeway.imaging-neuroscience.org
Redirect / https://janeway.imaging-neuroscience.org/
</VirtualHost>
```
Then set up the website and turn it on:
```bash
sudo mkdir /var/www/janeway.imaging-neuroscience.org
sudo chown janeway:janeway /var/www/janeway.imaging-neuroscience.org
sudo chmod -R 755 /var/www/janeway.imaging-neuroscience.org
ln -s ~/janeway /var/www/janeway.imaging-neuroscience.org/janeway
ln -s ~/janeway.env /var/www/janeway.imaging-neuroscience.org/janeway.env
sudo a2ensite janeway.imaging-neuroscience.org
sudo apache2ctl configtest
sudo systemctl reload apache2
```
## Backups
After the server has been configured as outlined above, we modify the live instance to allow backups of the Janeway database, and all files submitted through Janeway.
The Janeway files are moved to a separate EBS volume, and daily snapshots of the PostgreSQL database are also saved to that volume. The volume is called `imaging-neuroscience-janeway-data-store`, has ID `vol-0ba9f56a7b94cefae`, and is in availability zone `eu-west-2c`.
> This change was performed after the server went live due to time constraints. It would obviously make more sense to install Janeway onto a separate EBS volume from the outset.
### Move Janeway to a separate EBS volume
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-using-volumes.html
- https://www.microhost.com/docs/tutorial/how-to-move-a-postgresql-data-directory-to-a-new-location-on-ubuntu-22-04/
Create an EBS volume and attach it to the instance. Make sure that the volume is created in the same Availability Zone as the instance (e.g. `eu-west-2c`). Then mount the volume in the running instance:
```bash
# The volume device will be called /dev/xvdf or /dev/nvme1n1
# or something - find out by running sudo lsblk -f
sudo mkfs -t ext4 /dev/xvdf
sudo mkdir /data/
sudo chmod 777 /data/
sudo mount /dev/xvdf /data/
```
Add the volume to `/etc/fstab` so it is mounted at boot:
```
UUID=<find by running sudo blkid> /data ext4 defaults,nofail 0 2
```
Stop Apache:
```bash
sudo systemctl stop apache2
```
Move the Janeway directory to the new volume:
```bash
sudo su janeway
cd ~
mv janeway /data/
ln -s /data/janeway ./janeway
sudo chmod -R 775 /data/janeway
```
Restart Apache:
```bash
sudo systemctl stop apache2
```
> I had originally also planned to relocate the PostgreSQL database files to the EBS volume as well, but due to time constraints the system was made public before I was ready, and I was too afraid to do it on the running instance. But it would be done with something like the following:
>
> ```bash
> # double check config file / data directory
> sudo -u postgres psql
> # -> show config_file;
> # -> sheow data_directory;
> sudo systemctl stop apache2
> sudo systemctl stop postgresql
> sudo mkdir /data/pgdata
> sudo chown postgres:postgres /data/pgdata
> sudo chmod 700 /data/pgdata
> sudo rsync -av /var/lib/postgresql/14/main/ /data/pgdata
> sudo emacs /etc/postgresql/14/main/postgresql.conf
> # -> data_directory = '/data/pgdata'
> sudo systemctl start apache2
> sudo systemctl start postgresql
> ```
### Set up daily snapshots for PostgreSQL
We do this in case the database is somehow corrupted or compromised.
Create a snapshot script at `/data/pgdata_snapshot` containing the following:
```bash
#!/usr/bin/env bash
# This script is added to the postgres user crontab to run daily
snapshotdir=/data/pgdata_snapshots
datestamp=$(date +"%Y%m%d-%H%M%S")
filename=${snapshotdir}/${datestamp}.db
mkdir -p ${snapshotdir}
pg_dump -U postgres janeway | gzip > ${filename}
```
Make the script executable, and add it to the `postgres` user crontab - run:
```bash
sudo crontab -u postgres -e
```
and add `0 0 * * * /data/pgdata_snapshot`
### Set up a backup schedule on the EBS volume
We do this in case the server goes down and is unrecoverable.
An EBS snapshot lifecycle policy (`policy-091e2a3e4e1dcf879`) has been set up according to the instructions at: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snapshot-ami-policy.html
A snapshot of the Janeway EBS volume is saved every 24 hours. Snapshots more than 7 days old are deleted.
### Create an Amazon Machine Image (AMI)
We do this so that we can quickly re-provision a new server instance in case the server is compromised.
An AMI template (id `ami-06dd467c5ef1bcb37`, name `Imaging Neuroscience Janeway Server Template`) has been created according to the setup instructions above.
The Janeway data files and PostgreSQL backups are stored in the `imaging-neuroscience-janeway-data-store` EBS volume (ID `vol-0ba9f56a7b94cefae`).
### Provisioning a new server instance from a backup
1. Terminate the previous server instance.
2. Restore the Janeway EBS volume from a snapshot if necessary (if it has been somehow corrupted).
3. Create a new `t3.xlarge` EC2 instance from the AMI template.
- Make sure that the instance is created in the same availability zone as the EBS volume.
- Make sure that inbound SSH/HTTP/HTTPS traffic is allowed from anywhere.
- Make sure that login is allowed via the `Imaging Neuroscience Janeway Web Server key` key pair.
4. Associate elastic IP `13.41.96.240` with the instance
5. Attach the Janeway EBS volume to the instance.
6. Log in to the instance and mount the EBS volume at `/data/`
7. Restore the PostgreSQL database from a snapshot in `/data/pgdata_snapshots/`:
```bash
sudo systemctl stop apache2
sudo -u postgres psql
# -> drop database janeway;
# -> create database janeway with owner janeway;
# -> grant create on database janeway to janeway;
psql --username=janeway < <snapshot-file>
sudo systemctl start apache2
```
## Janeway updates
It may occasionally be necessary to update the Janeway installation if e.g. some changes need to be made to the code or database. The procedure for doing this is outlined below. It goes without saying that this should be performed on a test system before being attempted on the live system.
1. Update the janeway source code on the `mnt/imgneuro` branch at https://github.com/pauldmccarthy/janeway/.
2. Log into the web server
3. Shut down apache2 (as `ubuntu` user):
```
sudo systemctl stop apache2
```
4. Update the janeway installation (as `janeway` user):
```
sudo su janeway
cd /data/janeway/
git fetch --all
git merge origin/mnt/imgneuro
```
5. Apply Janeway database migrations if necessary (still as `janeway` user, in `/data/janeway/`):
```
source activate ~/janeway.env
python src/manage.py migrate
```
6. Restart apache2 (as `ubuntu` user):
```
sudo systemctl start apache2
```