From 91aa32161befb3099ca7b8904f182a0ca52421c8 Mon Sep 17 00:00:00 2001 From: Rares Matei Date: Wed, 5 Jul 2023 13:29:35 +0100 Subject: [PATCH] docs(nx-cloud): ami deplopyment docs (#17865) --- docs/generated/manifests/cloud.json | 64 ++-- docs/generated/manifests/menus.json | 50 +-- docs/map.json | 19 +- docs/nx-cloud/private/ami-setup.md | 170 ++++++++++ docs/nx-cloud/private/get-started.md | 63 +++- .../private/images/nx-cloud-landing.png | Bin 0 -> 130714 bytes docs/nx-cloud/private/kubernetes-setup.md | 282 ---------------- docs/nx-cloud/private/standalone.md | 315 ------------------ docs/shared/reference/sitemap.md | 5 +- .../src/e2e/nx-cloud-documentation.cy.ts | 6 +- nx-dev/nx-dev/redirect-rules.js | 3 + 11 files changed, 277 insertions(+), 700 deletions(-) create mode 100644 docs/nx-cloud/private/ami-setup.md create mode 100644 docs/nx-cloud/private/images/nx-cloud-landing.png delete mode 100644 docs/nx-cloud/private/kubernetes-setup.md delete mode 100644 docs/nx-cloud/private/standalone.md diff --git a/docs/generated/manifests/cloud.json b/docs/generated/manifests/cloud.json index 7640ebc9a2..2c4a81f9ef 100644 --- a/docs/generated/manifests/cloud.json +++ b/docs/generated/manifests/cloud.json @@ -234,8 +234,8 @@ }, "/nx-cloud/private-cloud": { "id": "private-cloud", - "name": "On Prem", - "description": "Learn about Nx Cloud On Premise, dedicated Nx Cloud application hosted on your server, in your network with total private access.", + "name": "Enterprise + On Prem", + "description": "Learn about Nx Cloud Enterprise + On-Prem.", "file": "", "itemList": [ { @@ -268,6 +268,16 @@ "path": "/nx-cloud/private-cloud/auth-github", "tags": [] }, + { + "id": "ami-setup", + "name": "On-Prem VM Setup", + "description": "", + "file": "nx-cloud/private/ami-setup", + "itemList": [], + "isExternal": false, + "path": "/nx-cloud/private-cloud/ami-setup", + "tags": [] + }, { "id": "auth-gitlab", "name": "Authenticate with GitLab", @@ -307,26 +317,6 @@ "isExternal": false, "path": "/nx-cloud/private-cloud/advanced-config", "tags": [] - }, - { - "id": "kubernetes-setup", - "name": "Kubernetes Setup", - "description": "", - "file": "nx-cloud/private/kubernetes-setup", - "itemList": [], - "isExternal": false, - "path": "/nx-cloud/private-cloud/kubernetes-setup", - "tags": [] - }, - { - "id": "standalone", - "name": "Standalone", - "description": "", - "file": "nx-cloud/private/standalone", - "itemList": [], - "isExternal": false, - "path": "/nx-cloud/private-cloud/standalone", - "tags": [] } ], "isExternal": false, @@ -363,6 +353,16 @@ "path": "/nx-cloud/private-cloud/auth-github", "tags": [] }, + "/nx-cloud/private-cloud/ami-setup": { + "id": "ami-setup", + "name": "On-Prem VM Setup", + "description": "", + "file": "nx-cloud/private/ami-setup", + "itemList": [], + "isExternal": false, + "path": "/nx-cloud/private-cloud/ami-setup", + "tags": [] + }, "/nx-cloud/private-cloud/auth-gitlab": { "id": "auth-gitlab", "name": "Authenticate with GitLab", @@ -403,26 +403,6 @@ "path": "/nx-cloud/private-cloud/advanced-config", "tags": [] }, - "/nx-cloud/private-cloud/kubernetes-setup": { - "id": "kubernetes-setup", - "name": "Kubernetes Setup", - "description": "", - "file": "nx-cloud/private/kubernetes-setup", - "itemList": [], - "isExternal": false, - "path": "/nx-cloud/private-cloud/kubernetes-setup", - "tags": [] - }, - "/nx-cloud/private-cloud/standalone": { - "id": "standalone", - "name": "Standalone", - "description": "", - "file": "nx-cloud/private/standalone", - "itemList": [], - "isExternal": false, - "path": "/nx-cloud/private-cloud/standalone", - "tags": [] - }, "/nx-cloud/reference": { "id": "reference", "name": "Reference", diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index ccf379a5e7..1aef7726d7 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -3960,7 +3960,7 @@ "disableCollapsible": false }, { - "name": "On Prem", + "name": "Enterprise + On Prem", "path": "/nx-cloud/private-cloud", "id": "private-cloud", "isExternal": false, @@ -3989,6 +3989,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "On-Prem VM Setup", + "path": "/nx-cloud/private-cloud/ami-setup", + "id": "ami-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Authenticate with GitLab", "path": "/nx-cloud/private-cloud/auth-gitlab", @@ -4020,22 +4028,6 @@ "isExternal": false, "children": [], "disableCollapsible": false - }, - { - "name": "Kubernetes Setup", - "path": "/nx-cloud/private-cloud/kubernetes-setup", - "id": "kubernetes-setup", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Standalone", - "path": "/nx-cloud/private-cloud/standalone", - "id": "standalone", - "isExternal": false, - "children": [], - "disableCollapsible": false } ], "disableCollapsible": false @@ -4064,6 +4056,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "On-Prem VM Setup", + "path": "/nx-cloud/private-cloud/ami-setup", + "id": "ami-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Authenticate with GitLab", "path": "/nx-cloud/private-cloud/auth-gitlab", @@ -4096,22 +4096,6 @@ "children": [], "disableCollapsible": false }, - { - "name": "Kubernetes Setup", - "path": "/nx-cloud/private-cloud/kubernetes-setup", - "id": "kubernetes-setup", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Standalone", - "path": "/nx-cloud/private-cloud/standalone", - "id": "standalone", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, { "name": "Reference", "path": "/nx-cloud/reference", diff --git a/docs/map.json b/docs/map.json index b3b6ccb843..fe9595f79b 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1540,9 +1540,9 @@ ] }, { - "name": "On Prem", + "name": "Enterprise + On Prem", "id": "private-cloud", - "description": "Learn about Nx Cloud On Premise, dedicated Nx Cloud application hosted on your server, in your network with total private access.", + "description": "Learn about Nx Cloud Enterprise + On-Prem.", "itemList": [ { "name": "Get Started", @@ -1559,6 +1559,11 @@ "id": "auth-github", "file": "nx-cloud/private/auth-github" }, + { + "name": "On-Prem VM Setup", + "id": "ami-setup", + "file": "nx-cloud/private/ami-setup" + }, { "name": "Authenticate with GitLab", "id": "auth-gitlab", @@ -1578,16 +1583,6 @@ "name": "Advanced Configuration", "id": "advanced-config", "file": "nx-cloud/private/advanced-config" - }, - { - "name": "Kubernetes Setup", - "id": "kubernetes-setup", - "file": "nx-cloud/private/kubernetes-setup" - }, - { - "name": "Standalone", - "id": "standalone", - "file": "nx-cloud/private/standalone" } ] }, diff --git a/docs/nx-cloud/private/ami-setup.md b/docs/nx-cloud/private/ami-setup.md new file mode 100644 index 0000000000..a52939dbfc --- /dev/null +++ b/docs/nx-cloud/private/ami-setup.md @@ -0,0 +1,170 @@ +# Setting up a dedicated NxCloud VM + +## AWS EC2 + +1. Login to your AWS Console and select [the top image published here](https://console.aws.amazon.com/ec2/v2/home?home#Images:visibility=public-images;imageName=nx-cloud;owner=623002322076;sort=desc:imageName) +2. Launch a new instance from that AMI +3. Recommended instance type: `t3.2xlarge` +4. You will need to SSH into the instance once it's created: + - Use an existing SSH key-pair that you already have installed locally. + - [Or create a new one and download the keys locally](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html?icmpid=docs_ec2_console#having-ec2-create-your-key-pair) + - Then select your new SSH pair from the list +5. Networking: + - Allow the instance to receive HTTP and HTTPS traffic + - Allow SSH from your current IP +6. Leave the storage options as they are +7. "Launch instance" +8. Wait 10 minutes, then navigate to your instance's IP in the browser. You should see the NxCloud dashboard! + +![NxCloud landing page](/nx-cloud/private/images/nx-cloud-landing.png) + +### Your NxCloud URL + +1. At this point, your instance will have a public IP accessible from the browser. + - You can consider this IP the URL of NxCloud, and proceed with the below steps and all will work fine! +2. You might want, however, to add a Load Balancer in front of the instance, with an explicit domain (e.g. https://my-nxcloud.my-org.com). + - This is strongly recommended because you will be able to upgrade/restart/re-configure your NxCloud EC2 instance while keeping the NxCloud URL static. + - Create an [application load balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-application-load-balancer.html) + - You will need to create a certificate for your domain to assign to the LB + - And you will need to target your EC2 instance from the LB + - You should now have a permanent domain pointing to your NxCloud instance + +Once you have your NxCloud URL proceed to the below steps! + +### Configuring your NxCloud instance + +1. Create a new `myconfiguration.yaml` file with the below contents + +```yaml +# This is all you need to get the baseline of your nx-cloud instance configured! + +# Set the external URL your instance is running on. This is the URL from the previous step +nxCloudAppURL: 'https://nx-cloud.on.my-domain.ca' + +secret: + # set your initial admin password for logging into the app + adminPassword: 'correcthorsebatterystaple' +``` + +2. Apply the configuration: + +```bash +scp -r ./myconfiguration.yaml nx-cloud@:~/config/user/update.yaml +``` + +That's it! After a few minutes, you should be able to log-in with: + +- username: `admin` +- password: `` + +### Applying the license + +Once you log-in, you will see an organisation has been created for you. + +1. You can rename it or create a new organization. +2. Navigate to your new organization's page and send us it's id + - It should look something like this: https://your-url.com/orgs/649f240f7fb955000c1fd10b/workspaces +3. We will then give you a License Key which you can apply on your org's billing page + +### Connecting to your NxCloud instance + +In your Nx workspace, you can enable NxCloud by running: + +```bash +NX_CLOUD_API="https://nx-cloud.on.my-domain.ca" npx nx connect +``` + +If it doesn't work, there might be an issue with unrecognized certificates on your instance. You can try running with: + +```bash +NODE_TLS_REJECT_UNAUTHORIZED=0 NX_CLOUD_API="https://nx-cloud.on.my-domain.ca" npx nx connect +``` + +Although we have [a full guide here](https://github.com/nrwl/nx-cloud-helm/blob/main/PROXY-GUIDE.md#nxcloud-runner-proxy-issues) for dealing with self-signed certificates. + +### Advanced configuration and auth + +You can optionally enable authentication using your preferred SSO provider: + +- GitHub +- Bitbucket +- GitLab +- SAML (Okta, Azure AD etc.) + +```yaml +# This is all you need to get the baseline of your nx-cloud instance configured! + +# only use this if you'd like to use any of the newer NxCloud version from here: https://nx.dev/nx-cloud/reference/release-notes#docker-containers +# global.imageTag: '' + +# Set the external URL your instance is running on +nxCloudAppURL: 'https://nx-cloud.on.my-domain.ca' + +# Uncomment (along with github secrets below) to enable working with GitHub pull requests or github auth +#github: +# auth: +# enabled: false +# pr: +# apiUrl: '' # this is only needed if you have a self-hosted github instance + +#gitlab: +# apiUrl: '' # this is only needed if you have a self-hosted gitlab instance +# auth: +# enabled: false + +# we do not support self-hosted bitbucket instances +#bitbucket: +# auth: +# enabled: false + +#saml: +# auth: +# enabled: false + +# Provide plaintext values for your application to use. We will extract them, +# store them within the application runtime, and scrub the plaintext ones from +# the filesystem +secret: + # set your initial admin password for logging into the app + # see here: https://nx.dev/nx-cloud/private-cloud/auth-single-admin + adminPassword: 'correcthorsebatterystaple' + + # If you want to enable GitHub Login, just provide your client id & secret, we handle the rest + # see here: https://nx.dev/nx-cloud/private-cloud/auth-github + githubAuthClientId: 'my_client_id' + githubAuthClientSecret: 'my_client_secret' + + # The same goes for GitLab authentication + # see here: https://nx.dev/nx-cloud/private-cloud/auth-gitlab + # gitlabAppId: 'my_gitlab_app_id' + # gitlabAppSecret: 'my_gitlab_app_secret' + + # Bitbucket too! If these are uncommented, BB auth is automatically enabled + # see here: https://nx.dev/nx-cloud/private-cloud/auth-bitbucket + # bitbucketAppId: 'bitbucket_app_id' + # bitbucketAppSecret: 'bitbucket_app_secret' + + # SAML auth + # see here: https://nx.dev/nx-cloud/private-cloud/auth-saml + # samlEntryPoint: 'your_saml_entry_point' + # samlCert: 'saml_cert' +``` + +### Upgrades + +We send out emails with every new NxCloud release to all our Enterprise customers: + +1. You can view your current version at the `/version` route: https://your-nx-cloud-url.com/version +2. [And these are the latest NxCloud releases](https://nx.dev/nx-cloud/reference/release-notes#docker-containers) + +To upgrade to a newer version, add the below line to your `myconfiguration.yml` file: + +```yaml +global.imageTag: '2306.01.2' # set the version of nx-cloud you'd like +``` + +And apply the changes: + +```bash +scp -r ./myconfiguration.yaml nx-cloud@:~/config/user/update.yaml +``` diff --git a/docs/nx-cloud/private/get-started.md b/docs/nx-cloud/private/get-started.md index 5348dfb5be..f24f788548 100644 --- a/docs/nx-cloud/private/get-started.md +++ b/docs/nx-cloud/private/get-started.md @@ -1,23 +1,62 @@ -# Running Nx Cloud on Prem +# Running Nx Cloud Enterprise -Nx Cloud can be deployed to your cloud, which gives you full control of your data, with no external API calls. +We offer multiple ways of running NxCloud for our Enterprise customers. The below options are listed in recommended order, from easiest to most complex in +terms of set-up and maintenance for your team. Please carefully consider your organization's requirements and level of infrastructure expertise before deciding on +a deployment option. -This solution is included as part of the Nx Enterprise package. You can learn more about it at [nx.app/enterprise](https://nx.app/enterprise). +Also, please make sure to [get in touch with us first](https://nx.app/enterprise?utm_source=nx.dev) so we can start creating an Enterprise package +that best fits your needs, and discuss any questions you might have! -Nx Cloud can be deployed in two ways: +## Clusters managed by us -- Using Kubernetes (several containers working together) -- Using a single standalone container (NOT RECOMMENDED) +### Multi-tenant -The flags and the capabilities are the same between the two, but the Kubernetes setup is more robust and better -documented. +The quickest way and easiest way to get up and running with NxCloud is using one of our existing secure, multi-tenant managed clusters: + +- https://nx.app/ +- Or, if you'd like all of your data to be hosted in Europe, you can use https://eu.nx.app/ + +You get the same level of security, dedicated support, SSO/SAML auth options and predictable seat-based pricing as all our other hosting options, but you won't have +to manage the instance yourself. + +We also offer an uptime SLA guarantee of 99.98% for our Enterprise customers, SOC certificates on request, and we're happy to meet with your security teams if they +have questions, or fill in security questionnaires. We also maintain a [Status Page here](https://status.nx.app/). + +To start with this option, it's as easy as running `npx nx connect` in your Nx workspace! + +### Single-tenant instance + +If you have very specific requirements, then we can also offer to host NxCloud for you in an isolated/single-tenant cluster. + +We'll be able to discuss specific requirements such as: + +- Specific regions you want your data to be in +- Network isolation / dedicated VPCs +- Dedicated instances +- Storage encryption +- Storage replication / redundancy + +This would be a "best of both worlds" option, as it would free you up from managing the instance yourself, but you will get to define specific parameters of how it should it run. +Your data and the NxCloud will run in complete isolation and will only serve your company. There will be no external API calls to any services outside of the cluster we set-up for you. + +Once you let us know you'd like this option, depending on the agreed requirements, it might take a few days to get it set up. + +## On-prem, managed by your organization + +#### Self-contained VM + +If you would like to host NxCloud yourself, within your organization's infrastructure, the easiest way to set it up is as a self-contained VM. + +Refer to our ["Self-contained VM" guide](/nx-cloud/private-cloud/ami-setup) for instructions on running NxCloud on Amazon EC2. + +#### Multi-node setup with Kubernetes + +The options above remove most of the maintenance burden required on your part, so we strongly recommend them! They also don't require too much infrastructure expertise. + +We do offer, however, a multi-node Kubernetes setup, that is deployed via Helm. You can head over to our [Helm repository](https://github.com/nrwl/nx-cloud-helm/) to explore this option. ## Resources -- [Kubernetes Setup Instructions](/nx-cloud/private-cloud/kubernetes-setup) -- [Nx Cloud K8s Example + All Config Options](https://github.com/nrwl/nx-cloud-helm) -- [Nx Cloud K8s Example + All Config Options (no Helm)](https://github.com/nrwl/nx-cloud-helm/tree/main/no-helm) -- [Standalone Container](/nx-cloud/private-cloud/standalone) - [GitHub PR Integration](/nx-cloud/set-up/github) - [Auth (Basic)](/nx-cloud/private-cloud/auth-single-admin) - [GitHub Auth](/nx-cloud/private-cloud/auth-github) diff --git a/docs/nx-cloud/private/images/nx-cloud-landing.png b/docs/nx-cloud/private/images/nx-cloud-landing.png new file mode 100644 index 0000000000000000000000000000000000000000..f5d3d9dcc0e43bb7f7f68f1f48858f2fb779701f GIT binary patch literal 130714 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 literal 0 HcmV?d00001 diff --git a/docs/nx-cloud/private/kubernetes-setup.md b/docs/nx-cloud/private/kubernetes-setup.md deleted file mode 100644 index 330e694d79..0000000000 --- a/docs/nx-cloud/private/kubernetes-setup.md +++ /dev/null @@ -1,282 +0,0 @@ -# Set Up Nx Cloud on Kubernetes - -A lot of organizations deploy Nx Cloud to Kubernetes. - -This guide references the [nx-cloud-helm](https://github.com/nrwl/nx-cloud-helm) repo which contains: - -- Nx Cloud Helm Chart -- Instructions on how to install Nx Cloud using Helm -- Instructions on how to install Nx Cloud using kubectl. See [here](https://github.com/nrwl/nx-cloud-helm/blob/main/no-helm/README.md). - -## Deployments on AWS/EKS - -If you're deploying on EKS, check out our [AWS Guide](https://github.com/nrwl/nx-cloud-helm/blob/main/aws-guide/AWS-GUIDE.md). Otherwise, continue reading below. - -## Installing Using Helm - -Steps: - -1. Deploy MongoDB Kubernetes Operator - - using helm: https://github.com/mongodb/helm-charts - - using kubectl: https://github.com/mongodb/mongodb-kubernetes-operator -2. Create a mongodb replica set -3. Create a secret -4. Install Nx Cloud using helm - -### Step 1: Deploy MongoDB Kubernetes Operator - -If you are using a hosted MongoDB installation (e.g., Mongo Atlas or CosmosSB, or you are running one yourself), you can -skip steps 1 and 2. - -``` -> helm repo add mongodb https://mongodb.github.io/helm-charts -> helm install community-operator mongodb/community-operator -``` - -### Step 2: Deploy a MongoDB replica set - -``` -> kubectl apply -f examples/mongodb.yml -``` - -This will create a secret. You can get the value of the secret as follows: - -> kubectl get secret cloud-mongodb-nrwl-api-admin-user -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"n"}}{{$v|base64decode}}{{"nn"}}{{end}}' - -You might need to wait a bit for the Pods to be created before this secret will be available. - -The output of the command can be a bit confusing (you are only interested in the second part of the output). The default connection string for the Mongo Community Operator will look like -this: `mongodb+srv://admin-user:DB_PASSWORD@cloud-mongodb-svc.default.svc.cluster.local/nrwl-api?replicaSet=cloud-mongodb&ssl=false` -. You should be able to use this value. - -Take this connection string and paste it into your `examples/secret.yml`, replacing the placeholder value. - -### Step 3: Create a secret - -With the values updated, create a secret by running `kubectl apply -f examples/secret.yml` - -### Step 4: Install Nx Cloud using helm - -``` -> helm repo add nx-cloud https://nrwl.github.io/nx-cloud-helm -> helm install nx-cloud nx-cloud/nx-cloud --values=overrides.yml -``` - -`examples/overrides` contains the min overrides files. You need to provision: - -1. The image tag you want to install -2. `nxCloudAppURL` which is the url used to access ingress from CI and dev machines ( - e.g., `https://nx-cloud.myorg.com`). -3. `secret/name` the name of the secret you created in Step 3. -4. `secret/nxCloudMongoServerEndpoint`, the name of the key from the secret. - 5`secret/adminPassword`, the name of the key from the secret. - -If you only applied the secret from Step 3, the only thing you will need to change is `nxCloudAppURL`. - -## Cloud Containers - -The installation will create the following: - -1. nx-cloud-frontend (deployment) -2. nx-cloud-api (deployment) -3. nx-cloud-nx-api (deployment) -4. nx-cloud-file-server (deployment) -5. nx-cloud-aggregator (cron job) - -## Ingress, IP, Certificates - -You can configure Ingress. For instance, the following will see the ingress class to 'gce', the global static ip name -to 'nx-cloud-ip', and will set a global Google managed certificate. - -```yaml -image: - tag: 'latest' - -nxCloudAppURL: 'https://nx-cloud.myorg.com' - -ingress: - class: 'gce' - globalStaticIpName: 'nx-cloud-ip' - managedCertificates: 'cloud-cert' - -secret: - name: 'cloud' - nxCloudMongoServerEndpoint: 'NX_CLOUD_MONGO_SERVER_ENDPOINT' - adminPassword: 'ADMIN_PASSWORD' -``` - -This configuration will look different for you. You will have a different global static ip and your cert name will also -be different. If you are interested in creating the two using GKE, check out the following links: - -- [Reserving a static external IP address](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address) -- [Using Google-managed SSL certificates](https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs) - -If you aren't using GKE, `ingress.class` will also be different. For example, see [our example config for AWS](https://github.com/nrwl/nx-cloud-helm/blob/main/aws-guide/helm-values.yml#L7) or check out the AWS Load Balancer set-up section [here for AWS set-up instructions.](https://github.com/nrwl/nx-cloud-helm/blob/main/aws-guide/AWS-GUIDE.md#3-install-a-load-balancer) - -If you need to have a detailed Ingress configuration, you can tell the package to skip defining ingress: - -```yaml -image: - tag: 'latest' - -nxCloudAppURL: 'https://nx-cloud.myorg.com' - -ingress: - skip: true -``` - -⤵️ and then define it yourself - -```yaml -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: nx-cloud-ingress - annotations: - - labels: - app: nx-cloud -spec: - rules: - - http: - paths: - # define the next /file section only if you use the built-in file server - - path: /file - pathType: Prefix - backend: - service: - name: nx-cloud-file-server-service - port: - number: 5000 - - path: /nx-cloud - pathType: Prefix - backend: - service: - name: nx-cloud-nx-api-service - port: - number: 4203 - - path: /api - pathType: Prefix - backend: - service: - name: nx-cloud-nrwl-api-service - port: - number: 4000 - - path: /graphql - pathType: Prefix - backend: - service: - name: nx-cloud-nrwl-api-service - port: - number: 4000 - - path: /auth - pathType: Prefix - backend: - service: - name: nx-cloud-nrwl-api-service - port: - number: 4000 - - path: /download - pathType: Prefix - backend: - service: - name: nx-cloud-nrwl-api-service - port: - number: 4000 - - path: /download - - pathType: Prefix - backend: - service: - name: nx-cloud-frontend-service - port: - number: 8080 -``` - -### Step 5: Connect Your Workspace - -Run `NX_CLOUD_API=https://nx-cloud.myorg.com nx connect`. Click on the link to connect the workspace -to your admin account. - -## Variations - -### External File Storage - -If you use AWS or Azure, you can configure Nx Cloud to store cached artifacts on S3 or Azure Blob. In this case, you -won't need the PVC or the file-server container. S3 and Azure Blob also tend to be faster. - -For S3 buckets, see the [AWS Guide](https://github.com/nrwl/nx-cloud-helm/blob/main/aws-guide/AWS-GUIDE.md#6-external-s3-access) - -For Azure: - -```yaml -image: - tag: 'latest' - -nxCloudAppURL: 'https://nx-cloud.myorg.com' - -azure: - enabled: true - container: 'nx-cloud' - -secret: - name: 'cloudsecret' - nxCloudMongoServerEndpoint: 'NX_CLOUD_MONGO_SERVER_ENDPOINT' - adminPassword: 'ADMIN_PASSWORD' - azureConnectionString: 'AZURE_CONNECTION_STRING' -``` - -Note that the secret for setting up Azure must contain `AZURE_CONNECTION_STRING`. - -### GitHub Auth - -To use GitHub for user authentication, you can use the following configuration: - -```yaml -image: - tag: 'latest' - -nxCloudAppURL: 'https://nx-cloud.myorg.com' - -github: - auth: - enabled: true - -secret: - name: 'cloudsecret' - nxCloudMongoServerEndpoint: 'NX_CLOUD_MONGO_SERVER_ENDPOINT' - githubAuthClientId: 'GITHUB_AUTH_CLIENT_ID' - githubAuthClientSecret: 'GITHUB_AUTH_CLIENT_SECRET' -``` - -Note that the secret must contain `GITHUB_AUTH_CLIENT_ID` and `GITHUB_AUTH_CLIENT_SECRET`. -Read [here](https://nx.dev/nx-cloud/private-cloud/auth-github) on how to get those values. - -### GitHub Integration - -To enable the GitHub PR integration, you can use the following configuration: - -```yaml -image: - tag: 'latest' - -nxCloudAppURL: 'https://nx-cloud.myorg.com' - -github: - pr: - enabled: true - # apiUrl: '' uncomment when using github enterprise - -secret: - name: 'cloudsecret' - nxCloudMongoServerEndpoint: 'NX_CLOUD_MONGO_SERVER_ENDPOINT' - githubWebhookSecret: 'GITHUB_WEBHOOK_SECRET' - githubAuthToken: 'GITHUB_AUTH_TOKEN' -``` - -Note that the secret must contain `GITHUB_WEBHOOK_SECRET` and `GITHUB_AUTH_TOKEN`. -Read [here](https://nx.dev/nx-cloud/private-cloud/github) on how to get those values. - -## More Information - -You can find more information about Nx Cloud and running it on -prem [here](https://nx.dev/nx-cloud/private-cloud/get-started). diff --git a/docs/nx-cloud/private/standalone.md b/docs/nx-cloud/private/standalone.md deleted file mode 100644 index 7f1b34491a..0000000000 --- a/docs/nx-cloud/private/standalone.md +++ /dev/null @@ -1,315 +0,0 @@ -# Running a Standalone Container - -Nx Cloud can be deployed in two ways: - -- [Using Kubernetes](https://github.com/nrwl/nx-cloud-helm) (several containers working together) -- Using a single standalone container (NOT RECOMMENDED) - -The flags and the capabilities are the same between the two, but the Kubernetes setup is more robust and better -documented. This document covers the latter version. - -**Nx Cloud consists of 3 parts:** - -1. The stateless Nx Cloud service -2. MongoDB database -3. File server - -By default, the container created by the `nxprivatecloud/single-image` image will create two of them: the stateless Nx Cloud service, and the file server. Using a single container is the easiest way to set it up, but it isn't the most robust way to run Nx Cloud. - -You will then need to host the database separately: - -- Either by using a service such as Mongo Atlas -- Or running it yourself. For that, we created the `nxprivatecloud/nx-cloud-mongo` image. - -The instructions will go through running the embedded file server, and then, at the end, will talk about hosting your cached artefacts on an external service, such as Amazon S3. - -## Running Nx Cloud - -### Step 1: Pull the Image - -```shell -> docker pull nxprivatecloud/single-image -``` - -To update the version of Nx Cloud, pull the new version of the image and run it against the same mount (see -below). - -### Step 2: Create a Container - -Depending on how your infrastructure is set up, you can either run Nx Cloud using HTTPS or HTTP. If you have a -proxy/load-balancer in front of Nx Cloud, you will likely want to run Nx Cloud using HTTP (the -proxy/load-balancer will handle TLS). Otherwise, you will likely want to run Nx Cloud using HTTPS. - -**To create a container:** - -1. You will need to create a directory on the host machine where data will be stored. (_This is not necessary if you are - running the file server separately. See below._) -2. You will need to know the URL that the Nx Cloud installation can be accessed by (see `NX_CLOUD_APP_URL` below). - - `NX_CLOUD_APP_URL` should be accessible from your CI and dev machines. - - `NX_CLOUD_APP_URL` can be set with an HTTP or HTTPS url. In a case where you are using a proxy/load-balancer, you - can still put HTTPS (the url will be resolved by the proxy before hitting the app). - - `NX_CLOUD_APP_URL` is likely to be an external IP/domain of the load balancer. -3. If you are running Nx Cloud using HTTPS, you need to generate or obtain an SSL certificate and an SSL private - key. - -**Once you obtain all the needed information, you can run the following:** - -**Using HTTPS** - -```shell -> docker create --name cloud \ - - -p 443:8081 \ - -e CERT_KEY="$(cat ./tools/certs/key.pem)" \ - -e CERT="$(cat ./tools/certs/cert.pem)" \ - -e NX_CLOUD_APP_URL="https://cloud.myorg.com" \ - -e ADMIN_PASSWORD=admin \ - -v /data/private-cloud:/data nxprivatecloud/nxcloud:latest -``` - -**Using HTTP (no proxy)** - -```shell -> docker create --name cloud \ - - -p 80:8081 \ - -e NX_CLOUD_APP_URL="http://cloud.myorg.com" \ - -e ADMIN_PASSWORD=admin \ - -v /data/private-cloud:/data nxprivatecloud/nxcloud:latest -``` - -**Using HTTPS via proxy** - -```shell -> docker create --name cloud \ - -p 80:8081 \ - -e NX_CLOUD_APP_URL="https://cloud.myorg.com" \ - -e ADMIN_PASSWORD=admin \ - -v /data/private-cloud:/data nxprivatecloud/nxcloud:latest -``` - -**Let's see what those options mean:** - -- `443:8081` maps the internal port 8081 to 443, so it can be accessed in the browser without specifying the port. 80: - 8081 works the same way when you use HTTP instead of HTTPS. -- `CERT_KEY` and `CERT` contain the values of private key and cert. The file extensions of the cert and key files can be - different, but as long as they are in the PEM format (which is the case if you use, for instance, OpenSSL), the - command will work. -- `NX_CLOUD_APP_URL` is the URL the cloud can be accessed by (e.g., `https://nxcloud.privateurl.com`). **Important: - Unless you are experimenting, it won't be localhost. It has to be the URL that your CI and your developer machine can - reach. Also note, there is no trailing slash in the URL.** -- `ADMIN_PASSWORD` contains the password of the admin user. The admin user is created the first time you run cloud, you - can remove this env variable after that. Instead of an admin password, you can also - follow [the instructions here](/nx-cloud/private-cloud/auth-github) to set up GitHub auth. -- `-v /data/private-cloud:/data` sets up the volume where the data (the cached artefacts) is stored. `/data/private-cloud` refers to a folder - on your machine, `/data` is the shareable folder from the Docker image. - -### Step 3: Run the Container - -Once you create the container, you can start it using: - -```shell -> docker start cloud -``` - -Imagine `NX_CLOUD_APP_URL` is set to `https://nxcloud.privateurl.com`. - -Now, go to https://nxcloud.privateurl.com to see cloud running. You can log into the account -using `admin/ADMIN_PASSWORD`. - -### Step 4: Connect Your Workspace - -Run `NX_CLOUD_API=https://nxcloud.privateurl.com` nx connect. Click on the link to connect the workspace -to your admin account. - -### Optional step 5: set up GitHub auth - -Follow the [instructions here](/nx-cloud/private-cloud/auth-github) to set up GitHub OAuth authentication so you can -invite other members in your team to the workspace. - -### Optional step 6: set up GitHub Pull Request integration - -You can [optionally configure Nx Cloud](/nx-cloud/set-up/github) to post build stats directly on your GitHub -pull requests. - -### Optional step 7: Setting Up Proxy - -If your container cannot access `api.nrwl.io` directly and has to talk via a proxy, you can -add `-e HTTPS_PROXY="https://myproxy.myorg.com"` to the container creation command. - -## Running the Mongo Database - -Nx Cloud uses MongoDB to store its metadata. You will need to provision the `NX_CLOUD_MONGO_SERVER_ENDPOINT` env variable when -creating a container, like so: - -```shell --e NX_CLOUD_MONGO_SERVER_ENDPOINT="mongodb://domain-with-mongo:27017/nrwl-api" -``` - -By default, Nx Cloud requires Mongo 4.2+. If you are using an older version of Mongo (for instance, if you are using -Cosmos DB), please add - -```shell --e NX_CLOUD_USE_MONGO42=false -``` - -### Deploy Mongo on your Kubernetes engine or Docker VM - -See [here](https://github.com/nrwl/nx-cloud-helm/blob/main/MONGO-OPERATOR-GUIDE.md) for a full guide on running Mongo yourself. - -### Using CosmosDB - -If you are deploying to Azure, you might have access to CosmosDB. See here for more information. - -### Using Mongo Atlas - -[Mongo Atlas](https://mongodb.com/) is a great option for deploying MongoDB. - -## Using External File Storage - -By default, Nx Cloud is going to start a file server and store the cached artifacts in the provided volume. But -you can also configure Nx Cloud to use an external file storage. At the moment, only S3 and Azure Blob are -supported. - -### Using S3/Minio - -To configure S3 as a file storage, provision the `AWS_S3_ACCESS_KEY_ID`, `AWS_S3_SECRET_ACCESS_KEY`, and `AWS_S3_BUCKET` -env variables when creating the Nx Cloud docker container, like so: - -```shell --e AWS_S3_ACCESS_KEY_ID="SOMEKEY" --e AWS_S3_SECRET_ACCESS_KEY="SOMESECRETKEY" --e AWS_S3_BUCKET="nx-cache-bucket-name" -``` - -If you are using an accelerated bucket, add: `-e AWS_S3_ACCELERATED=true` - -If you are using a local S3 installation (e.g., Minio), you can set the endpoint as follows: - -```shell --e AWS_S3_ENDPOINT="https://local-installation.myorg.com" --e AWS_S3_ACCESS_KEY_ID="SOMEKEY" --e AWS_S3_SECRET_ACCESS_KEY="SOMESECRETKEY" --e AWS_S3_BUCKET="nx-cache-bucket-name" -``` - -{% callout type="note" title="On cache item expiration time" %} -Remember to -set [a cache item expiration time](https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-expire-general-considerations.html) -. The default is currently 4 weeks. If you would like to keep items for longer, for example for 8 weeks, please remember -to set the `NX_CACHE_EXPIRATION_PERIOD_IN_DAYS=56` env variable as well, so the container knows when to expire the Mongo -cache entries as well. -{% /callout %} - -### Using Azure - -To configure Azure Blob as a file storage, provision the `AZURE_CONNECTION_STRING`, `AZURE_CONTAINER` env variables when -creating the Nx Cloud docker container, like so: - -```shell --e AZURE_CONNECTION_STRING="SOME-CONNECTION-STRING" --e AZURE_CONTAINER="files" -``` - -To obtain the `AZURE_CONNECTION_STRING` value go to your "Storage Account" and click on "Access Keys". You will also -need to create a container in your storage account before starting the Nx Cloud container. - -If you use an external file storage solution, you don't have to provision the volume. - -{% callout type="note" title="Cache expiration time" %} -See note above about setting a cache expiration time. For Azure blob -storage, [see this guide](https://docs.microsoft.com/en-us/azure/cdn/cdn-manage-expiration-of-blob-content). -{% /callout %} - -## Configure Memory Limits - -By default, the Nx Cloud container is configured to run on an instance with 8GB of RAM. - -If you have a container with 4GB of RAM, you can decrease the memory limits by setting the following env variables: - -- `NX_CLOUD_FILE_SERVER_MEMORY_LIMIT=500` -- `NX_CLOUD_API_MEMORY_LIMIT=800` - -Example: - -```shell -> docker create --name cloud \ - -p 80:8081 \ - -e NX_CLOUD_APP_URL="https://cloud.myorg.com" \ - -e ADMIN_PASSWORD=admin \ - -e NX_CLOUD_FILE_SERVER_MEMORY_LIMIT=500 \ - -e NX_CLOUD_API_MEMORY_LIMIT=800 \ - -v /data/private-cloud:/data nxprivatecloud/nxcloud:latest -``` - -The right amount of RAM depends heavily on how you run Nx Cloud. - -- The `NX_CLOUD_FILE_SERVER_MEMORY_LIMIT` value is only relevant if you use the built-in file server. - -For instance, if you use S3 to store the cached artifacts, even 2GB might be sufficient. You can set the following limit: - -- `NX_CLOUD_API_MEMORY_LIMIT=800` - -If you run everything in the Nx Cloud container, then 5GB is much preferred. - -## Configure Artifact Expiration When Using Built-in File Server - -By default, the Nx Cloud container is going to remove cached artifacts after two weeks. You can change it by setting `NX_CACHE_EXPIRATION_PERIOD_IN_DAYS` when starting the container. - -Example: - -```shell -> docker create --name cloud \ - -p 80:8081 \ - -e NX_CLOUD_APP_URL="https://cloud.myorg.com" \ - -e ADMIN_PASSWORD=admin \ - -e NX_CACHE_EXPIRATION_PERIOD_IN_DAYS=5 \ - -v /data/private-cloud:/data nxprivatecloud/nxcloud:latest -``` - -## Self-Signed Certificates - -If you have a self-signed certificate, you will have to provision `NODE_EXTRA_CA_CERTS`. The env variable should point to a PEM file with either your certificate, or the root certificate your certificate was created from. Though this can be accomplished with a CLI command like `NODE_EXTRA_CA_CERTS=./tools/certs/cert.crt nx test myapp`, you will most likely want to configure it as a global env variable (for instance in your `.bashrc` file). - -A self-sign certificate registered in your OS won't be picked up by Node. Node requires you to provision `NODE_EXTRA_CA_CERTS`. - -## Migration guide from `nxprivatecloud/nxcloud` to `nxprivatecloud/single-image` - -The old version of our Docker image, `nxprivatecloud/nxcloud`, is no longer being maintained. This section will explain how to migrate to the new standalone image, `nxprivatecloud/single-image`. - -Unlike `nxprivatecloud/nx-cloud`, the `nxprivatecloud/single-image` container does not come with MongoDB included. This makes for a much simpler image, based on Alpine (and not Ubuntu), with less chances for security vulnerabilities. However, it does require you to connect to an external Mongo instance. Below we'll cover the two possible migration scenarios. - -#### You are connecting to an external Mongo instance - -If you are currently connecting to an external Mongo instance, then migrating to the new image is as simple as switching the Docker tag from `nxprivatecloud/nxcloud` to `nxprivatecloud/single-image`. All the other configuration options can stay the same. - -#### You are running Mongo inside the Docker image - -If you are currently relying on the image to host Mongo, we will need to move that to an external instance. - -##### Starting fresh with a dedicated Mongo instance - -1. We recommend setting up a dedicated Mongo host, on Atlas [as described above](#using-mongo-atlas). This means you will lose you current workspace set-up, but it is the easiest migration path and the most maintanable one. - 1. To do this, get the connection string from Mongo Atlas - 2. And configure the image with it: `-e NX_CLOUD_MONGO_SERVER_ENDPOINT="mongodb://domain-with-mongo:27017/nrwl-api"` - 3. That's it! -2. If you cannot use Atlas or Azure CosmosDB within your org, then you'll need to run our dedidcated Mongo Docker image. Instructions for this approach are described below. - -##### Migrating your data to a separate self-hosted Mongo instance - -1. When running the image, you are probably mapping to the host volume like this `-v /data/private-cloud:/data:Z` -2. That data folder is where the image stores all its persistent data that needs exist between restarts or updates of the image. Inside it you'll find: - - 1. In the old image (`nxprivatecloud/nx-cloud`): - 1. `/data/file-server`: if you are using the built-in file-server, this is where you'll find all the cached artefacts. If you are using an external S3 buckets this folder won't exist. - 2. `/data/mongo`: this is where Mongo stores all its files. - 2. In the new image (`nxprivatecloud/single-image`): - 1. `/data/file-server` (if using the built-in file-server, otherwise you don't need to map anything) - -3. Copy the contents of `/data/mongo` folder from the host where you previously used to run Mongo, to the new host where you'll run the dedicated Mongo image -4. Run Mongo as described [here](https://github.com/nrwl/nx-cloud-helm/blob/main/MONGO-OPERATOR-GUIDE.md) - 1. In there, you'll find instructions to map the `$PWD/mongo-data:/data/db` folder to your host - 2. Copy the data from Step 1. above into the new mapped folder above. -5. Get the connection string for the above image -6. Start your `nxprivatecloud/single-image` container with the `-e NX_CLOUD_MONGO_SERVER_ENDPOINT="mongodb://52.201.253.213:27017/?authSource=admin&directConnection=true"` env var -7. You can remove the `/data/mongo` folder from the `single-image` mapping (you will need to keep `/data/file-server` if you not using an external S3 bucket) diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 00974a9797..564e8aa500 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -256,16 +256,15 @@ - [Access Tokens](/nx-cloud/account/access-tokens) - [Security Scenarios](/nx-cloud/account/scenarios) - [End to End Encryption](/nx-cloud/account/encryption) - - [On Prem](/nx-cloud/private-cloud) + - [Enterprise + On Prem](/nx-cloud/private-cloud) - [Get Started](/nx-cloud/private-cloud/get-started) - [Authenticate with a Single Admin](/nx-cloud/private-cloud/auth-single-admin) - [Authenticate with GitHub](/nx-cloud/private-cloud/auth-github) + - [On-Prem VM Setup](/nx-cloud/private-cloud/ami-setup) - [Authenticate with GitLab](/nx-cloud/private-cloud/auth-gitlab) - [Authenticate with BitBucket](/nx-cloud/private-cloud/auth-bitbucket) - [Authenticate via SAML](/nx-cloud/private-cloud/auth-saml) - [Advanced Configuration](/nx-cloud/private-cloud/advanced-config) - - [Kubernetes Setup](/nx-cloud/private-cloud/kubernetes-setup) - - [Standalone](/nx-cloud/private-cloud/standalone) - [Reference](/nx-cloud/reference) - [Configuration Options](/nx-cloud/reference/config) - [nx-cloud CLI](/nx-cloud/reference/nx-cloud-cli) diff --git a/nx-dev/nx-dev-e2e/src/e2e/nx-cloud-documentation.cy.ts b/nx-dev/nx-dev-e2e/src/e2e/nx-cloud-documentation.cy.ts index adac08ba2b..4a49688215 100644 --- a/nx-dev/nx-dev-e2e/src/e2e/nx-cloud-documentation.cy.ts +++ b/nx-dev/nx-dev-e2e/src/e2e/nx-cloud-documentation.cy.ts @@ -36,7 +36,7 @@ describe('nx-dev: Nx Cloud section', () => { path: '/nx-cloud/account/encryption', }, { - title: 'Running Nx Cloud on Prem', + title: 'Running Nx Cloud Enterprise', path: '/nx-cloud/private-cloud/get-started', }, { @@ -51,6 +51,10 @@ describe('nx-dev: Nx Cloud section', () => { title: 'GitLab Auth', path: '/nx-cloud/private-cloud/auth-gitlab', }, + { + title: 'Setting up a dedicated NxCloud VM', + path: '/nx-cloud/private-cloud/ami-setup', + }, { title: 'BitBucket Auth', path: '/nx-cloud/private-cloud/auth-bitbucket', diff --git a/nx-dev/nx-dev/redirect-rules.js b/nx-dev/nx-dev/redirect-rules.js index 4142429452..eaa591dd3a 100644 --- a/nx-dev/nx-dev/redirect-rules.js +++ b/nx-dev/nx-dev/redirect-rules.js @@ -360,6 +360,9 @@ const nxCloudUrls = { '/nx-cloud/set-up/add-nx-cloud': '/core-features/share-your-cache', '/nx-cloud/set-up/set-up-caching': '/core-features/share-your-cache', '/nx-cloud/set-up/set-up-dte': '/core-features/distribute-task-execution', + '/nx-cloud/private-cloud/standalone': '/nx-cloud/private-cloud/ami-setup', + '/nx-cloud/private-cloud/kubernetes-setup': + '/nx-cloud/private-cloud/get-started', }; /**