Deployment

When Scout is run from the command-line, it will use the multi-threaded Werkzeug WSGI server. While this server is perfect for development and small installations, you may want to use a high-performance WSGI server to deploy Scout.

Scout provides a WSGI app, so you can use any WSGI server for deployment. Popular choices are:

The Flask documentation also provides a list of popular WSGI servers and how to integrate them with Flask apps. Since Scout is a Flask application, all of these examples should work with minimal modification:

https://flask.palletsprojects.com/en/latest/deploying/

Environment variables

The following environment variables can be used to configure Scout in any deployment scenario:

  • SCOUT_DATABASE: path to the SQLite database file. Equivalent to passing the database path as a command-line argument.

  • SCOUT_CONFIG: path to a Python configuration file. Equivalent to the -c / --config command-line option. See Python Configuration File for details.

  • SCOUT_MAX_CONNECTIONS: maximum number of concurrent connections for the built-in gevent server. Defaults to 128. Only applies when using scout_wsgi.

Gevent

Scout comes with a production-ready gevent WSGI server. To run this server:

$ scout_wsgi /path/to/database.db

The built-in gevent server uses a connection pool to limit concurrency. You can control the pool size via the SCOUT_MAX_CONNECTIONS environment variable:

$ SCOUT_MAX_CONNECTIONS=256 scout_wsgi /path/to/database.db

If you wish to have more control over the server implementation, this example wrapper script can get you started:

from gevent import monkey
monkey.patch_all()

from gevent.pywsgi import WSGIServer
from scout.server import parse_options

# Parse command-line options and return a Flask app.
app = parse_options()

# Run the WSGI server on localhost:8000.
WSGIServer(('127.0.0.1', 8000), app).serve_forever()

You could then run the wrapper script using a tool like supervisord or another process manager.

Gunicorn

Here is an example wrapper script for running Scout using Gunicorn.

# Wrapper script to initialize database.
from scout.server import parse_options
app = parse_options()

Here is how to run gunicorn using the above wrapper script:

$ gunicorn --workers=4 --bind=127.0.0.1:8000 --worker-class=gevent wrapper:app

Note

The --worker-class=gevent option requires gevent to be installed (pip install gevent). You can omit this flag to use Gunicorn’s default synchronous workers instead.

uWSGI

Here is an example wrapper script for uWSGI.

# Wrapper script to initialize database.
from scout.server import parse_options
app = parse_options()

Here is how you might run using the above wrapper script:

$ uwsgi --http :8000 --wsgi-file wrapper.py --master --processes 4 --threads 2

It is common to run uWSGI behind Nginx. For more information check out the uWSGI docs.

Docker

Scout includes a Dockerfile for containerized deployments. The Docker image runs Scout on port 9004 (rather than the default 8000) using the built-in gevent WSGI server. The database path defaults to /data/search-index.db and is controlled by the SCOUT_DATABASE environment variable. The /data directory is declared as a volume.

To run Scout using Docker, you can pull the coleifer/scout image from the GitHub container registry:

$ docker run -d \
    --name scout \
    -p 9004:9004 \
    -v /path/to/data:/data \
    ghcr.io/coleifer/scout:latest

Note

Always mount a host directory to /data (as shown above) to persist your search index across container restarts.

You can also build the image locally:

$ cd scout/docker
$ docker build -t scout .
$ docker run -d \
    --name scout \
    -p 9004:9004 \
    -v /path/to/data:/data \
    scout

The database file is stored at /data/search-index.db inside the container. Logs are written to /data/scout.log.

Overriding settings

You can pass additional Scout CLI flags by appending them to the docker run command:

$ docker run -d \
    -p 9004:9004 \
    -v /path/to/data:/data \
    ghcr.io/coleifer/scout:latest \
    -k my-secret-api-key \
    --paginate-by 100

You can override the database location with the SCOUT_DATABASE environment variable:

$ docker run -d \
    -p 9004:9004 \
    -v /path/to/data:/data \
    -e SCOUT_DATABASE=/data/my-index.db \
    ghcr.io/coleifer/scout:latest

To use a custom configuration file, mount it into the container and set the SCOUT_CONFIG environment variable:

$ docker run -d \
    -p 9004:9004 \
    -v /path/to/data:/data \
    -v /path/to/config.py:/etc/scout/config.py \
    -e SCOUT_CONFIG=/etc/scout/config.py \
    ghcr.io/coleifer/scout:latest

The image includes a health check that polls the index list endpoint every 30 seconds.

Migrating an existing database

If you are upgrading from an older Scout version that used FTS4, you can run the migration inside the container:

$ docker run --rm \
    -v /path/to/data:/data \
    ghcr.io/coleifer/scout:latest --migrate