diff --git a/docs/datasette-package-help.txt b/docs/datasette-package-help.txt
new file mode 100644
index 00000000..cab77a13
--- /dev/null
+++ b/docs/datasette-package-help.txt
@@ -0,0 +1,25 @@
+$ datasette package --help
+
+ Usage: datasette package [OPTIONS] FILES...
+
+ Package specified SQLite files into a new datasette Docker container
+
+Options:
+ -t, --tag TEXT Name for the resulting Docker container, can
+ optionally use name:tag format
+ -m, --metadata FILENAME Path to JSON file containing metadata to publish
+ --extra-options TEXT Extra options to pass to datasette serve
+ --branch TEXT Install datasette from a GitHub branch e.g. master
+ --template-dir DIRECTORY Path to directory containing custom templates
+ --plugins-dir DIRECTORY Path to directory containing custom plugins
+ --static STATIC MOUNT mountpoint:path-to-directory for serving static
+ files
+ --install TEXT Additional packages (e.g. plugins) to install
+ --spatialite Enable SpatialLite extension
+ --version-note TEXT Additional note to show on /-/versions
+ --title TEXT Title for metadata
+ --license TEXT License label for metadata
+ --license_url TEXT License URL for metadata
+ --source TEXT Source label for metadata
+ --source_url TEXT Source URL for metadata
+ --help Show this message and exit.
diff --git a/docs/datasette-publish-help.txt b/docs/datasette-publish-help.txt
new file mode 100644
index 00000000..94753ef5
--- /dev/null
+++ b/docs/datasette-publish-help.txt
@@ -0,0 +1,34 @@
+$ datasette publish --help
+
+ Usage: datasette publish [OPTIONS] PUBLISHER [FILES]...
+
+ Publish specified SQLite database files to the internet along with a
+ datasette API.
+
+ Options for PUBLISHER: * 'now' - You must have Zeit Now installed:
+ https://zeit.co/now * 'heroku' - You must have Heroku installed:
+ https://cli.heroku.com/
+
+ Example usage: datasette publish now my-database.db
+
+Options:
+ -n, --name TEXT Application name to use when deploying to Now
+ (ignored for Heroku)
+ -m, --metadata FILENAME Path to JSON file containing metadata to publish
+ --extra-options TEXT Extra options to pass to datasette serve
+ --force Pass --force option to now
+ --branch TEXT Install datasette from a GitHub branch e.g. master
+ --token TEXT Auth token to use for deploy (Now only)
+ --template-dir DIRECTORY Path to directory containing custom templates
+ --plugins-dir DIRECTORY Path to directory containing custom plugins
+ --static STATIC MOUNT mountpoint:path-to-directory for serving static
+ files
+ --install TEXT Additional packages (e.g. plugins) to install
+ --spatialite Enable SpatialLite extension
+ --version-note TEXT Additional note to show on /-/versions
+ --title TEXT Title for metadata
+ --license TEXT License label for metadata
+ --license_url TEXT License URL for metadata
+ --source TEXT Source label for metadata
+ --source_url TEXT Source URL for metadata
+ --help Show this message and exit.
diff --git a/docs/datasette-serve-help.txt b/docs/datasette-serve-help.txt
new file mode 100644
index 00000000..4c7a9877
--- /dev/null
+++ b/docs/datasette-serve-help.txt
@@ -0,0 +1,29 @@
+$ datasette serve --help
+
+ Usage: datasette serve [OPTIONS] [FILES]...
+
+ Serve up specified SQLite database files with a web UI
+
+Options:
+ -h, --host TEXT host for server, defaults to 127.0.0.1
+ -p, --port INTEGER port for server, defaults to 8001
+ --asgi Run in ASGI mode
+ --debug Enable debug mode - useful for development
+ --reload Automatically reload if code change detected -
+ useful for development
+ --cors Enable CORS by serving Access-Control-Allow-
+ Origin: *
+ --load-extension PATH Path to a SQLite extension to load
+ --inspect-file TEXT Path to JSON file created using "datasette
+ inspect"
+ -m, --metadata FILENAME Path to JSON file containing license/source
+ metadata
+ --template-dir DIRECTORY Path to directory containing custom templates
+ --plugins-dir DIRECTORY Path to directory containing custom plugins
+ --static STATIC MOUNT mountpoint:path-to-directory for serving static
+ files
+ --config CONFIG Set config option using configname:value
+ datasette.readthedocs.io/en/latest/config.html
+ --version-note TEXT Additional note to show on /-/versions
+ --help-config Show available config options
+ --help Show this message and exit.
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index f09c3970..5b1d0647 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -79,31 +79,4 @@ JSON in a more convenient but less efficient format:
datasette serve options
-----------------------
-::
-
- $ datasette serve --help
- Usage: datasette serve [OPTIONS] [FILES]...
-
- Serve up specified SQLite database files with a web UI
-
- Options:
- -h, --host TEXT host for server, defaults to 127.0.0.1
- -p, --port INTEGER port for server, defaults to 8001
- --debug Enable debug mode - useful for development
- --reload Automatically reload if code change detected -
- useful for development
- --cors Enable CORS by serving Access-Control-Allow-
- Origin: *
- --load-extension PATH Path to a SQLite extension to load
- --inspect-file TEXT Path to JSON file created using "datasette
- inspect"
- -m, --metadata FILENAME Path to JSON file containing license/source
- metadata
- --template-dir DIRECTORY Path to directory containing custom templates
- --plugins-dir DIRECTORY Path to directory containing custom plugins
- --static STATIC MOUNT mountpoint:path-to-directory for serving static
- files
- --config CONFIG Set config option using configname:value
- datasette.readthedocs.io/en/latest/config.html
- --help-config Show available config options
- --help Show this message and exit.
+.. literalinclude:: datasette-serve-help.txt
diff --git a/docs/index.rst b/docs/index.rst
index 6f81b46e..e945cf64 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -18,6 +18,7 @@ Contents
installation
getting_started
+ publish
json_api
sql_queries
csv_export
diff --git a/docs/publish.rst b/docs/publish.rst
new file mode 100644
index 00000000..a7222959
--- /dev/null
+++ b/docs/publish.rst
@@ -0,0 +1,119 @@
+.. _publishing:
+
+=================
+ Publishing data
+=================
+
+Datasette includes tools for publishing and deploying your data to the internet. The ``datasette publish`` command will deploy a new Datasette instance containing your databases directly to a Zeit New or Heroku hosting account. You can also use ``datasette package`` to create a Docker image that bundles your databases together with the datasette application that is used to serve them.
+
+datasette publish
+=================
+
+Once you have created a SQLite database (e.g. using `csvs-to-sqlite `_) you can deploy it to a hosting account using a single command.
+
+You will need a free hosting account with either `Zeit Now `_ or `Heroku `_. Once you have created your account you will need to install and configure the ``now`` or ``heroku`` command-line tools.
+
+Publishing to Zeit Now
+----------------------
+
+To publish your database(s) to a new instance hosted by Zeit Now, create an account there, install the `now cli tool `_ and then run the following command::
+
+ datasette publish now mydatabase.db
+
+This will upload your database to Zeit Now, assign you a new URL and install and start a new instance of Datasette to serve your database.
+
+The command will output a URL that looks something like this::
+
+ https://datasette-elkksjmyfj.now.sh
+
+You can navigate to this URL to see live logs of the deployment process. Your new Datasette instance will be available at that URL.
+
+Once the deployment has completed, you can assign a custom URL to your instance using the ``now alias`` command::
+
+ now alias https://datasette-elkksjmyfj.now.sh datasette-publish-demo.now.sh
+
+You can use ``anything-you-like.now.sh``, provided no one else has already registered that alias.
+
+You can also use custom domains, if you `first register them with Zeit Now `_.
+
+Publishing to Heroku
+--------------------
+
+To publish your data using Heroku, first create an account there and install and configure the `Heroku CLI tool `_.
+
+You can now publish a database to Heroku using the following command::
+
+ datasette publish heroku mydatabase.db
+
+This will output some details about the new deployment, including a URL like this one::
+
+ https://limitless-reef-88278.herokuapp.com/ deployed to Heroku
+
+You can then set a custom subdomain by navigating to your new app's equivalent of ``https://dashboard.heroku.com/apps/limitless-reef-88278/settings`` and editing the name of your deployment, e.g. to http://datasette-publish-demo.herokuapp.com/
+
+Custom metadata and plugins
+---------------------------
+
+``datasette publish`` accepts a number of additional options which can be used to further customize your Datasette instance.
+
+You can define your own :ref:`metadata` and deploy that with your instance like so::
+
+ datasette publish now mydatabase.db -m metadata.json
+
+If you just want to set the title, license or source information you can do that directly using extra options to ``datasette publish``::
+
+ datasette publish now mydatabase.db \
+ --title="Title of my database" \
+ --source="Where the data originated" \
+ --source_url="http://www.example.com/"
+
+You can also specify plugins you would like to install. For example, if you want to include the `datasette-vega `_ visualization plugin you can use the following::
+
+ datasette publish now mydatabase.db --install=datasette-vega
+
+A full list of options can be seen by running ``datasette publish --help``:
+
+.. literalinclude:: datasette-publish-help.txt
+
+datasette package
+=================
+
+If you have docker installed (e.g. using `Docker for Mac `_) you can use the ``datasette package`` command to create a new Docker image in your local repository containing the datasette app bundled together with your selected SQLite databases::
+
+ datasette package mydatabase.db
+
+Here's example output for the package command::
+
+ $ datasette package parlgov.db --extra-options="--config sql_time_limit_ms:2500"
+ Sending build context to Docker daemon 4.459MB
+ Step 1/7 : FROM python:3
+ ---> 79e1dc9af1c1
+ Step 2/7 : COPY . /app
+ ---> Using cache
+ ---> cd4ec67de656
+ Step 3/7 : WORKDIR /app
+ ---> Using cache
+ ---> 139699e91621
+ Step 4/7 : RUN pip install datasette
+ ---> Using cache
+ ---> 340efa82bfd7
+ Step 5/7 : RUN datasette inspect parlgov.db --inspect-file inspect-data.json
+ ---> Using cache
+ ---> 5fddbe990314
+ Step 6/7 : EXPOSE 8001
+ ---> Using cache
+ ---> 8e83844b0fed
+ Step 7/7 : CMD datasette serve parlgov.db --port 8001 --inspect-file inspect-data.json --config sql_time_limit_ms:2500
+ ---> Using cache
+ ---> 1bd380ea8af3
+ Successfully built 1bd380ea8af3
+
+You can now run the resulting container like so::
+
+ docker run -p 8081:8001 1bd380ea8af3
+
+This exposes port 8001 inside the container as port 8081 on your host machine, so you can access the application at ``http://localhost:8081/``
+
+A full list of options can be seen by running ``datasette package --help``:
+
+.. literalinclude:: datasette-package-help.txt
diff --git a/update-docs-help.sh b/update-docs-help.sh
new file mode 100755
index 00000000..a5e8a7ab
--- /dev/null
+++ b/update-docs-help.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+echo $'$ datasette serve --help\n\n' "$(datasette serve --help)" > docs/datasette-serve-help.txt
+echo $'$ datasette publish --help\n\n' "$(datasette publish --help)" > docs/datasette-publish-help.txt
+echo $'$ datasette package --help\n\n' "$(datasette package --help)" > docs/datasette-package-help.txt