From 5444705a270453cbff3a704ab07d06a6933069a9 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Fri, 31 Mar 2023 10:17:50 -0400 Subject: [PATCH] docs(node): add recipe for deploying server to Fly.io --- docs/generated/manifests/menus.json | 25 ++++ docs/generated/manifests/recipes.json | 33 ++++- docs/generated/manifests/tags.json | 18 +++ docs/map.json | 15 +- .../node-server-tutorial/1-code-generation.md | 6 +- .../recipes/deployment/node-server-fly-io.md | 128 ++++++++++++++++++ 6 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 docs/shared/recipes/deployment/node-server-fly-io.md diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index e033a70c743b4..789a8e0fdc49d 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -2559,6 +2559,31 @@ "children": [], "disableCollapsible": false }, + { + "name": "Deployment", + "path": "/recipes/deployment", + "id": "deployment", + "isExternal": false, + "children": [ + { + "name": "Deploying a Node.js server to Fly.io", + "path": "/recipes/deployment/node-server-fly-io", + "id": "node-server-fly-io", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], + "disableCollapsible": false + }, + { + "name": "Deploying a Node.js server to Fly.io", + "path": "/recipes/deployment/node-server-fly-io", + "id": "node-server-fly-io", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Other", "path": "/recipes/other", diff --git a/docs/generated/manifests/recipes.json b/docs/generated/manifests/recipes.json index 097a186a399a3..c0ad3bee9e567 100644 --- a/docs/generated/manifests/recipes.json +++ b/docs/generated/manifests/recipes.json @@ -961,7 +961,7 @@ "/recipes/storybook": { "id": "storybook", "name": "Storybook", - "description": "Storybook how tos", + "description": "Storybook how tos.", "file": "", "itemList": [ { @@ -1029,6 +1029,37 @@ "path": "/recipes/storybook/one-storybook-with-composition", "tags": ["storybook"] }, + "/recipes/deployment": { + "id": "deployment", + "name": "Deployment", + "description": "Deployment recipes for Node.js and Deno server applications.", + "file": "", + "itemList": [ + { + "id": "node-server-fly-io", + "name": "Deploying a Node.js server to Fly.io", + "description": "", + "file": "shared/recipes/deployment/node-server-fly-io", + "itemList": [], + "isExternal": false, + "path": "/recipes/deployment/node-server-fly-io", + "tags": ["deployment", "node"] + } + ], + "isExternal": false, + "path": "/recipes/deployment", + "tags": [] + }, + "/recipes/deployment/node-server-fly-io": { + "id": "node-server-fly-io", + "name": "Deploying a Node.js server to Fly.io", + "description": "", + "file": "shared/recipes/deployment/node-server-fly-io", + "itemList": [], + "isExternal": false, + "path": "/recipes/deployment/node-server-fly-io", + "tags": ["deployment", "node"] + }, "/recipes/other": { "id": "other", "name": "Other", diff --git a/docs/generated/manifests/tags.json b/docs/generated/manifests/tags.json index 3699a22ac6e7a..caa837aab7d65 100644 --- a/docs/generated/manifests/tags.json +++ b/docs/generated/manifests/tags.json @@ -821,6 +821,24 @@ "path": "/recipes/storybook/one-storybook-with-composition" } ], + "deployment": [ + { + "description": "", + "file": "shared/recipes/deployment/node-server-fly-io", + "id": "node-server-fly-io", + "name": "Deploying a Node.js server to Fly.io", + "path": "/recipes/deployment/node-server-fly-io" + } + ], + "node": [ + { + "description": "", + "file": "shared/recipes/deployment/node-server-fly-io", + "id": "node-server-fly-io", + "name": "Deploying a Node.js server to Fly.io", + "path": "/recipes/deployment/node-server-fly-io" + } + ], "workspace-watching": [ { "description": "", diff --git a/docs/map.json b/docs/map.json index 7b79f97cf5a96..f5af614c0fe39 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1009,7 +1009,7 @@ { "name": "Storybook", "id": "storybook", - "description": "Storybook how tos", + "description": "Storybook how tos.", "itemList": [ { "name": "Publishing Storybook: One main Storybook instance for all projects", @@ -1031,6 +1031,19 @@ } ] }, + { + "name": "Deployment", + "id": "deployment", + "description": "Deployment recipes for Node.js and Deno server applications.", + "itemList": [ + { + "name": "Deploying a Node.js server to Fly.io", + "id": "node-server-fly-io", + "tags": ["deployment", "node"], + "file": "shared/recipes/deployment/node-server-fly-io" + } + ] + }, { "name": "Other", "id": "other", diff --git a/docs/shared/node-server-tutorial/1-code-generation.md b/docs/shared/node-server-tutorial/1-code-generation.md index 46b302354de51..75e709141fd2d 100644 --- a/docs/shared/node-server-tutorial/1-code-generation.md +++ b/docs/shared/node-server-tutorial/1-code-generation.md @@ -36,7 +36,7 @@ For this tutorial, you'll create an Express API application, a library that the Run the command `npx create-nx-workspace@latest` and when prompted, provide the following responses: ```{% command="npx create-nx-workspace@latest" path="~" %} -✔ Choose what to create · node-server +✔ Choose what to create · node-standalone ✔ Application name · products-api ✔ What framework should be used? · express ✔ Would you like to generate a Dockerfile? [https://docs.docker.com/] · Yes @@ -45,10 +45,10 @@ Run the command `npx create-nx-workspace@latest` and when prompted, provide the {% card title="Opting into Nx Cloud" description="You will also be prompted whether to add Nx Cloud to your workspace. We won't address this in this tutorial, but you can see the introduction to Nx Cloud for more details." url="/nx-cloud/intro/what-is-nx-cloud" /%} -The `node-server` preset automatically creates a `products-api` application at the root of the workspace and an `e2e` project that runs against it. +The `node-standalone` preset automatically creates a `products-api` application at the root of the workspace and an `e2e` project that runs against it. {% callout type="note" title="Framework Options" %} -This tutorial uses the `express` framework. The `node-server` preset also provides starter files for `koa` and `fastify`. +This tutorial uses the `express` framework. The `node-standalone` preset also provides starter files for `koa` and `fastify`. For other frameworks, you can choose `none` and add a it yourself. {% /callout %} ## Generating Libraries diff --git a/docs/shared/recipes/deployment/node-server-fly-io.md b/docs/shared/recipes/deployment/node-server-fly-io.md new file mode 100644 index 0000000000000..9eb230a79e678 --- /dev/null +++ b/docs/shared/recipes/deployment/node-server-fly-io.md @@ -0,0 +1,128 @@ +# Deploying a Node.js server to Fly.io + +In this guide, we'll show you how to go from zero to production using Nx and Node.js server support. We'll use [Fastify](https://www.fastify.io/) as the frameworks of choice, but you can also use [Express](https://expressjs.com/) and [Koa](https://koajs.com/) by selecting those frameworks during project creation. We'll also cover how to configure the same setup for existing Node.js projects. + +**Prefer a video version? Watch this short video to learn how to start a Node.js server project with Nx.** + +{% youtube +src="https://www.youtube.com/embed/K4f-fMuAoRY" +title="Build Node backends - The Easy Way!" +width="100%" /%} + +## Creating the project + +You can create a new server project with a single command. + +```bash +npx create-nx-workspace@latest my-api \ + --preset=node-standalone \ # create a Node.js project + --framework=fastify \ # other options are express and koa + --docker # generates a Dockerfile (we'll need this) +``` + +Once the command is finished, you can `cd` into the workspace. + +```bash +cd my-api +``` + +To run the server, use `nx serve` and the server should start on `http://localhost:3333`. You can also run the e2e tests against the running server by running `nx e2e e2e` in a separate tab. Note that the `e2e` project is separate from the server project, thus the need to specify it in the `nx e2e ` command. + +For existing projects, see the next section, otherwise you can skip to [deployment](#deploying-the-server-to-fly.io). + +### Configure existing projects + +**Skip this step if you are not configuring an exist project.** + +If you have an existing Node.js server project, you can add the same deployment capabilities as we've just covered. Firstly, if the project is not an Nx project you can initialize it as such by running the `npx nx init` command in your project. Next, we can add the `build` and `docker-build` targets by invoking a couple of generators. + +You will need to install `@nrwl/node` and `@nrwl/esbuild` if you haven't already. + +{% tabs %} +{% tab label="npm" %} + +```bash +npm i -D @nrwl/node @nrwl/esbuild +``` + +{% /tab %} +{% tab label="yarn" %} + +```bash +yarn add -D @nrwl/node @nrwl/esbuild +``` + +{% /tab %} +{% tab label="pnpm" %} + +```bash +pnpm add -D @nrwl/node @nrwl/esbuild +``` + +{% /tab %} +{% /tabs %} + +Now, set up the build and Docker targets with these commands. You will be prompted to select the project to configure. + +```bash +# Add build target +# You can skip this step if your project already has a build target. +nx g @nrwl/esbuild:esbuild-project --skipValidation + +# Add Dockerfile +nx g @nrwl/node:setup-docker +``` + +You are now ready to deploy the project. + +## Deploying the server to Fly.io + +Recall that a `Dockerfile` has been created for our project. If you missed the Docker setup, you can always run the `nx g @nrwl/node:setup-docker` command to generate the `Dockerfile`. + +Now, all we need to do is set up Fly.io and deploy! If you haven't used Fly.io before, you need to install the CLI and create an account. It'll only take a couple of minutes. + +1. [Install flyctl](https://fly.io/docs/hands-on/install-flyctl/) - This is the Fly.io CLI. +2. Create an account with `fly auth signup` or `fly auth login`. + +If you run into any issues, please refer to their [getting started guide](https://fly.io/docs/speedrun/). + +Once you have authenticated using `fly`, we are ready to launch our project. + +```bash +fly launch --generate-name --no-deploy +``` + +Follow the prompts and a `fly.toml` file will be generated, which contains the Fly.io configuration. We need to update this file with the correct port used by our image. + +``` +[[services]] +http_checks = [] +internal_port = 3000 # Make sure this matches the port in Dockerfile +``` + +Now we can build and deploy the server. + +```bash +nx build +fly deploy +``` + +Fly.io will log out the monitoring link when the server is successfully deployed. You can open the server in a browser using the `fly open` command. + +That's is! Our server is now deployed for the world to use. + +{% callout type="note" title="Adding deploy command" %} +You can add a `deploy` target to the project by add this to the `project.json` file (under `"targets"`). + +```json +"deploy": { + "dependsOn": [ + "build" + ], + "command": "fly deploy" +} +``` + +Then you can run `nx deploy`, which will run the build (if necessary) before deploying. + +{% /callout %}