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 default image uses the built-in gevent server on port 9004 with a volume-mounted database.

Building the image:

$ docker build -t scout .

Running the container:

$ docker run -d \
    -p 8000:9004 \
    -v /path/to/data:/data \
    --name scout \
    scout

The database file is stored at /data/search-index.db inside the container (controlled by the SCOUT_DATABASE environment variable). Logs are written to /data/scout.log.

You can override any Scout option by appending flags to the docker run command:

$ docker run -d \
    -p 8000:9004 \
    -v /path/to/data:/data \
    -e SCOUT_DATABASE=/data/my-index.db \
    scout \
    --api-key secret --paginate-by 100

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

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

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