Apache Installation
11 minute read
These instructions are for an apache-based installation. For nginx, use Nginx Installation.
Server requirements
- The supported PHP version >= 8.2 (8.3 recommended)
- Web server: apache for this guide. For nginx, use Nginx Installation.
- It requires a SQL database, MySQL and MariaDB have been tested, but may also work with Postgres. Tested with MySQL 8.0 and MariaDB 10.6+.
- PHP extensions required:
openssl,pdo,pdo_mysql,mbstring,tokenizer,xml,dom,gd,exif,bcmath,zip,curl,redis. - Redis Server is required for queues and cache.
- Tectonic is used for LaTeX/PDF label generation.
- Pandoc is used to translate LaTeX code used in bibliographic references. It is not necessary for installation, but suggested for a better user experience.
- Requires Supervisor, which is needed background jobs
- Node.js 22 with npm is required to build the frontend during installation and upgrades.
Create Dedicated User
The recommended way to install OpenDataBio for production is using a dedicated system user. In this instructions this user is odbserver.
Download OpenDataBio
Login as your Dedicated User and download or clone this software to where you want to install it.
Here we assume this is /home/odbserver/opendatabio so that the installation files will reside in this directory. If this is not your path, change below whenever it applies.
Download OpenDataBio
Prep the Server
First, install the prerequisite software: Apache, MySQL, PHP, Redis, Tectonic, Pandoc and Supervisor. On a Debian system, you need to install some PHP extensions as well and enable them:
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/apache2
sudo apt-get install mysql-server redis-server tectonic php8.3 libapache2-mod-php8.3 php8.3-intl \
php8.3-mysql php8.3-sqlite3 php8.3-gd php8.3-cli pandoc \
php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-zip php8.3-curl php8.3-redis \
supervisor
sudo a2enmod php8.3
sudo phpenmod mbstring
sudo phpenmod xml
sudo phpenmod dom
sudo phpenmod gd
sudo a2enmod rewrite
sudo a2enmod alias
sudo a2enmod headers
sudo systemctl restart apache2.service
#To check if they are installed:
php -m | grep -E 'mbstring|cli|xml|gd|mysql|redis|bcmath|pcntl|zip'
tectonic --version
redis-server --version
Add a dedicated virtual host to your Apache configuration.
- Change
/home/odbserver/opendatabioto your path (the files must be accessible by apache) - Create
/etc/apache2/sites-available/opendatabio.confwith the following content. - This example installs the application under
/opendatabio. Replacelocalhostwith the real host name in a public deployment.
<VirtualHost *:80>
ServerName localhost
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
RedirectMatch 302 ^/$ /opendatabio/
RedirectMatch 301 ^/opendatabio$ /opendatabio/
Alias /opendatabio/ "/home/odbserver/opendatabio/public/"
<Directory "/home/odbserver/opendatabio/public">
Options FollowSymLinks
AllowOverride All
Require all granted
DirectoryIndex index.php
</Directory>
ErrorLog ${APACHE_LOG_DIR}/opendatabio-error.log
CustomLog ${APACHE_LOG_DIR}/opendatabio-access.log combined
</VirtualHost>
The main alias serves all public assets, including build, images, fonts, and Livewire assets. Separate aliases for those directories are not required.
echo 'ServerName localhost' | sudo tee /etc/apache2/conf-available/servername.conf
sudo a2enconf servername
sudo a2enmod alias rewrite headers php8.3
sudo a2dissite 000-default
sudo a2ensite opendatabio
sudo apache2ctl configtest
sudo systemctl reload apache2
Do not reload Apache unless apache2ctl configtest reports Syntax OK.
Content Security Policy (CSP) for Apache
Configure CSP at the web server layer (not in Laravel files). Apply it first in report-only mode, inspect logs, then switch to enforced mode.
For nginx standalone installs, use Nginx Installation.
Apache: where to put it
- Enable required module:
sudo a2enmod headers
sudo systemctl restart apache2
- Edit your active vhost file (example):
sudo nano /etc/apache2/sites-available/opendatabio.conf
- Inside the correct
<VirtualHost ...>block (HTTP and/or HTTPS), add the header as a single directive:
Header always set Content-Security-Policy-Report-Only "default-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https://server.arcgisonline.com https://*.tile.openstreetmap.org; font-src 'self' data:; connect-src 'self'; media-src 'self' blob:; worker-src 'self' blob:;"
- Reload Apache:
sudo apachectl configtest
sudo systemctl reload apache2
Subpath installs (/opendatabio)
If your installation runs under a subpath (for example http://localhost/opendatabio), set in .env:
APP_URL=http://localhost/opendatabio
ASSET_URL=http://localhost/opendatabio
Then rebuild all generated assets:
sh scripts/build-assets.sh
php artisan optimize:clear
Notes
https://server.arcgisonline.comandhttps://*.tile.openstreetmap.orgare needed for map tiles.unsafe-inline/unsafe-evalare temporary compatibility flags; remove after hardening templates/assets.- Keep
Report-Onlywhile tuning policy in production.
Configure your php.ini files. With libapache2-mod-php8.3, the relevant files are /etc/php/8.3/cli/php.ini and /etc/php/8.3/apache2/php.ini. An FPM installation uses /etc/php/8.3/fpm/php.ini instead.
Update the values for the following variables:
Find files:
php -i | grep 'Configuration File'
Change in them:
memory_limit should be at least 512M
post_max_size should be at least 30M
upload_max_filesize should be at least 30M
Something like:
[PHP]
allow_url_fopen=1
memory_limit = 512M
post_max_size = 100M
upload_max_filesize = 100M
Mysql Charset and Collation
- You should add the following to your configuration file (mariadb.cnf or my.cnf), i.e. the Charset and Collation you choose for your installation must match that in the ‘config/database.php’
[mysqld]
character-set-client-handshake = FALSE #without this, there is no effect of the init_connect
collation-server = utf8mb4_unicode_ci
init-connect = "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
character-set-server = utf8mb4
log-bin-trust-function-creators = 1
sort_buffer_size = 256M #large enough for geometry sort operations; do not use multi-gigabyte global values
max_allowed_packet=100M
# MariaDB only:
[mariadb]
innodb_log_file_size=300M
- If using MariaDB and you still have problems of type #1267 Illegal mix of collations, then check here on how to fix that,
Configure supervisord
Configure Supervisor, which is required for jobs. Create a file name opendatabio-worker.conf in the Supervisor configuration folder /etc/supervisor/conf.d/opendatabio-worker.conf with the following content:
touch /etc/supervisor/conf.d/opendatabio-worker.conf
echo ";--------------
[program:opendatabio-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/odbserver/opendatabio/artisan queue:work --sleep=3 --tries=1 --timeout=0 --memory=512
autostart=true
autorestart=true
user=odbserver
numprocs=8
redirect_stderr=true
stdout_logfile=/home/odbserver/opendatabio/storage/logs/supervisor.log
;--------------" > /etc/supervisor/conf.d/opendatabio-worker.conf
Folder permissions
Security
Folder and file permissions are important for securing a public server installation. If you don’t set them correctly, your site may be at risk.- Folders
storageandbootstrap/cachemust be writable by the Server user (usuallywww-data). Use group write permission (0775) rather than making them world-writable. - Config
.envfile requires0640permission. - This link has different ways to set up permissions for files and folders of a Laravel application. Below the preferred method:
cd /home/odbserver
#give write permissions to odbserver user and the apache user
sudo chown -R odbserver:www-data opendatabio
sudo find ./opendatabio -type f -exec chmod 644 {} \;
sudo find ./opendatabio -type d -exec chmod 755 {} \;
#in these folders the server stores data and files.
#Make sure their permission is correct
cd /home/odbserver/opendatabio
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
sudo find storage bootstrap/cache -type d -exec chmod g+s {} \;
#make sure media folder has the correct permissions
sudo find ./storage/app/public/media -type f -exec chmod 664 {} \;
sudo find ./storage/app/public/media -type d -exec chmod 775 {} \;
#make sure the .env file has 640 permission
sudo chmod 640 ./.env
#verify that Apache can write to Laravel's writable directories
sudo -u www-data test -w storage
sudo -u www-data test -w bootstrap/cache
Install OpenDataBio
- Many Linux distributions (most notably Ubuntu and Debian) have different php.ini files for the command line interface and the Apache plugin. It is recommended to use the configuration file for Apache when running the install script, so it will be able to correctly point out missing extensions or configurations. To do so, find the correct path to the .ini file, and export it before using the
php installcommand.
For example,
export PHPRC=/etc/php/8.3/apache2/php.ini
The installation script will download the Composer dependency manager and all required PHP libraries listed in the
composer.jsonfile. However, if your server is behind a proxy, you should install and configure Composer independently. We have implemented PROXY configuration, but we are not using it anymore and have not tested properly (if you require adjustments, place an issue on GitLab).The script will prompt you configurations options, which are stored in the environment
.envfile in the application root folder.
You may, optionally, configure this file before running the installer:
- Create a
.envfile with the contents of the providedcp .env.example .env - Read the comments in this file and adjust accordingly.
- Make sure
ASSET_URLis correct for your deployment URL/subpath.
- Run the installer. Select the Apache profile explicitly:
cd /home/odbserver/opendatabio
php install apache
The installer builds the Vite frontend and publishes the Livewire assets
after .env is configured. These generated files are intentionally not
versioned. Node.js 22 and npm must therefore be installed on the server.
- Seed data - the script above will ask if you want to install seed data for Locations and Taxons - seed data is version specific. Check the seed data repository version notes.
Ready to go
If the install script finishes with success, you’re good to go! Point your browser to http://localhost/opendatabio. The database migrations include an administrator account, with loginadmin@example.org and password password1. Change the password after installing.Validate the completed installation:
php artisan migrate:status
php artisan locales:audit
composer check-platform-reqs
sudo supervisorctl status
redis-cli ping
curl -I http://localhost/opendatabio/
curl -I http://localhost/opendatabio/build/manifest.json
Optional assisted translation
User-maintained names and descriptions must contain their essential fields in the primary locale. Other enabled content locales are optional, and any enabled locale containing text may be used as the source of an assisted translation. A translation is always presented for review and is never saved automatically.
Assisted translation is disabled by default. Google Cloud Translation v3 is the only currently supported provider:
USER_TRANSLATION_PROVIDER=google
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_TRANSLATION_LOCATION=global
GOOGLE_APPLICATION_CREDENTIALS=/secure/path/service-account.json
Enable the Cloud Translation API and billing, grant the service account only
the required translation permission, keep its JSON file outside the
repository, and configure billing quotas/alerts. Google currently applies a
monthly free usage credit to the first 500,000 NMT characters; billing is still
required and usage beyond the credit is charged. Check current Google pricing
before enabling the feature. When the server provides Application Default
Credentials, GOOGLE_APPLICATION_CREDENTIALS may remain empty.
After editing .env, verify without sending text, then make one live request:
php artisan optimize:clear
php artisan translations:check --source=en --target=es
php artisan translations:check --source=en --target=es --live
The live command sends the short phrase shown by the command to the selected
provider. Provider failure does not prevent OpenDataBio from operating; leave
USER_TRANSLATION_PROVIDER empty to disable the feature.
Installation issues
There are countless possible ways to install the application, but they may involve more steps and configurations.
- if you browser return 500|SERVER ERROR you should look to the last error in
storage/logs/laravel.log. If you have ERROR: No application encryption key has been specified run:
php artisan key:generate
php artisan config:cache
- If you receive the error “failed to open stream: Connection timed out” while running the installer, this indicates a misconfiguration of your IPv6 routing. The easiest fix is to disable IPv6 routing on the server.
- If you receive errors during the random seeding of the database, you may attempt to remove the database entirely and rebuild it. Of course, do not run this on a production installation.
php artisan migrate:fresh
- You may also replace the Locations and Taxons tables with seed data after a fresh migration using:
php seedodb
Post-install configs
- If your import/export jobs are not being processed, make sure Supervisor is running with
sudo systemctl enable --now supervisor, and checkstorage/logs/supervisor.log. - You can change several configuration variables for the application. The most important of those are probably set
by the installer, and include database configuration and proxy settings, but many more exist in the
.envandconfig/app.phpfiles. In particular, you may want to change the language, timezone and e-mail settings. Runphp artisan config:cacheafter updating the config files. - In order to stop search engine crawlers from indexing your database, add the following to your “robots.txt” in your server root folder (in Debian, /var/www/html):
User-agent: *
Disallow: /
Updating an existing Apache installation
Before updating, back up your database, .env, and storage/app/public/media.
Before running commands, review config diffs for the target version:
- Compare
.envwith.env.example(includingASSET_URL) - Check PHP settings (
php.iniin CLI and FPM/Apache) - Check Supervisor worker settings
- Put the application in maintenance mode:
cd /home/odbserver/opendatabio
php artisan down
- Update source code to the target version:
git fetch --tags
git checkout <target-tag-or-branch>
- Update dependencies and apply database migrations:
composer install --no-dev --optimize-autoloader
php artisan migrate:status
php artisan migrate --force
- Rebuild frontend and Livewire assets after
.envupdates:
sh scripts/build-assets.sh
- Refresh caches and restart queue workers:
php artisan optimize:clear
php artisan config:cache
php artisan queue:restart
echo "" > storage/logs/laravel.log
- Bring the application back online:
php artisan up
If the target version includes new environment variables (compare yours with the contents of .env.example), add them to .env before running asset/cache commands.
Storage & Backups
You may change storage configurations in config/filesystem.php, where you may define cloud based storage, which may be needed if have many users submitting media files, requiring lots of drive space.
- Data downloads are queue as jobs and a file is written in a temporary folder, and the file is deleted when the job is deleted by the user. This folder is defined as the
download diskin filesystem.php config file, which point tostorage/app/public/downloads. UserJobs web interface difficult navigation will force users to delete old jobs, but a cron cleaning job may be advisable to implement in your installation; - Media files are by default stored in the
media disk, which place files in folderstorage/app/public/media; - For regular configuration create both directories
storage/app/public/downloadsandstorage/app/public/mediawith writable permissions by the Server user, see below topic; - Remember to include media folder in a backup plan;