This guide describes how to self-host an environment of Specify 7.
This guide is intended for technical or IT users only.
[!info]
Before you begin, consider that the Specify Collections Consortium (SCC) offers the Specify Cloud hosting service to members of the consortium.
By choosing SCCâs Specify Cloud hosting, you get a fully managed Specify 7 environment with automatic updates, priority support, and low-latency servers in cloud regions around the world. Daily backups of your database and attachments ensure your data is always protected, and optional add-onsâlike scalable digital asset storage, direct SQL access, and remote Specify 6 connectivityâgive your IT team the flexibility they need without the extra maintenance overhead.
If youâd like pricing details or to discuss an evaluation period, please see our services prices or get in touch at membership@specifysoftware.org. Weâd love to help you turn over the sysadmin headaches and focus on what you do bestâadvancing collectionâbased research.
Introduction
This approach means that your IT support will need to be responsible for managing the server hosting Specify and the associated assets, updates, and day-to-day accesss troubleshooting. We encourage SCC members to use our Dockerized compositions of Specify 7.
There already exists similar documentation regarding self hosting Specify 7. If desired, see the Installation Instructions on the Specify 7 GitHub, Specify 7 Installation Instructions, Install Specify 7 With Docker (from Matthew Cruz of the University of Michigan), the Developer Wiki for general information regarding the architecture of Specify 7, Docker Workflow for Development on the Developer Wiki regarding setting up an environment specifically for development.
Getting Started
We recommend using Docker to host Specify 7 (as well as hosting the Report Runner and Web Asset Server services). Docker allows each service to be âcontainerizedâ or in other words, generally isolated from the host computer. This means each container is in charge of its dependencies and only Docker is required to be installed for each containerized service.
Service and Architecture Overview
Because Specify 7 is a webservice, there are a number of separate services or components which act and communicate together to provide the entire Specify suite of functionality.
You can learn more about the software architecture in the following topic:
Recommended Server Specifications
Specify 7
Code Source: https://github.com/specify/specify7
Container Images: https://hub.docker.com/r/specifyconsortium/specify7-service/tags
The primary frontend and backend of the Specify 7 application. Specifically, it contains a Django web framework for processing web requests. Once the initial server-provided web-page is loaded, rendering is handled client-side via React and React Router.
Traditionally, the Web Server Gateway Interface (WSGI) Gunicorn is used to forward web-server requests to Django.
At runtime, Django configuration settings for the Specify installation are read from the specifyweb/settings/__init__.py file. This file generally expects the user-configured settings to be present within a local_specify_settings.py
file in the same directory. Possible user-configurable variables can be found within the specify_settings.py file.
For local non-containerized installations, this file is copied and renamed to local_specify_settings.py
(see Adjusting Settings Files).
When building Specify 7 using the provided Dockerfile or when using any of the built images hosted on Docker Hub (https://hub.docker.com/r/specifyconsortium/specify7-service/tags), these user-configurable variables are read from the container environment variables and copied into local_specify_settings.py
.
Example commands to start the Specify 7 Service:
# Apply the initial Specify migration if not already appliedve/bin/python manage.py base_specify_migration
# Apply any normal migrationsve/bin/python manage.py migrate
# Start the WSGI Server + Django
ve/bin/gunicorn -w 3 -b 0.0.0.0:8000 -t 300 specifyweb_wsgi
See Dockerfile#L225, docker-entrypoint.sh, and specifyweb.wsgi.
When using a built image from the Specify 7 Image repository, these commands are executed automatically on container startup.
Supported Customization / Environment Variables
Variable Name | Description | Default / Example Value |
---|---|---|
DATABASE_HOST | Hostname or IP of the server hosting the database | localhost |
DATABASE_PORT | The port number of the database application | 3306 |
DATABASE_NAME | The name of the database to connect to within the database application | SpecifyDB |
MASTER_NAME | The username of the database user which the Specify application will act as | MasterUser |
MASTER_PASSWORD | The password of the database user which the Specify application will act as | MasterPassword |
SECRET_KEY | An unpredictable, unique key that Django uses for cryptographic signing. See https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-SECRET_KEY | |
ASSET_SERVER_URL | The complete url to the web_asset_store.xml of the Attachment Server service |
http://host.docker.internal/web\_asset\_store.xml |
ASSET_SERVER_KEY | The configured ATTACHMENT_KEY of the Attachment Server service | |
REPORT_RUNNER_HOST | The hostname or IP of the Report Runner service | report-runner |
REPORT_RUNNER_PORT | The port number of the report runner application | 8080 |
CELERY_BROKER_URL | The URL of the message broker celery will use to send and receive messages. See https://docs.celeryq.dev/en/stable/userguide/configuration.html#broker-url | redis://localhost/0 |
CELERY_RESULT_BACKEND | The backend used to store task results. See https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-backend | redis://localhost/1 |
LOG_LEVEL | The logging level mask for the Specify 7 backend. All logging statements for levels below | WARNING (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL) |
SP7_DEBUG | Whether Django is run in DEBUG mode. See https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-DEBUG | true (or false) |
SPECIFY_CONFIG_DIR | A file path to a Specify 6 config directory containing Specify-specific configuration files. See https://github.com/specify/specify6/tree/master/config |
Specify 7 Worker
Potentially computationally expensive, asynchronous, or otherwise slow operations in the main Specify application are commonly passed to a separate task queue (traditionally Celery), through a message broker (commonly Redis).
Redis Container Images: https://hub.docker.com/_/redis
Architecturally, the Specify 7 Worker is usually identical to the primary Specify 7 service.
The Celery worker can be started from the Specify 7 Worker instance via the following command (which is commonly included within a compose file for the Specify 7 Worker service) :
command: bash -c "ve/bin/celery -A specifyweb worker -l INFO --concurrency=1"
For more information regarding using Celery from the command line, view the Celery documentation at https://docs.celeryq.dev/en/latest/userguide/workers.html.
Additional information regarding Celery and Django (including the CELERY_BROKER_URL and CELERY_RESULT_BACKEND variables) can be found at: celery/docs/django/first-steps-with-django.rst at main
Supported Customization / Environment Variables
Variable Name | Description | Default / Example Value |
---|---|---|
DATABASE_HOST | Hostname or IP of the server hosting the database | localhost |
DATABASE_PORT | The port number of the database application | 3306 |
DATABASE_NAME | The name of the database to connect to within the database application | SpecifyDB |
MASTER_NAME | The username of the database user which the Specify application will act as | MasterUser |
MASTER_PASSWORD | The password of the database user which the Specify application will act as | MasterPassword |
SECRET_KEY | An unpredictable, unique key that Django uses for cryptographic signing. See https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-SECRET_KEY | |
ASSET_SERVER_URL | The complete url to the web_asset_store.xml of the Attachment Server service |
http://host.docker.internal/web\_asset\_store.xml |
ASSET_SERVER_KEY | The configured ATTACHMENT_KEY of the Attachment Server service | |
REPORT_RUNNER_HOST | The hostname or IP of the Report Runner service | report-runner |
REPORT_RUNNER_PORT | The port number of the report runner application | 8080 |
CELERY_BROKER_URL | The URL of the message broker celery will use to send and receive messages. See https://docs.celeryq.dev/en/stable/userguide/configuration.html#broker-url | redis://localhost/0 |
CELERY_RESULT_BACKEND | The backend used to store task results. See https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-backend | redis://localhost/1 |
LOG_LEVEL | The logging level mask for the Specify 7 backend. All logging statements for levels below are ignored in the standard output. (DEBUG , INFO , WARNING , ERROR , or CRITICAL ). |
WARNING |
SP7_DEBUG | Whether Django is run in DEBUG mode. See https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-DEBUG | true (or false) |
SPECIFY_CONFIG_DIR | A file path to a Specify 6 config directory containing Specify-specific configuration files. See https://github.com/specify/specify6/tree/master/config |
MariaDB (Database)
The MariaDB service provides the database for Specify 7. By default, MariaDB listens on port 3306. At this time, there are no other supported database management systems available for Specify 7. This can both be managed in a Docker container and managed externally.
Supported Customization / Environment Variables
Variable Name | Description | Default Value |
---|---|---|
MYSQL_ROOT_PASSWORD | Password for the MariaDB root superuser. |
root |
MYSQL_DATABASE | Name of the default database to create on startup. | specify |
MYSQL_USER | Name of a non-root user to create and grant privileges on the default database. | master |
MYSQL_PASSWORD | Password for the non-root user specified by MYSQL_USER . |
master |
Additionally, command line options for starting the database application are commonly included within compose files:
command: --max_allowed_packet=1073741824
Attachment Server
Source Code: https://github.com/specify/web-asset-server
Docker Hub (Includes available Images): https://hub.docker.com/r/specifyconsortium/specify-asset-service
Documentation: https://discourse.specifysoftware.org/t/web-asset-server-attachment-server/657
This is our official attachment server implementation for Specify. This implementation is targeted at Ubuntu flavors, but will work with minor modifications on other Linux systems.
Supported Customization / Environment Variables
Variable Name | Description | Default Value |
---|---|---|
SERVER_NAME | The hostname or IP (and optional path) at which the asset server is publicly accessible. | |
SERVER_PORT | The TCP port on which the server listens for incoming HTTP requests. | 80 |
ATTACHMENT_KEY | A shared secret key used to authenticate requests between the Specify 7 service and the asset server service. | |
DEBUG_MODE | Enable verbose logging and error output. Set to true for development, false for production. |
false |
Report Runner
Source Code: https://github.com/specify/report-runner-service
Docker Hub (Includes available Images): https://hub.docker.com/r/specifyconsortium/report-runner
The Specify Report Runner is a simple web service wrapper around the Jasper Reports libraries for report and label generation in Specify 7. It generates reports for Specify 7 via a REST endpoint.
Supported Customization / Environment Variables
Variable Name | Description | Default Value |
---|---|---|
REPORT_RUNNER_HOST | Hostname or IP address (container name or network alias) where the report-runner service is reachable. | report-runner |
REPORT_RUNNER_PORT | TCP port on which the report-runner service listens. | 8080 |
LOG_LEVEL | Minimum log level for the report-runner process (DEBUG , INFO , WARNING , ERROR , or CRITICAL ). |
INFO |
SP7_DEBUG | Enable debug mode in integrated components (affects verbose output). | false |
Web Server / Reverse Proxy
Docker Hub (Includes available Images): https://hub.docker.com/_/nginx
We recommend and commonly utilize NGINX as a webserver and reverse proxy.
As a reverse proxy, itâs important to forward requests meant for the asset server (see the routes in web-asset-server/server.py#L212-361) to the correct hostname and port, as well as serving static files directly to the requesting client. All other requests can be forwarded to the main Specify 7 service.
Simple example NGINX configuration for Specify 7:
See docker-compositions/all-in-one/nginx/specify.conf or specify7/nginx.conf
Self-Hosting Specify 7: Example Docker Compose Configurations
Below are three example compositions for self-hosting Specify 7. Each scenario is available in our member-exclusive GitHub repository.
Click here to request access, including your GitHub username, member institution, collection, and any additional questions or notes you have for us.
Clone the repo, pick the directory matching your needs, adjust environment variables, then start the containers.
1. All-in-One
Use case: Single-host evaluation or small deployments where you want every service bundled: database, Specify 7, asset server, report runner, and web server.
Key steps:
-
Seed database:
⢠Place your Specify 6 SQL dump (noCREATE DATABASE
/USE
statements) intoseed-database/
.
⢠Ensure the dump originates from a preconfigured Specify 6 instance (with at least one collection, discipline, division, and institution). -
Configure
.env
ordocker-compose.yml
:
â˘SEED_DB_FILE
â filename inseed-database/
â˘MYSQL_ROOT_PASSWORD
â MariaDB root password
â˘MYSQL_USER
/MYSQL_PASSWORD
â non-root Specify 7 user credentials
â˘SPECIFY_ASSET_DIR
â in-container mount point for attachments volume
â˘REPORT_RUNNER_ENABLED
âtrue
orfalse
-
Launch:
docker-compose up -d
Reference: all-in-one/docker-compose.yml
2. Just Specify 7
Use case: You already have a production Specify 6 (MySQL/MariaDB + asset server). You only want the new Specify 7 front-end and its web server.
Services included:
- specify7-service (Specify 7 application)
- nginx (proxy + static file server)
- report-runner (optional; for labels & reports)
Configuration steps:
- In
docker-compose.yml
, set:
â˘DATABASE_HOST
,DATABASE_NAME
,MASTER_NAME
,MASTER_PASSWORD
â point to your existing MariaDB
â˘ASSET_SERVER_URL
/ASSET_SERVER_KEY
â match your asset server
â˘REPORT_RUNNER_HOST
/REPORT_RUNNER_PORT
(if enabled) - Comment out the
report-runner
service if you donât need reporting. - Start services:
docker-compose up -d
Reference: just-specify/docker-compose.yml
3. Multiple Databases
Use case: Host multiple, distinct Specify 7 databases on one host via name-based virtual hosting.
How it works:
- Define one Specify 7 service per database in
docker-compose.yml
. - Allocate a dedicated Docker volume (for static files) to each instance.
- In Nginxâs
specify.conf
, create multipleserver
blocksâeach with its ownserver_name
and upstream to the matching Specify 7 container.
Setup steps:
- Duplicate the Specify 7 service block (
-db1
,-db2
, âŚ) and assign unique environment variables and volumes. - Update
nginx/specify.conf
:
server {
listen 80;
server_name specify-db1.example.com;
location / {
proxy_pass http://specify7-db1:8000;
}
âŚ
}
server {
listen 80;
server_name specify-db2.example.com;
location / {
proxy_pass http://specify7-db2:8000;
}
âŚ
}
- Launch all services:
docker-compose up -d
Reference:
Updating Specify 7
When a new Specify 7 release is available, follow these steps to safely upgrade your self-hosted system.
1. Review the Release Notes
- Check the Specify Discourse for release announcements for breaking changes, new environment variables, and migration notes.
- Note any required adjustments to your
docker-compose.yml
, Nginx config, or application settings.
2. Backup Your Data
Always back up your database and volumes before upgrading:
# Dump the Specify database
docker exec -it <db_container> \
mysqldump -u it_user -p"${MYSQL_ROOT_PASSWORD}" \
--databases "${MYSQL_DATABASE}" > specify7_backup.sql
# Archive attachments volume
docker run --rm \
-v attachments:/data \
-v "$(pwd)":/backup \
alpine \
tar czf /backup/attachments_backup.tgz -C /data .
# Archive static-files volume (if used)
docker run --rm \
-v static-files:/data \
-v "$(pwd)":/backup \
alpine \
tar czf /backup/staticfiles_backup.tgz -C /data .
Store backups off-site or in a secure location.
3. Choose & Update Docker Tags
Recommended: use the v7
tagâthis always pulls the latest Specify 7 release.
If you want to âlockâ to a specific point release, specify v7.10
(or v7.x.x
); youâll only move to v7.11
when you manually change the tag.
Tag | Pulls |
---|---|
v7 | Latest tagged release of Specify |
v7.x | Latest release in major version 7.x |
v7.x.x | Latest release in minor version 7.x.x |
In your docker-compose.yml
, update image references accordingly:
services:
specify7:
image: specifyconsortium/specify7-service:v7
report-runner:
image: specifyconsortium/report-runner:v7
asset-server:
image: specifyconsortium/specify-asset-service:v7
Then:
docker-compose pull
4. Merge Configuration Changes
- Compare your existing
docker-compose.yml
,nginx.conf
, and any mountedsettings.py
against examples in the new release. - Add or update environment variables (new
ASSET_SERVER_URL
,SP7_DEBUG
, etc.). - Commit these changes to your configuration repo.
5. Apply Database Migrations
Specify 7 auto-runs Django migrations on startup using the IT userâthis ensures all schema changes and new records are applied. Do not use the master user for migrations.
docker-compose run --rm specify7 \
./ve/bin/python manage.py migrate
Verify that migrations complete without errors.
6. Restart & Verify Services
Bring up the updated containers:
docker-compose up -d
Monitor logs:
docker-compose logs -f specify7 report-runner nginx
Then, in your browser:
- Log in to the Specify 7 UI.
- Test core workflows: record search, attachment upload, report generation.
- Confirm no errors appear in the logs.
7. Post-Upgrade Cleanup
Once youâve verified the upgrade, you can safely remove old images:
docker image prune -f
Tips & Best Practices
- Always back up before any upgrade.
- Test upgrades in a staging environment.
- Pin tags if you require stability; use
v7
for automatic updates. - For production, terminate debug modes (
SP7_DEBUG=false
) and enable HTTPS at your proxy layer.