Skip to content

Commit

Permalink
docs(guides/local-tls): dedicated guide for setting up local TLS (#7476)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori authored Sep 18, 2023
1 parent ddc022a commit 7f4168f
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 68 deletions.
117 changes: 117 additions & 0 deletions docs/guides/local-tls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
title: "Local TLS"
---

# Local TLS

It's simpler to use HTTP locally, but if you really need to use HTTPS locally, here's how to do it.

<docs-warning>

`remix-serve` does not support local HTTPS as its meant to be a minimal server to get you off the ground.
`remix-serve` is a simple wrapper around Express, so you can use Express directly if you want to use HTTPS locally.

If you are running `remix dev` without the `-c` flag, you are implicitly using `remix-serve` as your app server.

</docs-warning>

## Running your app server with local TLS

The first step is to get your app server running with local TLS _without_ running `remix dev`.
That will set you up for success when you setup `remix dev` with local TLS in the next section.

👉 Install [mkcert][mkcert]

👉 Create a local Certificate Authority:

```sh
mkcert -install
```

👉 Tell Node to use our local CA:

```sh
export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
```

👉 Create a TLS key and certificate:

```
mkcert -key-file key.pem -cert-file cert.pem localhost
```

<docs-info>

You can change `localhost` to something else when generating TLS keys and certificates if you are using custom hostnames.

</docs-info>

👉 Use the `key.pem` and `cert.pem` to get HTTPS working locally with your app server.

How you do this will depend on what app server you are using.
For example, here's how you could use HTTPS with an Express server:

```ts filename=server.js
import fs from "node:fs";
import https from "node:https";
import path from "node:path";

import express from "express";

const BUILD_DIR = path.resolve(__dirname, "build");
const build = require(BUILD_DIR);

const app = express();

// ... code setting up your express app goes here ...

const server = https.createServer(
{
key: fs.readFileSync("path/to/key.pem"),
cert: fs.readFileSync("path/to/cert.pem"),
},
app
);

const port = 3000;
server.listen(port, () => {
// ... code to run after your server is running goes here ...
});
```

👉 Run your app server with local TLS

For example, with the Express server above, you would run it like this:

```sh
remix build
node ./server.js
```

## Running `remix dev` with local TLS

Make sure you can run your app with local TLS without `remix dev` first!
Check out the previous section if you haven't done that yet.

👉 Enable TLS for `remix dev`

Via config:

```js filename=remix.config.js
module.exports = {
dev: {
tlsKey: "key.pem", // relative to cwd
tlsCert: "cert.pem", // relative to cwd
},
};
```

or via flags:

```sh
remix dev --tls-key=key.pem --tls-cert=cert.pem -c "node ./server.js"
```

Your app should now be running with local TLS!

[mkcert]: https://github.com/FiloSottile/mkcert#installation
68 changes: 0 additions & 68 deletions docs/other-api/dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,73 +213,6 @@ export const server = setupServer(
);
```

### How to set up local HTTPS

For this example, let's use [mkcert][mkcert].
After you have it installed, make sure to:

- Create a local Certificate Authority if you haven't already done so
- Use `NODE_EXTRA_CA_CERTS` for Node compatibility

```sh
mkcert -install # create a local CA
export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" # tell Node to use our local CA
```

Now, create the TLS key and certificate:

```sh
mkcert -key-file key.pem -cert-file cert.pem localhost
```

👆 You can change `localhost` to something else if you are using custom hostnames.

Next, use the `key.pem` and `cert.pem` to get HTTPS working locally with your app server.
This depends on what you are using for your app server.
For example, here's how you could use HTTPS with an Express server:

```ts filename=server.js
import fs from "node:fs";
import https from "node:https";
import path from "node:path";

import express from "express";

const BUILD_DIR = path.resolve(__dirname, "build");
const build = require(BUILD_DIR);

const app = express();

// ... code setting up your express app goes here ...

const server = https.createServer(
{
key: fs.readFileSync("path/to/key.pem"),
cert: fs.readFileSync("path/to/cert.pem"),
},
app
);

const port = 3000;
server.listen(port, () => {
console.log(`👉 https://localhost:${port}`);

if (process.env.NODE_ENV === "development") {
broadcastDevReady(build);
}
});
```

Now that the app server is set up, you should be able to build and run your app in production mode with TLS.
To get the Remix compiler to interop with TLS, you'll need to specify the TLS cert and key you created:

```sh
remix dev --tls-key=key.pem --tls-cert=cert.pem -c "node ./server.js"
```

Alternatively, you can specify the TLS key and cert via the `dev.tlsCert` and `dev.tlsKey` config options.
Now your app server and Remix compiler are TLS ready!

### How to integrate with a reverse proxy

Let's say you have the app server and Remix compiler both running on the same machine:
Expand Down Expand Up @@ -383,7 +316,6 @@ While the initial build slowdown is inherently a cost for HDR, we plan to optimi
[react-keys]: https://react.dev/learn/rendering-lists#why-does-react-need-keys
[react-refresh]: https://github.com/facebook/react/tree/main/packages/react-refresh
[msw]: https://mswjs.io/
[mkcert]: https://github.com/FiloSottile/mkcert
[path-imports]: https://mui.com/material-ui/guides/minimizing-bundle-size/#option-one-use-path-imports
[bundle-analysis]: ../guides/performance
[manual-mode]: ../guides/manual-mode

0 comments on commit 7f4168f

Please sign in to comment.