Custom Domains and White Labeling

Once a project is imported into Read the Docs, by default it’s hosted under a subdomain on one of our domains. If you need a custom domain, see Custom domain support.

Subdomain support

Every project has a subdomain that is available to serve its documentation. If you go to <slug>.readthedocs.io, it should show you the latest version of your documentation. A good example is https://pip.readthedocs.io For Read the Docs for Business the subdomain looks like <slug>.readthedocs-hosted.com.

Custom domain support

You can also host your documentation from your own domain.

Note

We don’t currently support pointing subdomains or root domains to a project using A records. DNS A records require a static IP address and our IPs may change without notice.

In order to setup your custom domain, follow these steps:

  1. For a subdomain like docs.example.com, add a CNAME record in your DNS that points the domain to readthedocs.io. For a root domain like example.com use an ANAME or ALIAS record pointing to readthedocs.io.

  2. Go the Admin tab of your project

  3. Click on Domains

  4. Enter your domain and click on Add

By default, we provide a validated SSL certificate for the domain. This service is generously provided by Cloudflare. The SSL certificate issuance can take about one hour, you can see the status of the certificate on the domain page in your project.

As an example, fabric’s DNS record looks like this:

 dig CNAME +short docs.fabfile.org
readthedocs.io.

In order to setup your custom domain, follow these steps:

  1. Go the Admin tab of your project

  2. Click on Domains

  3. Enter your domain and click on Add

  4. Follow the steps shown on the domain page. This will require adding 2 DNS records, one pointing your custom domain to our servers, and another allowing us to provision an SSL certificate.

By default, we provide a validated SSL certificate for the domain. The SSL certificate issuance can take a few days, you can see the status of the certificate on the domain page in your project.

Note

Some older setups configured a CNAME record pointing to <organization-slug>.users.readthedocs.com. These domains will continue to resolve.

Strict Transport Security

By default, we do not return a Strict Transport Security header (HSTS) for user custom domains. This is a conscious decision as it can be misconfigured in a not easily reversible way. For both Read the Docs Community and Read the Docs for Business, HSTS for custom domains can be set upon request.

We always return the HSTS header with a max-age of at least one year for our own domains including *.readthedocs.io, *.readthedocs-hosted.com, readthedocs.org and readthedocs.com.

Troubleshooting

SSL certificate issue delays

The status of your domain validation and certificate can always be seen on the details page for your domain under Admin > Domains > YOURDOMAIN.TLD (details).

  • For Read the Docs Community, domains are usually validated and a certificate issued within minutes. However, if you setup the domain in Read the Docs without provisioning the necessary DNS changes and then update DNS hours or days later, this can cause a delay in validating because there is an exponential back-off in validation. Loading the domain details in the Read the Docs dashboard and saving the domain again will force a revalidation.

  • For Read the Docs for Business, domains can take up to a couple days to validate and issue a certificate. To avoid any downtime in moving a domain from somewhere else to Read the Docs, it is possible to validate the domain and provision the certificate before pointing your domain to Read the Docs.

Certificate authority authorization

Certificate authority authorization (CAA) is a security feature that allows domain owners to limit which certificate authorities (CAs) can issue certificates for a domain. This is done by setting CAA DNS records for your domain. CAA records are typically on the root domain, not subdomains since you can’t have a CNAME and CAA record for the same subdomain. Here’s an example for palletsprojects.com:

 dig CAA +short palletsprojects.com
0 issue "digicert.com"
0 issue "comodoca.com"
0 issue "letsencrypt.org"

If there are CAA records for your domain that do not allow the certificate authorities that Read the Docs uses, you may see an error message like pending_validation: caa_error: YOURDOMAIN.TLD in the Read the Docs dashboard for your domain. You will need to update your CAA records to allow us to issue the certificate.

  • For Read the Docs Community, we use Cloudflare which uses Digicert as a CA. See the Cloudflare CAA FAQ for details.

  • For Read the Docs for Business, we use AWS Certificate Manager as a CA. See the Amazon CAA guide for details.

Notes for Cloudflare DNS users

Due to a limitation between Read the Docs Community and Cloudflare, a domain cannot be proxied on Cloudflare to another Cloudflare account that also proxies. You will see a “CNAME Cross-User Banned” error in your Cloudflare dashboard and a requested hostname resolves to a Cloudflare zone that is not owned by you error in the Read the Docs dashboard. In order to do SSL termination, we must proxy this connection. If you don’t want us to do SSL termination for your domain — which means you are responsible for the SSL certificate — then set your CNAME to cloudflare-to-cloudflare.readthedocs.io instead of readthedocs.io. For more details, see this previous issue.

Proxy SSL

Warning

This option is deprecated, we already issue SSL certificates for all domains.

If you would prefer to do your own SSL termination on a server you own and control, you can do that although the setup is a bit more complex.

Broadly, the steps are:

  • Have a server listening on 443 that you control

  • Procure an SSL certificate for your domain and provision it and the private key on your server.

  • Add a domain that you wish to point at Read the Docs

  • Enable proxying to us, with a custom X-RTD-SLUG header

An example nginx configuration for pip would look like:

 server {
     server_name pip.pypa.io;
     location / {
         proxy_pass https://pip.readthedocs.io:443;
         proxy_set_header Host $http_host;
         proxy_set_header X-Forwarded-Proto https;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Scheme $scheme;
         proxy_set_header X-RTD-SLUG pip;
         proxy_connect_timeout 10s;
         proxy_read_timeout 20s;
     }
 }