--- description: Run your own notary service to host arbitrary content signing. keywords: docker, notary, notary-server, notary server, notary-signer, notary signer title: Run a Notary service --- This document is for anyone who wants to run their own Notary service (such as those who want to use Notary with a private Docker registry). Running a Notary service requires that you are already familiar with using [Docker Engine](/engine/userguide/) and [Docker Compose](/compose/). ## Run a service for testing or development The quickest way to spin up a full Notary service for testing and development purposes is to use the Docker compose file in the [Notary project](https://github.com/docker/notary). ```bash $ git clone https://github.com/theupdateframework/notary.git $ cd notary $ docker-compose up ``` This builds the development Notary server and Notary signer images, and start up containers for the Notary server, Notary signer, and the MySQL database that both of them share. The MySQL data is stored in a volume. Notary server and Notary signer communicate over mutually authenticated TLS (using the self-signed testing certs in the repository), and Notary server listens for HTTPS traffic on port 4443. By default, this development Notary server container runs with the testing self-signed TLS certificates. Before you can successfully connect to it, you must use the root CA file in `fixtures/root-ca.crt`. For example, to connect using OpenSSL: ```bash $ openssl s_client -connect :4443 -CAfile fixtures/root-ca.crt -no_ssl3 -no_ssl2 ``` To connect using the Notary Client CLI, see [Getting Started](getting_started.md). The version of the Notary server and signer needs to be greater than or equal to that of the Notary Client CLI to ensure feature compatibility. For instance, if you use Notary Client CLI 0.2, the server and signer each need to be at least version 0.2 as well. The self-signed certificate's subject name and subject alternative names are `notary-server`, `notaryserver`, and `localhost`, so if your Docker host is not on `localhost` (for example if you are using Docker Machine), update your hosts file such that the name `notary-server` is associated with the IP address of your Docker host. ## Advanced configuration options Both the Notary server and the Notary signer take [JSON configuration files](reference/index.md). Pre-built images, such as the [development images above](running_a_service.md#run-a-service-for-testing-or-development) provide these configuration files for you with some sane defaults. However, for running in production, or if you just want to change those defaults on your development service, you probably want to change those defaults. ### Running with different command line arguments You can override the `docker run` command for the image if you want to pass different command line options. Both Notary server and Notary signer take the following command line arguments: - `-config=` - specify the path to the JSON configuration file. - `-debug` - Passing this flag enables the debugging server on `localhost:8080`. The debugging server provides [pprof](https://golang.org/pkg/net/http/pprof) and [expvar](ttps://golang.org/pkg/expvar/) endpoints. (Remember, this is localhost with respect to the running container - this endpoint is not exposed from the container). This option can also be set in the configuration file. - `-logf=` - This flag sets the output format for the logs. Possible formats are "json" and "logfmt". This option cannot be set in the configuration file, since some log messages are produced on startup before the configuration file has been read. ### Specifying your own configuration files You can run the images with your own configuration files entirely. You just need to mount your configuration directory, and then pass the path to that configuration file as an argument to the `docker run` command. ### Overriding configuration file parameters using environment variables You can also override the parameters of the configuration by setting environment variables of the form `NOTARY_SERVER_` or `NOTARY_SIGNER_`. `var` is the ALL-CAPS, `"_"`-delimited path of keys from the top level of the configuration JSON. For instance, if you wanted to override the storage URL of the Notary server configuration: ```json "storage": { "backend": "mysql", "db_url": "dockercondemo:dockercondemo@tcp(notary-mysql)/dockercondemo" } ``` You would need to set the environment variable `NOTARY_SERVER_STORAGE_DB_URL`, because the `db_url` is in the `storage` section of the Notary server configuration JSON. ou cannot override a key whose value is another map. For instance, setting `NOTARY_SERVER_STORAGE='{"storage": {"backend": "memory"}}'` does not set in-memory storage. It just fails to parse. You can only override keys whose values are strings or numbers. For example, let's say that you wanted to run a single Notary server instance: - with your own TLS cert and keys - with a local, in-memory signer service rather than using Notary signer - using a local, in-memory TUF metadata store rather than using MySQL - produce JSON-formatted logs One way to do this would be: 1. Generate your own TLS certificate and key as `server.crt` and `server.key`, and put them in the directory `/tmp/server-configdir`. 2. Write the following configuration file to `/tmp/server-configdir/config.json`: { "server": { "http_addr": ":4443", "tls_key_file": "./server.key", "tls_cert_file": "./server.crt" }, "trust_service": { "type": "remote", "hostname": "notarysigner", "port": "7899", "tls_ca_file": "./root-ca.crt", "key_algorithm": "ecdsa", "tls_client_cert": "./notary-server.crt", "tls_client_key": "./notary-server.key" }, "storage": { "backend": "mysql", "db_url": "server@tcp(mysql:3306)/notaryserver?parseTime=True" } } NWe include a remote trust service and a database storage type to demonstrate how environment variables can override configuration parameters. 3. Run the following command (assuming you've already built or pulled a Notary server docker image): $ docker run \ -p "4443:4443" \ -v /tmp/server-configdir:/etc/docker/notary-server/ \ -e NOTARY_SERVER_TRUST_SERVICE_TYPE=local \ -e NOTARY_SERVER_STORAGE_BACKEND=memory \ -e NOTARY_SERVER_LOGGING_LEVEL=debug \ notary_server \ -config=/etc/docker/notary-server/config.json \ -logf=json {"level":"info","msg":"Version: 0.2, Git commit: 619f8cf","time":"2016-02-25T00:53:59Z"} {"level":"info","msg":"Using local signing service, which requires ED25519. Ignoring all other trust_service parameters, including keyAlgorithm","time":"2016-02-25T00:53:59Z"} {"level":"info","msg":"Using memory backend","time":"2016-02-25T00:53:59Z"} {"level":"info","msg":"Starting Server","time":"2016-02-25T00:53:59Z"} {"level":"info","msg":"Enabling TLS","time":"2016-02-25T00:53:59Z"} {"level":"info","msg":"Starting on :4443","time":"2016-02-25T00:53:59Z"} You can do the same using [Docker Compose](/compose/) by setting volumes, environment variables, and overriding the default command for the Notary server containers in the Compose file. ## Recommendations for deploying in production When moving from development to production there are a number of considerations that must be made to ensure security and scalability. ### Certificates The Notary repository includes sample certificates in the fixtures directory. When you initialize a development service using the provided `docker-compose.yml` file, these sample certificates are used to create a more production like environment. **You must acquire your own certificates to use in a production deployment.** The sample private key files in the Notary repository are obviously public knowledge and using them in a production deployment is highly insecure. ### Certificate directory Notary is a user/client-based system, and it searches for certificates in the user's home directory, at `~/.docker/trust`. To streamline using Notary from the command line, create an alias that maps the user's `trust` directory to the system's `ca-certificates` directory. ```bash $ alias notary="notary -s https:// -d ~/.docker/trust --tlscacert /usr/local/share/ca-certificates/.crt" ``` ### Databases The server and signer each require a database. These should be separate databases with different users. The users should be limited in their permissions. We recommend giving the following MySQL (or equivalent) permissions to the users restricted to only their own databases: - Notary server database user: `SELECT, INSERT, UPDATE, DELETE` - Notary signer database user: `SELECT, INSERT, DELETE` ### High Availability To increase availability, you can run multiple instances of both the server and signer applications. These can scale arbitrarily and independently. The database can also scale independently but this is left as an exercise for experienced DBAs and Operations teams. A typical deployment looks like this: ![Notary server Deployment Diagram](https://cdn.rawgit.com/docker/notary/09f81717080f53276e6881ece57cbbbf91b8e2a7/docs/images/service-deployment.svg) In the diagram, a load balancer routes external traffic to a cluster of Notary server instances. These may make requests to Notary signer instances if either a) signing is required, or b) key generation is required. The requests from a Notary server to a Notary signer cluster are router via an internal load balancer. Notary can be used with a CDN or other caching system. All GET requests for JSON files may be cached indefinitely __except__ URLs matching: - `*/root.json` - `*/timestamp.json` All other requests for JSON files include sha256 checksums of the file being requested and are therefore immutable. Requests for JSON files make up the vast majority of all notary requests. Requests for anything other than a GET of a JSON file should not be cached. ## Related information * [Notary service architecture](service_architecture.md) * [Notary configuration files](reference/index.md)