+
+ Hello Variables - Index
+
+ Hello, {{ with nomadVar "nomad/jobs/example" }}{{ .person_to_greet }}{{ end }}!
+ Here is the group variable:
+
+ {{- with nomadVar "nomad/jobs/example/web" -}}
+ {{- range $k, $v := . }}
+ - {{ $k }}={{ $v }}
+ {{- end }}
+ {{- end }}
+
+ View the output from the sidecar task.
+
+
+EOT
+```
+
+Visit the webpage rendered by the sidecar task:
+
+```shell-session
+curl -s http://127.0.0.1:21976/sidecar.html
+
+
+ Hello Variables - Sidecar
+
+ The task has access to the following variables:
+
+ - nomad/jobs
+ - nomad/jobs/example
+ - nomad/jobs/example/web
+ - nomad/jobs/example/web/sidecar
+
+ View the index page.
+
+
+```
+
+This corresponds to the following template block, which lists all the variables
+this task has access to in its own namespace:
+
+```
+ template {
+ destination = "${NOMAD_ALLOC_DIR}/data/sidecar.html"
+ change_mode = "noop"
+ data = <
+
+ Hello Variables - Sidecar
+
+ The task has access to the following variables:
+
+ {{- range nomadVarList "nomad" }}
+ - {{ .Path }}
+ {{- end }}
+
+ View the index page.
+
+
+EOT
+ }
+```
+
+Note that `nomad/jobs/example/httpd` does not appear in the list. If you added a
+variable to `nomad/jobs/another-example` it would also not appear in the
+list. If you added `nomad/jobs/example/sidecar` to a different namespace, it
+would not appear in the list.
+
+## Workload associated ACL policies
+
+You may need to give tasks access to variables that are on paths shared by many
+jobs. For example, all jobs in your cluster may need a shared API key for a
+third-party monitoring vendor. You can provide access to these variables secrets
+by creating policies associated with the task's [workload identity][]. See
+[Workload Associated ACL Policies][] for full documentation.
+
+Create a new namespace named `shared`.
+
+```shell-session
+$ nomad namespace apply shared
+Successfully applied namespace "shared"!
+```
+
+Create a variable named `vendor/foo/bar` in the `shared` namespace.
+
+```shell-session
+nomad var put -namespace shared vendor/foo/bar user=me password=passw0rd1
+```
+
+To give the task you wrote earlier access to all secrets in the `shared`
+namespace, you can create the following policy file `shared-policy.hcl`.
+
+```hcl
+namespace "shared" {
+ variables {
+ path "*" {
+ capabilities = ["read"]
+ }
+ }
+}
+```
+
+Now, create the policy and associate it with the `httpd` task in the web group
+of the example job, specifying the appropriate flags on the `nomad acl policy
+apply` command.
+
+```shell-session
+nomad acl policy apply \
+ -namespace prod -job example -group web -task httpd \
+ shared-policy ./shared-policy.hcl
+```
+
+You can view the policy to see that it's associated with the workload.
+
+```shell-session
+$ nomad acl policy info shared-policy
+Name = shared-policy
+Description =
+CreateIndex = 390
+ModifyIndex = 390
+
+Associated Workload
+Namespace = prod
+JobID = example
+Group = web
+Task = httpd
+
+Rules
+
+namespace "shared" {
+ variables {
+ path "*" {
+ capabilities = ["read"]
+ }
+ }
+}
+```
+
+Change the template for the `httpd` task.
+
+```hcl
+ template {
+ destination = "alloc/index.html"
+ data = <
+
+ Hello Variables - Index
+
+ Hello, {{ with nomadVar "nomad/jobs/example" }}{{ .person_to_greet }}{{ end }}!
+ Here is the shared variable:
+
+ {{- with nomadVar "vendor/foo/bar@shared" }}
+ {{- range $k, $v := . }}
+ - {{ $k }}={{ $v }}
+ {{- end }}
+ {{- end }}
+
+
+
+EOT
+```
+
+Update the job and wait for the deployment to complete.
+
+```shell-session
+nomad job run ./example.nomad.hcl
+```
+
+Visit the webpage served by the `httpd` task.
+
+```shell-session
+curl -s http://127.0.0.1:8001/index.html
+
+
+ Hello Variables - Index
+
+ Hello, alice!
+ Here is the shared variable:
+
+ - password=passw0rd1
+ - user=me
+
+
+
+```
+
+## Updating task variables
+
+You can update the value of a variable and it will be updated in the templates
+that read that value.
+
+Update the shared variable so that the "password" field changes.
+
+```shell-session
+nomad var put -namespace shared -force vendor/foo/bar user=me password=passw0rd2
+```
+
+After a few moments, the value will be updated on the template.
+
+```shell-session
+curl -s http://127.0.0.1:8001/index.html
+
+
+ Hello Variables - Index
+
+ Hello, alice!
+ Here is the shared variable:
+
+ - password=passw0rd2
+ - user=me
+
+
+
+```
+
+You can use the template
+[`change_mode`](/nomad/docs/job-specification/template#change_mode)
+to specify Nomad's behavior when a value changes.
+
+## Next steps
+
+Because Nomad Variables use functions in the template block to emit data to
+Nomad jobs, consider learning more about templates in Nomad with the [Templates
+collection](/nomad/tutorials/templates).
+
+[Nomad Variables]: /nomad/docs/concepts/variables
+[Nomad Variables Access Control]: /nomad/tutorials/variables/variables-acls
+[Variables reference documentation]: /nomad/docs/concepts/variables
+[Key Management documentation]: /nomad/docs/manage/key-management
+[Workload Identity documentation]: /nomad/docs/concepts/workload-identity
+[workload identity]: /nomad/docs/concepts/workload-identity
+[`template`]: /nomad/docs/job-specification/template
+[Workload Associated ACL Policies]: /nomad/docs/concepts/workload-identity#workload-associated-acl-policies
+
diff --git a/website/content/docs/job-declare/strategy/blue-green-canary.mdx b/website/content/docs/job-declare/strategy/blue-green-canary.mdx
new file mode 100644
index 000000000..b79401694
--- /dev/null
+++ b/website/content/docs/job-declare/strategy/blue-green-canary.mdx
@@ -0,0 +1,474 @@
+---
+layout: docs
+page_title: Configure blue-green and canary deployments
+description: |-
+ Set up and configure Nomad jobs to deploy using the blue-green and
+ canary deployment strategies.
+---
+
+# Configure blue-green and canary deployments
+
+Sometimes [rolling updates] do not offer the required flexibility for updating
+an application in production. Often organizations prefer to put a "canary" build
+into production or utilize a technique known as a "blue/green" deployment to
+ensure a safe application roll-out to production while minimizing downtime.
+
+## Blue/Green deployments
+
+Blue/Green deployments have several other names including Red/Black or A/B, but
+the concept is generally the same. In a blue/green deployment, there are two
+application versions. Only one application version is active at a time, except
+during the transition phase from one version to the next. The term "active"
+tends to mean "receiving traffic" or "in service".
+
+Imagine a hypothetical API server which has five instances deployed to
+production at version 1.3, and you want to safely update to version 1.4. You
+want to create five new instances at version 1.4 and in the case that they are
+operating correctly you want to promote them and take down the five versions
+running 1.3. In the event of failure, you can quickly rollback to 1.3.
+
+To start, you examine your job which is running in production:
+
+```hcl
+job "docs" {
+ # ...
+
+ group "api" {
+ count = 5
+
+ update {
+ max_parallel = 1
+ canary = 5
+ min_healthy_time = "30s"
+ healthy_deadline = "10m"
+ auto_revert = true
+ auto_promote = false
+ }
+
+ task "api-server" {
+ driver = "docker"
+
+ config {
+ image = "api-server:1.3"
+ }
+ }
+ }
+}
+```
+
+Notice that the job has an `update` stanza with the `canary` count equal to the
+desired count. This allows a Nomad job to model blue/green deployments. When you
+change the job to run the "api-server:1.4" image, Nomad will create five new
+allocations while leaving the original "api-server:1.3" allocations running.
+
+Observe how this works by changing the image to run the new version:
+
+```diff
+@@ -2,6 +2,8 @@ job "docs" {
+ group "api" {
+ task "api-server" {
+ config {
+- image = "api-server:1.3"
++ image = "api-server:1.4"
+```
+
+Next, plan these changes. Save the modified jobspec with the new version of `api-server` to a file name `docs.nomad.hcl`.
+
+```shell-session
+$ nomad job plan docs.nomad.hcl
++/- Job: "docs"
++/- Task Group: "api" (5 canary, 5 ignore)
+ +/- Task: "api-server" (forces create/destroy update)
+ +/- Config {
+ +/- image: "api-server:1.3" => "api-server:1.4"
+ }
+
+Scheduler dry-run:
+- All tasks successfully allocated.
+
+Job Modify Index: 7
+To submit the job with version verification run:
+
+nomad job run -check-index 7 docs.nomad.hcl
+
+When running the job with the check-index flag, the job will only be run if the
+job modify index given matches the server-side version. If the index has
+changed, another user has modified the job and the plan's results are
+potentially invalid.
+```
+
+Run the changes.
+
+```shell-session
+$ nomad job run docs.nomad.hcl
+## ...
+```
+
+The plan output states that Nomad is going to create five canaries running the
+"api-server:1.4" image and ignore all the allocations running the older image.
+Now, if you examine the status of the job you will note that both the blue
+("api-server:1.3") and green ("api-server:1.4") set are running.
+
+```shell-session
+$ nomad status docs
+ID = docs
+Name = docs
+Submit Date = 07/26/17 19:57:47 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+api 0 0 10 0 0 0
+
+Latest Deployment
+ID = 32a080c1
+Status = running
+Description = Deployment is running but requires manual promotion
+
+Deployed
+Task Group Auto Revert Promoted Desired Canaries Placed Healthy Unhealthy
+api true false 5 5 5 5 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+6d8eec42 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+7051480e 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+36c6610f 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+410ba474 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+85662a7a 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+3ac3fe05 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+4bd51979 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+2998387b 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+35b813ee 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+b53b4289 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+```
+
+Now that the new version is running in production, you can route traffic to it
+and validate that it is working properly. If so, you would promote the
+deployment and Nomad would stop allocations running the older version. If not,
+you would either troubleshoot one of the running containers or destroy the new
+containers by failing the deployment.
+
+### Promote the deployment
+
+After deploying the new image along side the old version you have determined it
+is functioning properly and you want to transition fully to the new version.
+Doing so is as simple as promoting the deployment:
+
+```shell-session
+$ nomad deployment promote 32a080c1
+==> Monitoring evaluation "61ac2be5"
+ Evaluation triggered by job "docs"
+ Evaluation within deployment: "32a080c1"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "61ac2be5" finished with status "complete"
+```
+
+If you inspect the job's status, you can observe that after promotion, Nomad
+stopped the older allocations and is only running the new one. This now
+completes the blue/green deployment.
+
+```shell-session
+$ nomad status docs
+ID = docs
+Name = docs
+Submit Date = 07/26/17 19:57:47 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+api 0 0 5 0 5 0
+
+Latest Deployment
+ID = 32a080c1
+Status = successful
+Description = Deployment completed successfully
+
+Deployed
+Task Group Auto Revert Promoted Desired Canaries Placed Healthy Unhealthy
+api true true 5 5 5 5 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+6d8eec42 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+7051480e 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+36c6610f 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+410ba474 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+85662a7a 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+3ac3fe05 087852e2 api 0 stop complete 07/26/17 19:53:56 UTC
+4bd51979 087852e2 api 0 stop complete 07/26/17 19:53:56 UTC
+2998387b 087852e2 api 0 stop complete 07/26/17 19:53:56 UTC
+35b813ee 087852e2 api 0 stop complete 07/26/17 19:53:56 UTC
+b53b4289 087852e2 api 0 stop complete 07/26/17 19:53:56 UTC
+```
+
+### Fail a deployment
+
+After deploying the new image alongside the old version you have determined it
+is not functioning properly and you want to roll back to the old version. Doing
+so is as simple as failing the deployment:
+
+```shell-session
+$ nomad deployment fail 32a080c1
+Deployment "32a080c1-de5a-a4e7-0218-521d8344c328" failed. Auto-reverted to job version 0.
+
+==> Monitoring evaluation "6840f512"
+ Evaluation triggered by job "example"
+ Evaluation within deployment: "32a080c1"
+ Allocation "0ccb732f" modified: node "36e7a123", group "cache"
+ Allocation "64d4f282" modified: node "36e7a123", group "cache"
+ Allocation "664e33c7" modified: node "36e7a123", group "cache"
+ Allocation "a4cb6a4b" modified: node "36e7a123", group "cache"
+ Allocation "fdd73bdd" modified: node "36e7a123", group "cache"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "6840f512" finished with status "complete"
+```
+
+After failing the deployment, check the job's status. Confirm that Nomad has
+stopped the new allocations and is only running the old ones, and that the working
+copy of the job has reverted back to the original specification running "api-server:1.3".
+
+```shell-session
+$ nomad status docs
+ID = docs
+Name = docs
+Submit Date = 07/26/17 19:57:47 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+api 0 0 5 0 5 0
+
+Latest Deployment
+ID = 6f3f84b3
+Status = successful
+Description = Deployment completed successfully
+
+Deployed
+Task Group Auto Revert Desired Placed Healthy Unhealthy
+cache true 5 5 5 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+27dc2a42 36e7a123 api 1 stop complete 07/26/17 20:07:31 UTC
+5b7d34bb 36e7a123 api 1 stop complete 07/26/17 20:07:31 UTC
+983b487d 36e7a123 api 1 stop complete 07/26/17 20:07:31 UTC
+d1cbf45a 36e7a123 api 1 stop complete 07/26/17 20:07:31 UTC
+d6b46def 36e7a123 api 1 stop complete 07/26/17 20:07:31 UTC
+0ccb732f 36e7a123 api 2 run running 07/26/17 20:06:29 UTC
+64d4f282 36e7a123 api 2 run running 07/26/17 20:06:29 UTC
+664e33c7 36e7a123 api 2 run running 07/26/17 20:06:29 UTC
+a4cb6a4b 36e7a123 api 2 run running 07/26/17 20:06:29 UTC
+fdd73bdd 36e7a123 api 2 run running 07/26/17 20:06:29 UTC
+```
+
+```shell-session
+$ nomad job deployments docs
+ID Job ID Job Version Status Description
+6f3f84b3 example 2 successful Deployment completed successfully
+32a080c1 example 1 failed Deployment marked as failed - rolling back to job version 0
+c4c16494 example 0 successful Deployment completed successfully
+```
+
+## Deploy with canaries
+
+Canary updates are a useful way to test a new version of a job before beginning
+a rolling update. The `update` stanza supports setting the number of canaries
+the job operator would like Nomad to create when the job changes via the
+`canary` parameter. When the job specification is updated, Nomad creates the
+canaries without stopping any allocations from the previous job.
+
+This pattern allows operators to achieve higher confidence in the new job
+version because they can route traffic, examine logs, etc, to determine the new
+application is performing properly.
+
+```hcl
+job "docs" {
+ # ...
+
+ group "api" {
+ count = 5
+
+ update {
+ max_parallel = 1
+ canary = 1
+ min_healthy_time = "30s"
+ healthy_deadline = "10m"
+ auto_revert = true
+ auto_promote = false
+ }
+
+ task "api-server" {
+ driver = "docker"
+
+ config {
+ image = "api-server:1.3"
+ }
+ }
+ }
+}
+```
+
+In the example above, the `update` stanza tells Nomad to create a single canary
+when the job specification is changed.
+
+You can experience how this behaves by changing the image to run the new
+version:
+
+```diff
+@@ -2,6 +2,8 @@ job "docs" {
+ group "api" {
+ task "api-server" {
+ config {
+- image = "api-server:1.3"
++ image = "api-server:1.4"
+```
+
+Next, plan these changes.
+
+```shell-session
+$ nomad job plan docs.nomad.hcl
++/- Job: "docs"
++/- Task Group: "api" (1 canary, 5 ignore)
+ +/- Task: "api-server" (forces create/destroy update)
+ +/- Config {
+ +/- image: "api-server:1.3" => "api-server:1.4"
+ }
+
+Scheduler dry-run:
+- All tasks successfully allocated.
+
+Job Modify Index: 7
+To submit the job with version verification run:
+
+nomad job run -check-index 7 docs.nomad.hcl
+
+When running the job with the check-index flag, the job will only be run if the
+job modify index given matches the server-side version. If the index has
+changed, another user has modified the job and the plan's results are
+potentially invalid.
+
+$ nomad job run docs.nomad.hcl
+# ...
+```
+
+Run the changes.
+
+```shell-session
+$ nomad job run docs.nomad.hcl
+## ...
+```
+
+Note from the plan output, Nomad is going to create one canary that will run the
+"api-server:1.4" image and ignore all the allocations running the older image.
+After running the job, The `nomad status` command output shows that the canary
+is running along side the older version of the job:
+
+```shell-session
+$ nomad status docs
+ID = docs
+Name = docs
+Submit Date = 07/26/17 19:57:47 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+api 0 0 6 0 0 0
+
+Latest Deployment
+ID = 32a080c1
+Status = running
+Description = Deployment is running but requires manual promotion
+
+Deployed
+Task Group Auto Revert Promoted Desired Canaries Placed Healthy Unhealthy
+api true false 5 1 1 1 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+85662a7a 087852e2 api 1 run running 07/26/17 19:57:47 UTC
+3ac3fe05 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+4bd51979 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+2998387b 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+35b813ee 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+b53b4289 087852e2 api 0 run running 07/26/17 19:53:56 UTC
+```
+
+Now if you promote the canary, this will trigger a rolling update to replace the
+remaining allocations running the older image. The rolling update will happen at
+a rate of `max_parallel`, so in this case, one allocation at a time.
+
+```shell-session
+$ nomad deployment promote 37033151
+==> Monitoring evaluation "37033151"
+ Evaluation triggered by job "docs"
+ Evaluation within deployment: "ed28f6c2"
+ Allocation "f5057465" created: node "f6646949", group "cache"
+ Allocation "f5057465" status changed: "pending" -> "running"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "37033151" finished with status "complete"
+```
+
+Check the status.
+
+```shell-session
+$ nomad status docs
+ID = docs
+Name = docs
+Submit Date = 07/26/17 20:28:59 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+api 0 0 5 0 2 0
+
+Latest Deployment
+ID = ed28f6c2
+Status = running
+Description = Deployment is running
+
+Deployed
+Task Group Auto Revert Promoted Desired Canaries Placed Healthy Unhealthy
+api true true 5 1 2 1 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+f5057465 f6646949 api 1 run running 07/26/17 20:29:23 UTC
+b1c88d20 f6646949 api 1 run running 07/26/17 20:28:59 UTC
+1140bacf f6646949 api 0 run running 07/26/17 20:28:37 UTC
+1958a34a f6646949 api 0 run running 07/26/17 20:28:37 UTC
+4bda385a f6646949 api 0 run running 07/26/17 20:28:37 UTC
+62d96f06 f6646949 api 0 stop complete 07/26/17 20:28:37 UTC
+f58abbb2 f6646949 api 0 stop complete 07/26/17 20:28:37 UTC
+```
+
+Alternatively, if the canary was not performing properly, you could abandon the
+change using the `nomad deployment fail` command, similar to the blue/green
+example.
+
+[rolling updates]: /nomad/docs/job-declare/strategy/rolling
diff --git a/website/content/docs/job-declare/strategy/index.mdx b/website/content/docs/job-declare/strategy/index.mdx
new file mode 100644
index 000000000..fc78f08b6
--- /dev/null
+++ b/website/content/docs/job-declare/strategy/index.mdx
@@ -0,0 +1,16 @@
+---
+layout: docs
+page_title: Job deployment strategies
+description: |-
+ Discover common patterns to update running jobs in Nomad, including rolling updates, blue-green deployments, and canary deployments. Nomad provides built-in support for each strategy.
+---
+
+# Job deployment strategies
+
+Most applications are long-lived and require updates over time. Whether you are
+deploying a new version of your web application or upgrading to a new version of
+Redis, Nomad has built-in support for rolling, blue/green, and canary updates.
+When a job specifies a rolling update, Nomad uses task state and health check
+information in order to detect allocation health and minimize or eliminate
+downtime. This section and subsections will explore how to do so safely with
+Nomad.
diff --git a/website/content/docs/job-declare/strategy/rolling.mdx b/website/content/docs/job-declare/strategy/rolling.mdx
new file mode 100644
index 000000000..667f9e5be
--- /dev/null
+++ b/website/content/docs/job-declare/strategy/rolling.mdx
@@ -0,0 +1,323 @@
+---
+layout: docs
+page_title: Configure rolling updates
+description: |-
+ Enable rolling updates for a Nomad job, inspect the deployment, and set up
+ Nomad to automatically revert failed deployments to a previous working
+ version.
+---
+
+# Configure rolling updates
+
+Nomad supports rolling updates as a first class feature. To enable rolling
+updates a job or task group is annotated with a high-level description of the
+update strategy using the [`update` stanza]. Under the hood, Nomad handles
+limiting parallelism, interfacing with Consul to determine service health and
+even automatically reverting to an older, healthy job when a deployment fails.
+
+## Enable rolling updates for job
+
+Rolling updates are enabled by adding the [`update` stanza] to the job
+specification. The `update` stanza may be placed at the job level or in an
+individual task group. When placed at the job level, the update strategy is
+inherited by all task groups in the job. When placed at both the job and group
+level, the `update` stanzas are merged, with group stanzas taking precedence
+over job level stanzas. There is more information about
+[inheritance][update-stanza-inheritance] in the `update` stanza documentation.
+
+```hcl
+job "geo-api-server" {
+ # ...
+
+ group "api-server" {
+ count = 6
+
+ # Add an update stanza to enable rolling updates of the service
+ update {
+ max_parallel = 2
+ min_healthy_time = "30s"
+ healthy_deadline = "10m"
+ }
+
+ task "server" {
+ driver = "docker"
+
+ config {
+ image = "geo-api-server:0.1"
+ }
+
+ # ...
+ }
+ }
+}
+```
+
+In this example, by adding the simple `update` stanza to the "api-server" task
+group, you inform Nomad that updates to the group should be handled with a
+rolling update strategy.
+
+Thus when a change is made to the job file that requires new allocations to be
+made, Nomad will deploy 2 allocations at a time and require that the allocations
+be running in a healthy state for 30 seconds before deploying more versions of the
+new group.
+
+By default Nomad determines allocation health by ensuring that all tasks in the
+group are running and that any [service check] the tasks register are passing.
+
+## Check the planned changes
+
+Suppose you make a change to a file to update the version of a Docker container
+that is configured with the same rolling update strategy from above.
+
+```diff
+@@ -2,6 +2,8 @@ job "geo-api-server" {
+ group "api-server" {
+ task "server" {
+ driver = "docker"
+
+ config {
+- image = "geo-api-server:0.1"
++ image = "geo-api-server:0.2"
+```
+
+The [`nomad job plan` command] allows you to visualize the series of steps the
+scheduler would perform. You can analyze this output to confirm it is correct:
+
+```shell-session
+$ nomad job plan geo-api-server.nomad.hcl
++/- Job: "geo-api-server"
++/- Task Group: "api-server" (2 create/destroy update, 4 ignore)
+ +/- Task: "server" (forces create/destroy update)
+ +/- Config {
+ +/- image: "geo-api-server:0.1" => "geo-api-server:0.2"
+ }
+
+Scheduler dry-run:
+- All tasks successfully allocated.
+
+Job Modify Index: 7
+To submit the job with version verification run:
+
+nomad job run -check-index 7 geo-api-server.nomad.hcl
+
+When running the job with the check-index flag, the job will only be run if the
+job modify index given matches the server-side version. If the index has
+changed, another user has modified the job and the plan's results are
+potentially invalid.
+```
+
+Here you can observe that Nomad will begin a rolling update by creating and
+destroying two allocations first; for the time being ignoring four of the old
+allocations, consistent with the configured `max_parallel` count.
+
+## Inspect a deployment
+
+After running the plan you can submit the updated job by running `nomad run`.
+Once run, Nomad will begin the rolling update of the service by placing two
+allocations at a time of the new job and taking two of the old jobs down.
+
+You can inspect the current state of a rolling deployment using `nomad status`:
+
+```shell-session
+$ nomad status geo-api-server
+ID = geo-api-server
+Name = geo-api-server
+Submit Date = 07/26/17 18:08:56 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+api-server 0 0 6 0 4 0
+
+Latest Deployment
+ID = c5b34665
+Status = running
+Description = Deployment is running
+
+Deployed
+Task Group Desired Placed Healthy Unhealthy
+api-server 6 4 2 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+14d288e8 f7b1ee08 api-server 1 run running 07/26/17 18:09:17 UTC
+a134f73c f7b1ee08 api-server 1 run running 07/26/17 18:09:17 UTC
+a2574bb6 f7b1ee08 api-server 1 run running 07/26/17 18:08:56 UTC
+496e7aa2 f7b1ee08 api-server 1 run running 07/26/17 18:08:56 UTC
+9fc96fcc f7b1ee08 api-server 0 run running 07/26/17 18:04:30 UTC
+2521c47a f7b1ee08 api-server 0 run running 07/26/17 18:04:30 UTC
+6b794fcb f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+9bc11bd7 f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+691eea24 f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+af115865 f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+```
+
+The output indicates that Nomad has created a deployment to conduct the rolling
+update from job version 0 to 1. It has placed four instances of the new job and
+has stopped four of the old instances. Consult the list of deployed allocations,
+and note that Nomad has placed four instances of job version 1 but only
+considers 2 of them healthy. This is because the two newest placed allocations
+haven't been healthy for the required 30 seconds yet.
+
+Wait for the deployment to complete, and then re-issue the command. You will
+receive output similar to the following:
+
+```shell-session
+$ nomad status geo-api-server
+ID = geo-api-server
+Name = geo-api-server
+Submit Date = 07/26/17 18:08:56 UTC
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+cache 0 0 6 0 6 0
+
+Latest Deployment
+ID = c5b34665
+Status = successful
+Description = Deployment completed successfully
+
+Deployed
+Task Group Desired Placed Healthy Unhealthy
+cache 6 6 6 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created At
+d42a1656 f7b1ee08 api-server 1 run running 07/26/17 18:10:10 UTC
+401daaf9 f7b1ee08 api-server 1 run running 07/26/17 18:10:00 UTC
+14d288e8 f7b1ee08 api-server 1 run running 07/26/17 18:09:17 UTC
+a134f73c f7b1ee08 api-server 1 run running 07/26/17 18:09:17 UTC
+a2574bb6 f7b1ee08 api-server 1 run running 07/26/17 18:08:56 UTC
+496e7aa2 f7b1ee08 api-server 1 run running 07/26/17 18:08:56 UTC
+9fc96fcc f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+2521c47a f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+6b794fcb f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+9bc11bd7 f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+691eea24 f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+af115865 f7b1ee08 api-server 0 stop complete 07/26/17 18:04:30 UTC
+```
+
+Nomad has successfully transitioned the group to running the updated canary and
+did so with no downtime to your service by ensuring only two allocations were
+changed at a time and the newly placed allocations ran successfully. Had any of
+the newly placed allocations failed their health check, Nomad would have aborted
+the deployment and stopped placing new allocations. If configured, Nomad can
+automatically revert back to the old job definition when the deployment fails.
+
+## Use auto-revert on failed deployments
+
+In the case you do a deployment in which the new allocations are unhealthy,
+Nomad will fail the deployment and stop placing new instances of the job. It
+optionally supports automatically reverting back to the last stable job version
+on deployment failure. Nomad keeps a history of submitted jobs and whether the
+job version was stable. A job is considered stable if all its allocations are
+healthy.
+
+To enable this, add the `auto_revert` parameter to the `update` stanza:
+
+```hcl
+update {
+ max_parallel = 2
+ min_healthy_time = "30s"
+ healthy_deadline = "10m"
+
+ # Enable automatically reverting to the last stable job on a failed
+ # deployment.
+ auto_revert = true
+}
+```
+
+Now imagine you want to update your image to "geo-api-server:0.3" but you instead
+update it to the below and run the job:
+
+```diff
+@@ -2,6 +2,8 @@ job "geo-api-server" {
+ group "api-server" {
+ task "server" {
+ driver = "docker"
+
+ config {
+- image = "geo-api-server:0.2"
++ image = "geo-api-server:0.33"
+```
+
+Running `nomad job deployments` will show that the deployment fails, and Nomad
+auto-reverted to the last stable job:
+
+```shell-session
+$ nomad job deployments geo-api-server
+ID Job ID Job Version Status Description
+0c6f87a5 geo-api-server 3 successful Deployment completed successfully
+b1712b7f geo-api-server 2 failed Failed due to unhealthy allocations - rolling back to job version 1
+3eee83ce geo-api-server 1 successful Deployment completed successfully
+72813fcf geo-api-server 0 successful Deployment completed successfully
+```
+
+Nomad job versions increment monotonically. Even though Nomad reverted to the
+job specification at version 1, it creates a new job version. You can observe the
+differences between a job's versions and how Nomad auto-reverted the job using
+the `job history` command:
+
+```shell-session
+$ nomad job history -p geo-api-server
+Version = 3
+Stable = true
+Submit Date = 07/26/17 18:44:18 UTC
+Diff =
++/- Job: "geo-api-server"
++/- Task Group: "api-server"
+ +/- Task: "server"
+ +/- Config {
+ +/- image: "geo-api-server:0.33" => "geo-api-server:0.2"
+ }
+
+Version = 2
+Stable = false
+Submit Date = 07/26/17 18:45:21 UTC
+Diff =
++/- Job: "geo-api-server"
++/- Task Group: "api-server"
+ +/- Task: "server"
+ +/- Config {
+ +/- image: "geo-api-server:0.2" => "geo-api-server:0.33"
+ }
+
+Version = 1
+Stable = true
+Submit Date = 07/26/17 18:44:18 UTC
+Diff =
++/- Job: "geo-api-server"
++/- Task Group: "api-server"
+ +/- Task: "server"
+ +/- Config {
+ +/- image: "geo-api-server:0.1" => "geo-api-server:0.2"
+ }
+
+Version = 0
+Stable = true
+Submit Date = 07/26/17 18:43:43 UTC
+```
+
+This output describes the process of a reverted deployment. Starting at the end
+of the output and working backwards, Nomad shows that version 0 was submitted.
+Next, version 1 was an image change from 0.1 to 0.2 of geo-api-server and was
+flagged as stable. Version 2 of the job attempted to update geo-api-server from
+0.2 to 0.33; however, the deployment failed and never became stable. Finally,
+version 3 of the job is created when Nomad automatically reverts the failed
+deployment and redeploys the last healthy version--geo-api-server version 0.2.
+
+[`nomad job plan` command]: /nomad/commands/job/plan
+[`update` stanza]: /nomad/docs/job-specification/update
+[service check]: /nomad/docs/job-specification/check
+[update-stanza-inheritance]: /nomad/docs/job-specification/update
diff --git a/website/content/docs/job-declare/task-dependencies.mdx b/website/content/docs/job-declare/task-dependencies.mdx
new file mode 100644
index 000000000..9a7cfe068
--- /dev/null
+++ b/website/content/docs/job-declare/task-dependencies.mdx
@@ -0,0 +1,385 @@
+---
+layout: docs
+page_title: Configure task dependencies
+description: |-
+ Create, configure, and run two jobs to use init and sidecar tasks. Create a dependency between the jobs and discover how to model complex workload dependency trees.
+---
+
+# Configure task dependencies
+
+
+Nomad task dependencies provide the ability to define prestart tasks.
+
+Prestart tasks have two patterns: init tasks and sidecar tasks. Init
+tasks are tasks that must run to completion before the main workload is started.
+They are commonly used to download assets or to create necessary tables for an
+extract-transform-load (ETL) job. Sidecar tasks are started before main workload
+starts and run for the lifetime of the main workload. Typical sidecars tasks are
+log forwarders, proxies, and for platform abstractions. This tutorial demonstrates
+an init task.
+
+You can create an init task by adding a [`lifecycle` stanza] with `hook` set to
+`prestart` and `sidecar` to `false` as below.
+
+```hcl
+ lifecycle {
+ hook = "prestart"
+ sidecar = false
+ }
+```
+
+You can model complex job dependency trees by using one or more init tasks to
+delay the job's main tasks from running until a condition is met. In this case,
+until a service is available and advertised in Consul.
+
+In this tutorial you will work with several Nomad objects:
+
+- **mock-app** - a job file that contains two tasks
+
+ - **await-mock-service** - an init task that will wait infinitely for a
+ service named "mock-service" to be advertised over the Consul DNS API. Once
+ found, it will exit successfully.
+
+ - **mock-app-container** - the main workload task that is dependent on the
+ "mock-service" service.
+
+- **mock-service** - a job that contains one task which advertises a service
+ named "mock-service". This is provided as a Nomad job as a convenience, but
+ could be replaced by any means of registering a service named "mock-service"
+ in Consul, like the CLI or API.
+
+In this guide, you will complete the following actions:
+
+- Deploy the "mock-app" job.
+
+- Verify that the "mock-app-container" task remains in pending and unstarted.
+
+- Start the "mock-service" job.
+
+- Verify that the "await-mock-service" container completes successfully and that
+ the "mock-app-container" task starts.
+
+## Prerequisites
+
+To complete this tutorial you will need:
+
+- a Nomad cluster and at least one Consul server.
+- Nomad v0.11.0 or greater
+
+If you do not have an existing Nomad cluster, you can learn how to deploy
+on using the [Install Nomad] guide. Similarly, if you do not have an
+existing Consul datacenter, you can learn how to deploy Consul with the
+[Install Consul] guide.
+
+## Create the mock-app job file
+
+This example uses a looping script, in the `config` stanza, to mock service
+payloads.
+
+Create an HCL file named `mock-app.nomad.hcl` with the following content.
+
+```hcl
+job "mock-app" {
+ datacenters = ["dc1"]
+ type = "service"
+
+ group "mock-app" {
+ # disable deployments
+ update {
+ max_parallel = 0
+ }
+
+ task "await-mock-service" {
+ driver = "docker"
+
+ config {
+ image = "busybox:1.28"
+ command = "sh"
+ args = ["-c", "echo -n 'Waiting for service'; until nslookup mock-service.service.consul 2>&1 >/dev/null; do echo '.'; sleep 2; done"]
+ network_mode = "host"
+ }
+
+ resources {
+ cpu = 200
+ memory = 128
+ }
+
+ lifecycle {
+ hook = "prestart"
+ sidecar = false
+ }
+ }
+
+ task "mock-app-container" {
+ driver = "docker"
+
+ config {
+ image = "busybox"
+ command = "sh"
+ args = ["-c", "echo The app is running! && sleep 3600"]
+ }
+
+ resources {
+ cpu = 200
+ memory = 128
+ }
+ }
+ }
+}
+```
+
+The job contains two tasks—"await-mock-service" and "mock-app". The
+"await-mock-service" task is configured to busy-wait until the "mock-service"
+service is advertised in Consul. For this guide, this will not happen until you
+run the `mock-service.nomad.hcl` job. In a more real-world case, this could be any
+service dependency that advertises itself in Consul.
+
+You can use this pattern to model more complicated chains of service dependency
+by including more await-style workloads.
+
+### Ensure that name resolution works properly
+
+Since the "await-mock-service" task uses nslookup inside of a Docker container,
+you will need to ensure that your container can perform lookups against your
+Consul DNS API endpoint. This tutorial uses `network_mode = host` to allow the
+container to use the Nomad client nodes DNS resolution pathway.
+
+The nslookup application will only perform queries on the standard DNS port
+(53). You might need to use an application to forward requests from port 53 to
+the Consul DNS API port—port 8600 by default. You can learn several ways to
+accomplish this forwarding in the [Forward DNS] Learn guide.
+
+You could also add a `dns_servers` value to the config stanza of the
+"await-mock-service" task in the mock-app.nomad.hcl file to direct the query to a
+DNS server directly that meets the above criteria.
+
+## Run the mock-app job
+
+Run `nomad run mock-app.nomad.hcl`.
+
+```shell-session
+$ nomad run mock-app.nomad.hcl
+```
+
+The job will launch and provide you an allocation ID in the output.
+
+```shell-session
+$ nomad run mock-app.nomad.hcl
+==> Monitoring evaluation "01c73d5a"
+ Evaluation triggered by job "mock-app"
+ Allocation "3044dda0" created: node "f26809e6", group "mock-app"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "01c73d5a" finished with status "complete"
+```
+
+## Verify mock-app-container is pending
+
+Run the `nomad alloc status` command with the provided allocation ID.
+
+```shell-session
+$ nomad alloc status 3044dda0
+```
+
+The `nomad alloc status` command provides you with useful information about the resource. For this guide, focus on the status
+of each task. Each task's status is output in lines that look like `Task "await-mock-service" is "running"`.
+
+```shell-session
+$ nomad alloc status 3044dda0
+ID = 3044dda0-8dc1-1bac-86ea-66a3557c67d3
+Eval ID = 01c73d5a
+Name = mock-app.mock-app[0]
+Node ID = f26809e6
+Node Name = nomad-client-2.node.consul
+Job ID = mock-app
+Job Version = 0
+Client Status = running
+Client Description = Tasks are running
+Desired Status = run
+Desired Description =
+Created = 43s ago
+Modified = 42s ago
+
+Task "await-mock-service" (prestart) is "running"
+Task Resources
+CPU Memory Disk Addresses
+3/200 MHz 80 KiB/128 MiB 300 MiB
+
+Task Events:
+Started At = 2020-03-18T17:07:26Z
+Finished At = N/A
+Total Restarts = 0
+Last Restart = N/A
+
+Recent Events:
+Time Type Description
+2020-03-18T13:07:26-04:00 Started Task started by client
+2020-03-18T13:07:26-04:00 Task Setup Building Task Directory
+2020-03-18T13:07:26-04:00 Received Task received by client
+
+Task "mock-app-container" is "pending"
+Task Resources
+CPU Memory Disk Addresses
+200 MHz 128 MiB 300 MiB
+
+Task Events:
+Started At = N/A
+Finished At = N/A
+Total Restarts = 0
+Last Restart = N/A
+
+Recent Events:
+Time Type Description
+2020-03-18T13:07:26-04:00 Received Task received by client
+```
+
+Notice that the await-mock-service task is running and that the
+"mock-app-container" task is pending. The "mock-app-container" task will remain
+in pending until the "await-mock-service" task completes successfully.
+
+## Create the mock-service job file
+
+Create a file named `mock-service.nomad.hcl` with the following content.
+
+```hcl
+job "mock-service" {
+ datacenters = ["dc1"]
+ type = "service"
+
+ group "mock-service" {
+ task "mock-service" {
+ driver = "docker"
+
+ config {
+ image = "busybox"
+ command = "sh"
+ args = ["-c", "echo The service is running! && while true; do sleep 2; done"]
+ }
+
+ resources {
+ cpu = 200
+ memory = 128
+ }
+
+ service {
+ name = "mock-service"
+ }
+ }
+ }
+}
+
+```
+
+This job advertises the "mock-service" service in Consul. When run, this
+will allow the await-mock-service task to complete successfully and let
+the "mock-app-container" task start up.
+
+## Start mock-service job
+
+Run `nomad run mock-service.nomad.hcl`.
+
+```shell-session
+$ nomad run mock-service.nomad.hcl
+```
+
+Nomad will start the job and return information about the scheduling information.
+
+```shell-session
+$ nomad run mock-service.nomad
+==> Monitoring evaluation "f31f8eb1"
+ Evaluation triggered by job "mock-service"
+ Allocation "d7767adf" created: node "f26809e6", group "mock-service"
+ Evaluation within deployment: "3d86e09a"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "f31f8eb1" finished with status "complete"
+```
+
+## Verify mock-app-container is running
+
+Finally, check the output of the `nomad alloc status` command again to check the
+task statuses. Use the allocation ID from when you ran the "mock-app" job.
+
+```shell-session
+$ nomad alloc status 3044dda0
+```
+
+Again, focus on the task status lines for "await-mock-service" and
+"mock-app-container".
+
+```plaintext
+ID = 3044dda0-8dc1-1bac-86ea-66a3557c67d3
+Eval ID = 01c73d5a
+Name = mock-app.mock-app[0]
+Node ID = f26809e6
+Node Name = nomad-client-2.node.consul
+Job ID = mock-app
+Job Version = 0
+Client Status = running
+Client Description = Tasks are running
+Desired Status = run
+Desired Description =
+Created = 21m38s ago
+Modified = 7m27s ago
+
+Task "await-mock-service" (prestart) is "dead"
+Task Resources
+CPU Memory Disk Addresses
+0/200 MHz 80 KiB/128 MiB 300 MiB
+
+Task Events:
+Started At = 2020-03-18T17:07:26Z
+Finished At = 2020-03-18T17:21:35Z
+Total Restarts = 0
+Last Restart = N/A
+
+Recent Events:
+Time Type Description
+2020-03-18T13:21:35-04:00 Terminated Exit Code: 0
+2020-03-18T13:07:26-04:00 Started Task started by client
+2020-03-18T13:07:26-04:00 Task Setup Building Task Directory
+2020-03-18T13:07:26-04:00 Received Task received by client
+
+Task "mock-app-container" is "running"
+Task Resources
+CPU Memory Disk Addresses
+0/200 MHz 32 KiB/128 MiB 300 MiB
+
+Task Events:
+Started At = 2020-03-18T17:21:37Z
+Finished At = N/A
+Total Restarts = 0
+Last Restart = N/A
+
+Recent Events:
+Time Type Description
+2020-03-18T13:21:37-04:00 Started Task started by client
+2020-03-18T13:21:35-04:00 Driver Downloading image
+2020-03-18T13:21:35-04:00 Task Setup Building Task Directory
+2020-03-18T13:07:26-04:00 Received Task received by client
+```
+
+Notice, the "await-mock-service" task is dead and based on the "Recent Events"
+table terminated with "Exit Code: 0". This indicates that it completed
+successfully. The "mock-app-container" task has now transitioned to the
+"running" status and the container is running.
+
+## Next steps
+
+Now that you have completed this guide, you have experimented with using Nomad
+task dependencies to model inter-job dependencies.
+
+### Further reading
+
+- [`lifecycle` stanza]
+- [`service` stanza]
+- Consul [Service Definition]
+- Consul [DNS Interface]
+
+[forward dns]: /consul/tutorials/networking/dns-forwarding
+[install consul]: /consul/tutorials/production-deploy/deployment-guide
+[install nomad]: /nomad/tutorials/enterprise/production-deployment-guide-vm-with-consul
+[`lifecycle` stanza]: /nomad/docs/job-specification/lifecycle
+[`service` stanza]: /nomad/docs/job-specification/service
+[service definition]: /consul/docs/services/usage/define-services
+[dns interface]: /consul/docs/services/discovery/dns-overview
+[dns interface]: /consul/docs/services/discovery/dns-overview
+
diff --git a/website/content/docs/drivers/docker.mdx b/website/content/docs/job-declare/task-driver/docker.mdx
similarity index 57%
rename from website/content/docs/drivers/docker.mdx
rename to website/content/docs/job-declare/task-driver/docker.mdx
index 146c335eb..5b8511761 100644
--- a/website/content/docs/drivers/docker.mdx
+++ b/website/content/docs/job-declare/task-driver/docker.mdx
@@ -1,10 +1,10 @@
---
layout: docs
-page_title: Docker task driver
-description: Nomad's Docker task driver lets you run Docker-based tasks in your jobs. Learn how to configure job tasks, authenticate against a private repository, use insecure registries, and configure Docker networking. Modify the Docker task driver plugin configuration. Learn about CPU, memory, filesystem IO, and security resource isolation as well as how Nomad handles dangling containers.
+page_title: Use the Docker task driver in a job
+description: Nomad's Docker task driver lets you run Docker-based tasks in your jobs. Learn how to configure job tasks, authenticate against a private repository, use insecure registries, and configure Docker networking.
---
-# Docker task driver
+# Use the Docker task driver in a job
Name: `docker`
@@ -12,8 +12,12 @@ The `docker` driver provides a first-class Docker workflow on Nomad. The Docker
driver handles downloading containers, mapping ports, and starting, watching,
and cleaning up after containers.
--> **Note:** If you are using Docker Desktop for Windows or MacOS, please check
-[our FAQ][faq-win-mac].
+**Note:** If you are using Docker Desktop for Windows or MacOS, check
+[the FAQ][faq-win-mac].
+
+Refer to [Configure the Docker task
+driver](/nomad/docs/deploy/task-driver/docker) for capabilities, client
+requirements, and plugin configuration.
## Task Configuration
@@ -37,8 +41,7 @@ The `docker` driver supports the following configuration in the job spec. Only
and should include `https://` if required. By default it will be fetched from
Docker Hub. If the tag is omitted or equal to `latest` the driver will always
try to pull the image. If the image to be pulled exists in a registry that
- requires authentication credentials must be provided to Nomad. Please see the
- [Authentication section](#authentication).
+ requires authentication credentials must be provided to Nomad.
```hcl
config {
@@ -53,7 +56,7 @@ The `docker` driver supports the following configuration in the job spec. Only
- `args` - (Optional) A list of arguments to the optional `command`. If no
`command` is specified, the arguments are passed directly to the container.
References to environment variables or any [interpretable Nomad
- variables](/nomad/docs/runtime/interpolation) will be interpreted before
+ variables](/nomad/docs/reference/runtime-variable-interpolation) will be interpreted before
launching the task. For example:
```hcl
@@ -71,7 +74,7 @@ The `docker` driver supports the following configuration in the job spec. Only
- `auth_soft_fail` `(bool: false)` - Don't fail the task on an auth failure.
Attempt to continue without auth. If the Nomad client configuration has an
- [`auth.helper`](#plugin_auth_helper) block, the helper will be tried for
+ [`auth.helper`](/nomad/docs/deploy/task-driver/docker#helper) block, the helper will be tried for
all images, including public images. If you mix private and public images,
you will need to include `auth_soft_fail=true` in every job using a public
image.
@@ -378,7 +381,7 @@ The `docker` driver supports the following configuration in the job spec. Only
that exist inside the allocation working directory. You can allow mounting
host paths outside of the [allocation working directory] on individual clients
by setting the `docker.volumes.enabled` option to `true` in the
- [client's configuration](#client-requirements). We recommend using
+ [client's configuration](/nomad/docs/deploy/task-driver/docker#client-requirements). We recommend using
[`mount`](#mount) if you wish to have more control over volume definitions.
```hcl
@@ -608,10 +611,10 @@ you will need to specify credentials in your job via:
- the `auth` option in the task config.
- by storing explicit repository credentials or by specifying Docker
- `credHelpers` in a file and setting the auth [config](#plugin_auth_file)
+ `credHelpers` in a file and setting the auth [config](/nomad/docs/deploy/task-driver/docker#config)
value on the client in the plugin options.
-- by specifying an auth [helper](#plugin_auth_helper) on the client in the
+- by specifying an auth [helper](/nomad/docs/deploy/task-driver/docker#helper) on the client in the
plugin options.
The `auth` object supports the following keys:
@@ -817,473 +820,28 @@ Some networking modes like `container` or `none` will require coordination
outside of Nomad. First-class support for these options may be improved later
through Nomad plugins or dynamic job configuration.
-## Capabilities
-
-The `docker` driver implements the following [capabilities](/nomad/docs/concepts/plugins/task-drivers#capabilities-capabilities-error).
-
-| Feature | Implementation |
-| -------------------- | ----------------- |
-| `nomad alloc signal` | true |
-| `nomad alloc exec` | true |
-| filesystem isolation | image |
-| network isolation | host, group, task |
-| volume mounting | all |
-
-## Client Requirements
-
-Nomad requires Docker to be installed and running on the host alongside the
-Nomad agent.
-
-By default Nomad communicates with the Docker daemon using the daemon's Unix
-socket. Nomad will need to be able to read/write to this socket. If you do not
-run Nomad as root, make sure you add the Nomad user to the Docker group so
-Nomad can communicate with the Docker daemon.
-
-For example, on Ubuntu you can use the `usermod` command to add the `nomad`
-user to the `docker` group so you can run Nomad without root:
-
-```shell-session
-$ sudo usermod -G docker -a nomad
-```
-
-Nomad clients manage a cpuset cgroup for each task to reserve or share CPU
-[cores][]. In order for Nomad to be compatible with Docker's own cgroups
-management, it must write to cgroups owned by Docker, which requires running as
-root. If Nomad is not running as root, CPU isolation and NUMA-aware scheduling
-will not function correctly for workloads with `resources.cores`, including
-workloads using task drivers other than `docker` on the same host.
-
-For the best performance and security features you should use recent versions
-of the Linux Kernel and Docker daemon.
-
-If you would like to change any of the options related to the `docker` driver
-on a Nomad client, you can modify them with the [plugin block][plugin-block]
-syntax. Below is an example of a configuration (many of the values are the
-default). See the next section for more information on the options.
-
-```hcl
-plugin "docker" {
- config {
- endpoint = "unix:///var/run/docker.sock"
-
- auth {
- config = "/etc/docker-auth.json"
- helper = "ecr-login"
- }
-
- tls {
- cert = "/etc/nomad/nomad.pub"
- key = "/etc/nomad/nomad.pem"
- ca = "/etc/nomad/nomad.cert"
- }
-
- extra_labels = ["job_name", "job_id", "task_group_name", "task_name", "namespace", "node_name", "node_id"]
-
- gc {
- image = true
- image_delay = "3m"
- container = true
-
- dangling_containers {
- enabled = true
- dry_run = false
- period = "5m"
- creation_grace = "5m"
- }
- }
-
- volumes {
- enabled = true
- selinuxlabel = "z"
- }
-
- allow_privileged = false
- allow_caps = ["chown", "net_raw"]
- }
-}
-```
-
-## Plugin Options
-
-- `endpoint` - If using a non-standard socket, HTTP or another location, or if
- TLS is being used, docker.endpoint must be set. If unset, Nomad will attempt
- to instantiate a Docker client using the `DOCKER_HOST` environment variable and
- then fall back to the default listen address for the given operating system.
- Defaults to `unix:///var/run/docker.sock` on Unix platforms and
- `npipe:////./pipe/docker_engine` for Windows.
-
-- `allow_privileged` - Defaults to `false`. Changing this to true will allow
- containers to use privileged mode, which gives the containers full access to
- the host's devices. Note that you must set a similar setting on the Docker
- daemon for this to work.
-
-- `pull_activity_timeout` - Defaults to `2m`. If Nomad receives no communication
- from the Docker engine during an image pull within this timeframe, Nomad will
- time out the request that initiated the pull command. (Minimum of `1m`)
-
-- `pids_limit` - Defaults to unlimited (`0`). An integer value that specifies
- the pid limit for all the Docker containers running on that Nomad client. You
- can override this limit by setting [`pids_limit`] in your task config. If
- this value is greater than `0`, your task `pids_limit` must be less than or
- equal to the value defined here.
-
-- `allow_caps` - A list of allowed Linux capabilities. Defaults to
-
-```hcl
-["audit_write", "chown", "dac_override", "fowner", "fsetid", "kill", "mknod",
- "net_bind_service", "setfcap", "setgid", "setpcap", "setuid", "sys_chroot"]
-```
-
- which is the same list of capabilities allowed by [docker by
- default][docker_caps] (without [`NET_RAW`][no_net_raw]). Allows the operator
- to control which capabilities can be obtained by tasks using
- [`cap_add`][cap_add] and [`cap_drop`][cap_drop] options. Supports the value
- `"all"` as a shortcut for allow-listing all capabilities supported by the
- operating system. Note that due to a limitation in Docker, tasks running as
- non-root users cannot expand the capabilities set beyond the default. They can
- only have their capabilities reduced.
-
-!> **Warning:** Allowing more capabilities beyond the default may lead to
-undesirable consequences, including untrusted tasks being able to compromise the
-host system.
-
-- `allow_runtimes` - defaults to `["runc", "nvidia"]` - A list of the allowed
- docker runtimes a task may use.
-
-- `auth` block:
-
- - `config` - Allows an operator to specify a
- JSON file which is in the dockercfg format containing authentication
- information for a private registry, from either (in order) `auths`,
- `credsStore` or `credHelpers`.
-
- - `helper` - Allows an operator to specify a
- [credsStore](https://docs.docker.com/engine/reference/commandline/login/#credential-helper-protocol)
- like script on `$PATH` to lookup authentication information from external
- sources. The script's name must begin with `docker-credential-` and this
- option should include only the basename of the script, not the path.
-
- If you set an auth helper, it will be tried for all images, including
- public images. If you mix private and public images, you will need to
- include [`auth_soft_fail=true`] in every job using a public image.
-
-- `tls` block:
-
- - `cert` - Path to the server's certificate file (`.pem`). Specify this
- along with `key` and `ca` to use a TLS client to connect to the docker
- daemon. `endpoint` must also be specified or this setting will be ignored.
-
- - `key` - Path to the client's private key (`.pem`). Specify this along with
- `cert` and `ca` to use a TLS client to connect to the docker daemon.
- `endpoint` must also be specified or this setting will be ignored.
-
- - `ca` - Path to the server's CA file (`.pem`). Specify this along with
- `cert` and `key` to use a TLS client to connect to the docker daemon.
- `endpoint` must also be specified or this setting will be ignored.
-
-- `disable_log_collection` - Defaults to `false`. Setting this to true will
- disable Nomad logs collection of Docker tasks. If you don't rely on nomad log
- capabilities and exclusively use host based log aggregation, you may consider
- this option to disable nomad log collection overhead.
-
-- `extra_labels` - Extra labels to add to Docker containers.
- Available options are `job_name`, `job_id`, `task_group_name`, `task_name`,
- `namespace`, `node_name`, `node_id`. Globs are supported (e.g. `task*`)
-
-- `logging` block:
-
- - `type` - Defaults to `"json-file"`. Specifies the logging driver docker
- should use for all containers Nomad starts. Note that for older versions
- of Docker, only `json-file` file or `journald` will allow Nomad to read
- the driver's logs via the Docker API, and this will prevent commands such
- as `nomad alloc logs` from functioning.
-
- - `config` - Defaults to `{ max-file = "2", max-size = "2m" }`. This option
- can also be used to pass further
- [configuration](https://docs.docker.com/config/containers/logging/configure/)
- to the logging driver.
-
-- `gc` block:
-
- - `image` - Defaults to `true`. Changing this to `false` will prevent Nomad
- from removing images from stopped tasks.
-
- - `image_delay` - A time duration, as [defined
- here](https://golang.org/pkg/time/#ParseDuration), that defaults to `3m`.
- The delay controls how long Nomad will wait between an image being unused
- and deleting it. If a task is received that uses the same image within
- the delay, the image will be reused. If an image is referenced by more than
- one tag, `image_delay` may not work correctly.
-
- - `container` - Defaults to `true`. This option can be used to disable Nomad
- from removing a container when the task exits. Under a name conflict,
- Nomad may still remove the dead container.
-
- - `dangling_containers` block for controlling dangling container detection
- and cleanup:
-
- - `enabled` - Defaults to `true`. Enables dangling container handling.
-
- - `dry_run` - Defaults to `false`. Only log dangling containers without
- cleaning them up.
-
- - `period` - Defaults to `"5m"`. A time duration that controls interval
- between Nomad scans for dangling containers.
-
- - `creation_grace` - Defaults to `"5m"`. Grace period after a container is
- created during which the GC ignores it. Only used to prevent the GC from
- removing newly created containers before they are registered with the
- GC. Should not need adjusting higher but may be adjusted lower to GC
- more aggressively.
-
-- `volumes` block:
-
- - `enabled` - Defaults to `false`. Allows tasks to bind host paths
- (`volumes`) inside their container and use volume drivers
- (`volume_driver`). Binding relative paths is always allowed and will be
- resolved relative to the allocation's directory.
-
- - `selinuxlabel` - Allows the operator to set a SELinux label to the
- allocation and task local bind-mounts to containers. If used with
- `docker.volumes.enabled` set to false, the labels will still be applied to
- the standard binds in the container.
-
-- `infra_image` - This is the Docker image to use when creating the parent
- container necessary when sharing network namespaces between tasks. Defaults to
- `registry.k8s.io/pause-:3.3`. The image will only be pulled from the
- container registry if its tag is `latest` or the image doesn't yet exist
- locally.
-
-- `infra_image_pull_timeout` - A time duration that controls how long Nomad will
- wait before cancelling an in-progress pull of the Docker image as specified in
- `infra_image`. Defaults to `"5m"`.
-
-- `image_pull_timeout` - (Optional) A default time duration that controls how long Nomad
- waits before cancelling an in-progress pull of the Docker image as specified
- in `image` across all tasks. Defaults to `"5m"`.
-
-- `windows_allow_insecure_container_admin` - Indicates that on windows, docker
- checks the `task.user` field or, if unset, the container image manifest after
- pulling the container, to see if it's running as `ContainerAdmin`. If so, exits
- with an error unless the task config has `privileged=true`. Defaults to `false`.
-
-## Client Configuration
-
-~> Note: client configuration options will soon be deprecated. Please use
-[plugin options][plugin-options] instead. See the [plugin block][plugin-block]
-documentation for more information.
-
-The `docker` driver has the following [client configuration
-options](/nomad/docs/configuration/client#options):
-
-- `docker.endpoint` - If using a non-standard socket, HTTP or another location,
- or if TLS is being used, `docker.endpoint` must be set. If unset, Nomad will
- attempt to instantiate a Docker client using the `DOCKER_HOST` environment
- variable and then fall back to the default listen address for the given
- operating system. Defaults to `unix:///var/run/docker.sock` on Unix platforms
- and `npipe:////./pipe/docker_engine` for Windows.
-
-- `docker.auth.config` - Allows an operator to specify a
- JSON file which is in the dockercfg format containing authentication
- information for a private registry, from either (in order) `auths`,
- `credsStore` or `credHelpers`.
-
-- `docker.auth.helper` - Allows an operator to specify a
- [credsStore](https://docs.docker.com/engine/reference/commandline/login/#credential-helper-protocol)
- -like script on \$PATH to lookup authentication information from external
- sources. The script's name must begin with `docker-credential-` and this
- option should include only the basename of the script, not the path.
-
-- `docker.tls.cert` - Path to the server's certificate file (`.pem`). Specify
- this along with `docker.tls.key` and `docker.tls.ca` to use a TLS client to
- connect to the docker daemon. `docker.endpoint` must also be specified or this
- setting will be ignored.
-
-- `docker.tls.key` - Path to the client's private key (`.pem`). Specify this
- along with `docker.tls.cert` and `docker.tls.ca` to use a TLS client to
- connect to the docker daemon. `docker.endpoint` must also be specified or this
- setting will be ignored.
-
-- `docker.tls.ca` - Path to the server's CA file (`.pem`). Specify this along
- with `docker.tls.cert` and `docker.tls.key` to use a TLS client to connect to
- the docker daemon. `docker.endpoint` must also be specified or this setting
- will be ignored.
-
-- `docker.cleanup.image` Defaults to `true`. Changing this to `false` will
- prevent Nomad from removing images from stopped tasks.
-
-- `docker.cleanup.image.delay` A time duration, as [defined
- here](https://golang.org/pkg/time/#ParseDuration), that defaults to `3m`. The
- delay controls how long Nomad will wait between an image being unused and
- deleting it. If a tasks is received that uses the same image within the delay,
- the image will be reused.
-
-- `docker.volumes.enabled`: Defaults to `false`. Allows tasks to bind host paths
- (`volumes`) inside their container and use volume drivers (`volume_driver`).
- Binding relative paths is always allowed and will be resolved relative to the
- allocation's directory.
-
-- `docker.volumes.selinuxlabel`: Allows the operator to set a SELinux label to
- the allocation and task local bind-mounts to containers. If used with
- `docker.volumes.enabled` set to false, the labels will still be applied to the
- standard binds in the container.
-
-- `docker.privileged.enabled` Defaults to `false`. Changing this to `true` will
- allow containers to use `privileged` mode, which gives the containers full
- access to the host's devices. Note that you must set a similar setting on the
- Docker daemon for this to work.
-
-- `docker.caps.allowlist`: A list of allowed Linux capabilities. Defaults to
- `"CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID,SETUID,SETFCAP, SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE"`, which is the list of
- capabilities allowed by docker by default, as [defined
- here](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).
- Allows the operator to control which capabilities can be obtained by tasks
- using `cap_add` and `cap_drop` options. Supports the value `"ALL"` as a
- shortcut for allowlisting all capabilities.
-
-- `docker.cleanup.container`: Defaults to `true`. This option can be used to
- disable Nomad from removing a container when the task exits. Under a name
- conflict, Nomad may still remove the dead container.
-
-- `docker.nvidia_runtime`: Defaults to `nvidia`. This option allows operators to select the runtime that should be used in order to expose Nvidia GPUs to the container.
-
-Note: When testing or using the `-dev` flag you can use `DOCKER_HOST`,
-`DOCKER_TLS_VERIFY`, and `DOCKER_CERT_PATH` to customize Nomad's behavior. If
-`docker.endpoint` is set Nomad will **only** read client configuration from the
-config file.
-
-An example is given below:
-
-```hcl
-client {
- options {
- "docker.cleanup.image" = "false"
- }
-}
-```
-
-## Client Attributes
-
-The `docker` driver will set the following client attributes:
-
-- `driver.docker` - This will be set to "1", indicating the driver is
- available.
-
-- `driver.docker.bridge_ip` - The IP of the Docker bridge network if one
- exists.
-
-- `driver.docker.version` - This will be set to version of the docker server.
-
-Here is an example of using these properties in a job file:
-
-```hcl
-job "docs" {
- # Require docker version higher than 1.2.
- constraint {
- attribute = "${attr.driver.docker.version}"
- operator = ">"
- version = "1.2"
- }
-}
-```
-
-## Resource Isolation
-
-### CPU
-
-Nomad limits containers' CPU based on CPU shares. CPU shares allow containers
-to burst past their CPU limits. CPU limits will only be imposed when there is
-contention for resources. When the host is under load your process may be
-throttled to stabilize QoS depending on how many shares it has. You can see how
-many CPU shares are available to your process by reading [`NOMAD_CPU_LIMIT`][runtime_env].
-1000 shares are approximately equal to 1 GHz.
-
-Please keep the implications of CPU shares in mind when you load test workloads
-on Nomad.
-
-If resources [`cores`][cores] is set, the task is given an isolated reserved set of
-CPU cores to make use of. The total set of cores the task may run on is the private
-set combined with the variable set of unreserved cores. The private set of CPU cores
-is available to your process by reading [`NOMAD_CPU_CORES`][runtime_env].
-
-### Memory
-
-Nomad limits containers' memory usage based on total virtual memory. This means
-that containers scheduled by Nomad cannot use swap. This is to ensure that a
-swappy process does not degrade performance for other workloads on the same
-host.
-
-Since memory is not an elastic resource, you will need to make sure your
-container does not exceed the amount of memory allocated to it, or it will be
-terminated or crash when it tries to malloc. A process can inspect its memory
-limit by reading [`NOMAD_MEMORY_LIMIT`][runtime_env], but will need to track its own memory
-usage. Memory limit is expressed in megabytes so 1024 = 1 GB.
-
-### IO
-
-Nomad's Docker integration does not currently provide QoS around network or
-filesystem IO. These will be added in a later release.
-
-### Security
-
-Docker provides resource isolation by way of
-[cgroups and namespaces](https://docs.docker.com/introduction/understanding-docker/#the-underlying-technology).
-Containers essentially have a virtual file system all to themselves. If you
-need a higher degree of isolation between processes for security or other
-reasons, it is recommended to use full virtualization like
-[QEMU](/nomad/docs/drivers/qemu).
-
-## Caveats
-
-### Dangling Containers
-
-Nomad has a detector and a reaper for dangling Docker containers,
-containers that Nomad starts yet does not manage or track. Though rare, they
-lead to unexpectedly running services, potentially with stale versions.
-
-When Docker daemon becomes unavailable as Nomad starts a task, it is possible
-for Docker to successfully start the container but return a 500 error code from
-the API call. In such cases, Nomad retries and eventually aims to kill such
-containers. However, if the Docker Engine remains unhealthy, subsequent retries
-and stop attempts may still fail, and the started container becomes a dangling
-container that Nomad no longer manages.
-
-The newly added reaper periodically scans for such containers. It only targets
-containers with a `com.hashicorp.nomad.allocation_id` label, or match Nomad's
-conventions for naming and bind-mounts (i.e. `/alloc`, `/secrets`, `local`).
-Containers that don't match Nomad container patterns are left untouched.
-
-Operators can run the reaper in a dry-run mode, where it only logs dangling
-container ids without killing them, or disable it by setting the
-`gc.dangling_containers` config block.
-
-### Docker for Windows
-
-Docker for Windows only supports running Windows containers. Because Docker for
-Windows is relatively new and rapidly evolving you may want to consult the
-[list of relevant issues on GitHub][winissues].
[faq-win-mac]: /nomad/docs/faq#q-how-to-connect-to-my-host-network-when-using-docker-desktop-windows-and-macos
[winissues]: https://github.com/hashicorp/nomad/issues?q=is%3Aopen+is%3Aissue+label%3Atheme%2Fdriver%2Fdocker+label%3Atheme%2Fplatform-windows
[plugin-options]: #plugin-options
[plugin-block]: /nomad/docs/configuration/plugin
-[allocation working directory]: /nomad/docs/runtime/environment#task-directories 'Task Directories'
+[allocation working directory]: /nomad/docs/reference/runtime-environment-settings#task-directories 'Task Directories'
[`auth_soft_fail=true`]: #auth_soft_fail
-[cap_add]: /nomad/docs/drivers/docker#cap_add
-[cap_drop]: /nomad/docs/drivers/docker#cap_drop
+[cap_add]: /nomad/docs/deploy/task-driver/docker#cap_add
+[cap_drop]: /nomad/docs/deploy/task-driver/docker#cap_drop
[no_net_raw]: /nomad/docs/upgrade/upgrade-specific#nomad-1-1-0-rc1-1-0-5-0-12-12
[upgrade_guide_extra_hosts]: /nomad/docs/upgrade/upgrade-specific#docker-driver
[tini]: https://github.com/krallin/tini
[docker_caps]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
-[allow_caps]: /nomad/docs/drivers/docker#allow_caps
+[allow_caps]: /nomad/docs/deploy/task-driver/docker#allow_caps
[Connect]: /nomad/docs/job-specification/connect
[`bridge`]: /nomad/docs/job-specification/network#bridge
[network block]: /nomad/docs/job-specification/network#bridge-mode
[`network.mode`]: /nomad/docs/job-specification/network#mode
-[`pids_limit`]: /nomad/docs/drivers/docker#pids_limit
+[`pids_limit`]: /nomad/docs/deploy/task-driver/docker#pids_limit
[Windows isolation]: https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container
[cores]: /nomad/docs/job-specification/resources#cores
-[runtime_env]: /nomad/docs/runtime/environment#job-related-variables
+[runtime_env]: /nomad/docs/reference/runtime-environment-settings#job-related-variables
[`--cap-add`]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
[`--cap-drop`]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
[cores]: /nomad/docs/job-specification/resources#cores
diff --git a/website/content/docs/job-declare/task-driver/exec.mdx b/website/content/docs/job-declare/task-driver/exec.mdx
new file mode 100644
index 000000000..94760d656
--- /dev/null
+++ b/website/content/docs/job-declare/task-driver/exec.mdx
@@ -0,0 +1,148 @@
+---
+layout: docs
+page_title: Use the Isolated Fork/Exec task driver in a job
+description: Nomad's Isolated Fork/Exec task driver lets you run binaries using OS isolation primitives. Learn how to use the Isolated Fork/Exec task driver in your jobs. Configure the command to execute with command arguments, namespace isolation, and Linux capabilities.
+---
+
+# Use the Isolated Fork/Exec task driver in a job
+
+Name: `exec`
+
+The `exec` driver is used to execute a particular command for a task. However,
+unlike [`raw_exec`](/nomad/docs/job-declare/task-driver/raw_exec) it uses the
+underlying isolation primitives of the operating system to limit the task's
+access to resources. While simple, since the `exec` driver can invoke any
+command, it can be used to call scripts or other wrappers which provide higher
+level features.
+
+Refer to [Configure the Isolated Fork/Exec task
+driver](/nomad/docs/deploy/task-driver/exec) for capabilities, client
+requirements, and plugin configuration.
+
+## Task Configuration
+
+```hcl
+task "webservice" {
+ driver = "exec"
+
+ config {
+ command = "my-binary"
+ args = ["-flag", "1"]
+ }
+}
+```
+
+The `exec` driver supports the following configuration in the job spec:
+
+- `command` - The command to execute. Must be provided. If executing a binary
+ that exists on the host, the path must be absolute and within the task's
+ [chroot](/nomad/docs/deploy/task-driver/exec#chroot) or in a [host volume][] mounted with a
+ [`volume_mount`][volume_mount] block. The driver will make the binary
+ executable and will search, in order:
+
+ - The `local` directory with the task directory.
+ - The task directory.
+ - Any mounts, in the order listed in the job specification.
+ - The `usr/local/bin`, `usr/bin` and `bin` directories inside the task
+ directory.
+
+ If executing a binary that is downloaded
+ from an [`artifact`](/nomad/docs/job-specification/artifact), the path can be
+ relative from the allocation's root directory.
+
+- `args` - (Optional) A list of arguments to the `command`. References
+ to environment variables or any [interpretable Nomad
+ variables](/nomad/docs/reference/runtime-variable-interpolation) will be interpreted before
+ launching the task.
+
+- `pid_mode` - (Optional) Set to `"private"` to enable PID namespace isolation for
+ this task, or `"host"` to disable isolation. If left unset, the behavior is
+ determined from the [`default_pid_mode`][default_pid_mode] in plugin configuration.
+
+!> **Warning:** If set to `"host"`, other processes running as the same user will
+be able to access sensitive process information like environment variables.
+
+- `ipc_mode` - (Optional) Set to `"private"` to enable IPC namespace isolation for
+ this task, or `"host"` to disable isolation. If left unset, the behavior is
+ determined from the [`default_ipc_mode`][default_ipc_mode] in plugin configuration.
+
+!> **Warning:** If set to `"host"`, other processes running as the same user will be
+able to make use of IPC features, like sending unexpected POSIX signals.
+
+- `cap_add` - (Optional) A list of Linux capabilities to enable for the task.
+ Effective capabilities (computed from `cap_add` and `cap_drop`) must be a
+ subset of the allowed capabilities configured with [`allow_caps`][allow_caps].
+ Note that `"all"` is not permitted here if the `allow_caps` field in the
+ driver configuration doesn't also allow all capabilities.
+
+```hcl
+config {
+ cap_add = ["net_raw", "sys_time"]
+}
+```
+
+- `cap_drop` - (Optional) A list of Linux capabilities to disable for the task.
+ Effective capabilities (computed from `cap_add` and `cap_drop`) must be a subset
+ of the allowed capabilities configured with [`allow_caps`][allow_caps].
+
+```hcl
+config {
+ cap_drop = ["all"]
+ cap_add = ["chown", "sys_chroot", "mknod"]
+}
+```
+
+- `work_dir` - (Optional) Sets a custom working directory for the task. This path must be
+ absolute and within the task's [chroot](/nomad/docs/deploy/task-driver/exec#chroot) or in a [host volume][] mounted
+ with a [`volume_mount`][volume_mount] block. This will also change the working
+ directory when using `nomad alloc exec`.
+
+## Examples
+
+To run a binary present on the Node:
+
+```hcl
+task "example" {
+ driver = "exec"
+
+ config {
+ # When running a binary that exists on the host, the path must be absolute.
+ command = "/bin/sleep"
+ args = ["1"]
+ }
+}
+```
+
+To execute a binary downloaded from an
+[`artifact`](/nomad/docs/job-specification/artifact):
+
+```hcl
+task "example" {
+ driver = "exec"
+
+ config {
+ command = "name-of-my-binary"
+ }
+
+ artifact {
+ source = "https://internal.file.server/name-of-my-binary"
+ options {
+ checksum = "sha256:abd123445ds4555555555"
+ }
+ }
+}
+```
+
+
+[default_pid_mode]: /nomad/docs/deploy/task-driver/exec#default_pid_mode
+[default_ipc_mode]: /nomad/docs/deploy/task-driver/exec#default_ipc_mode
+[cap_add]: /nomad/docs/deploy/task-driver/exec#cap_add
+[cap_drop]: /nomad/docs/deploy/task-driver/exec#cap_drop
+[no_net_raw]: /nomad/docs/upgrade/upgrade-specific#nomad-1-1-0-rc1-1-0-5-0-12-12
+[allow_caps]: /nomad/docs/deploy/task-driver/exec#allow_caps
+[docker_caps]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
+[host volume]: /nomad/docs/configuration/client#host_volume-block
+[volume_mount]: /nomad/docs/job-specification/volume_mount
+[cores]: /nomad/docs/job-specification/resources#cores
+[runtime_env]: /nomad/docs/reference/runtime-environment-settings#job-related-variables
+[cgroup controller requirements]: /nomad/docs/deploy/production/requirements#hardening-nomad
diff --git a/website/content/docs/job-declare/task-driver/index.mdx b/website/content/docs/job-declare/task-driver/index.mdx
new file mode 100644
index 000000000..9bceb69a9
--- /dev/null
+++ b/website/content/docs/job-declare/task-driver/index.mdx
@@ -0,0 +1,42 @@
+---
+layout: docs
+page_title: Use Nomad task drivers in jobs
+description: Nomad's bundled task drivers integrate with the host OS to run job tasks in isolation. Review conceptual, installation, usage, and reference information for the Docker, Isolated Fork/Exec, Java, QEMU, and Raw Fork/Exec task drivers.
+---
+
+# Use Nomad task drivers in jobs
+
+Nomad's bundled task drivers integrate with the host OS to run job tasks in
+isolation. Review job usage for the Docker, Isolated
+Fork/Exec, Java, QEMU, and Raw Fork/Exec task drivers.
+
+@include 'task-driver-intro.mdx'
+
+## Nomad task drivers
+
+The Nomad binary contains several bundled task drivers. We also support
+additional task driver plugins that you may install separately.
+
+| Bundled with Nomad | Plugins |
+|----------------------|-----------------------|
+| [Docker] | [Exec2] |
+| [Isolated Fork/Exec] | [Podman] |
+| [Java] | [Virt] |
+| [QEMU] | |
+| [Raw Fork/Exec] | |
+
+Refer to each task driver's page for detailed usage.
+
+## Configure task driver plugins
+
+Refer to [Configure Nomad task drivers](/nomad/docs/deploy/task-driver) for task
+driver plugin configuration details.
+
+[Docker]: /nomad/docs/job-declare/task-driver/docker
+[Exec2]: /nomad/plugins/drivers/exec2
+[Isolated Fork/Exec]: /nomad/docs/job-declare/task-driver/exec
+[Podman]: /nomad/plugins/drivers/podman
+[Java]: /nomad/docs/job-declare/task-driver/java
+[Virt]: /nomad/plugins/drivers/virt
+[QEMU]: /nomad/docs/job-declare/task-driver/qemu
+[Raw Fork/Exec]: /nomad/docs/job-declare/task-driver/raw_exec
diff --git a/website/content/docs/job-declare/task-driver/java.mdx b/website/content/docs/job-declare/task-driver/java.mdx
new file mode 100644
index 000000000..79b2fd2f6
--- /dev/null
+++ b/website/content/docs/job-declare/task-driver/java.mdx
@@ -0,0 +1,154 @@
+---
+layout: docs
+page_title: Use the Java task driver in a job
+description: Nomad's Java task driver lets you run JAR files in your workloads. Learn how to configure a job task that uses the Java task driver. Configure paths, JAR args, JVM options, namespace isolation, work directory, and Linux capabilities.
+---
+
+# Use the Java task driver in a job
+
+Name: `java`
+
+The `java` driver is used to execute Java applications packaged into a Java Jar
+file. The driver requires the Jar file to be accessible from the Nomad
+client via the [`artifact` downloader](/nomad/docs/job-specification/artifact).
+
+Refer to [Configure the Java task driver](/nomad/docs/deploy/task-driver/java)
+for capabilities, client requirements, and plugin configuration.
+
+## Task Configuration
+
+```hcl
+task "webservice" {
+ driver = "java"
+
+ config {
+ jar_path = "local/example.jar"
+ jvm_options = ["-Xmx2048m", "-Xms256m"]
+ }
+}
+```
+
+The `java` driver supports the following configuration in the job spec:
+
+- `class` - (Optional) The name of the class to run. If `jar_path` is specified
+ and the manifest specifies a main class, this is optional. If shipping classes
+ rather than a Jar, please specify the class to run and the `class_path`.
+
+- `class_path` - (Optional) The `class_path` specifies the class path used by
+ Java to lookup classes and Jars.
+
+- `jar_path` - (Optional) The path to the downloaded Jar. In most cases this will just be
+ the name of the Jar. However, if the supplied artifact is an archive that
+ contains the Jar in a subfolder, the path will need to be the relative path
+ (`subdir/from_archive/my.jar`).
+
+- `args` - (Optional) A list of arguments to the Jar's main method. References
+ to environment variables or any [interpretable Nomad
+ variables](/nomad/docs/reference/runtime-variable-interpolation) will be interpreted before
+ launching the task.
+
+- `jvm_options` - (Optional) A list of JVM options to be passed while invoking
+ java. These options are passed without being validated in any way by Nomad.
+
+- `pid_mode` - (Optional) Set to `"private"` to enable PID namespace isolation for
+ this task, or `"host"` to disable isolation. If left unset, the behavior is
+ determined from the [`default_pid_mode`][default_pid_mode] in plugin configuration.
+
+!> **Warning:** If set to `"host"`, other processes running as the same user will
+be able to access sensitive process information like environment variables.
+
+- `ipc_mode` - (Optional) Set to `"private"` to enable IPC namespace isolation for
+ this task, or `"host"` to disable isolation. If left unset, the behavior is
+ determined from the [`default_ipc_mode`][default_ipc_mode] in plugin configuration.
+
+!> **Warning:** If set to `"host"`, other processes running as the same user will be
+able to make use of IPC features, like sending unexpected POSIX signals.
+
+- `cap_add` - (Optional) A list of Linux capabilities to enable for the task.
+ Effective capabilities (computed from `cap_add` and `cap_drop`) must be a
+ subset of the allowed capabilities configured with [`allow_caps`][allow_caps].
+ Note that `"all"` is not permitted here if the `allow_caps` field in the
+ driver configuration doesn't also allow all capabilities.
+
+
+```hcl
+config {
+ cap_add = ["net_raw", "sys_time"]
+}
+```
+
+- `cap_drop` - (Optional) A list of Linux capabilities to disable for the task.
+ Effective capabilities (computed from `cap_add` and `cap_drop`) must be a subset
+ of the allowed capabilities configured with [`allow_caps`][allow_caps].
+
+```hcl
+config {
+ cap_drop = ["all"]
+ cap_add = ["chown", "sys_chroot", "mknod"]
+}
+```
+
+- `work_dir` - (Optional) Sets a custom working directory for the task. This path must be
+ absolute and within the task's [chroot](/nomad/docs/deploy/task-driver/java#chroot) or in a [host volume][] mounted
+ with a [`volume_mount`][volume_mount] block. This will also change the working
+ directory when using `nomad alloc exec`.
+
+## Examples
+
+A simple config block to run a Java Jar:
+
+```hcl
+task "web" {
+ driver = "java"
+
+ config {
+ jar_path = "local/hello.jar"
+ jvm_options = ["-Xmx2048m", "-Xms256m"]
+ }
+
+ # Specifying an artifact is required with the "java" driver. This is the
+ # mechanism to ship the Jar to be run.
+ artifact {
+ source = "https://internal.file.server/hello.jar"
+
+ options {
+ checksum = "md5:123445555555555"
+ }
+ }
+}
+```
+
+A simple config block to run a Java class:
+
+```hcl
+task "web" {
+ driver = "java"
+
+ config {
+ class = "Hello"
+ class_path = "${NOMAD_TASK_DIR}"
+ jvm_options = ["-Xmx2048m", "-Xms256m"]
+ }
+
+ # Specifying an artifact is required with the "java" driver. This is the
+ # mechanism to ship the Jar to be run.
+ artifact {
+ source = "https://internal.file.server/Hello.class"
+
+ options {
+ checksum = "md5:123445555555555"
+ }
+ }
+}
+```
+
+[default_pid_mode]: /nomad/docs/deploy/task-driver/java#default_pid_mode
+[default_ipc_mode]: /nomad/docs/deploy/task-driver/java#default_ipc_mode
+[cap_add]: /nomad/docs/deploy/task-driver/java#cap_add
+[cap_drop]: /nomad/docs/deploy/task-driver/java#cap_drop
+[no_net_raw]: /nomad/docs/upgrade/upgrade-specific#nomad-1-1-0-rc1-1-0-5-0-12-12
+[allow_caps]: /nomad/docs/deploy/task-driver/java#allow_caps
+[docker_caps]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
+[cgroup controller requirements]: /nomad/docs/deploy/production/requirements#hardening-nomad
+[volume_mount]: /nomad/docs/job-specification/volume_mount
+[host volume]: /nomad/docs/configuration/client#host_volume-block
diff --git a/website/content/docs/drivers/qemu.mdx b/website/content/docs/job-declare/task-driver/qemu.mdx
similarity index 56%
rename from website/content/docs/drivers/qemu.mdx
rename to website/content/docs/job-declare/task-driver/qemu.mdx
index ad68dbd91..2eee6c201 100644
--- a/website/content/docs/drivers/qemu.mdx
+++ b/website/content/docs/job-declare/task-driver/qemu.mdx
@@ -1,10 +1,10 @@
---
layout: docs
-page_title: QEMU task driver
-description: Nomad's QEMU task driver provides a generic virtual machine runner that can execute any regular QEMU image. Learn how to use the QEMU task driver in your jobs. Configure image path, driver interface, accelerator, graceful shutdown, guest agent, and port map. Review the QEMU task driver capabilities, plugin options, client requirements, and client attributes such as QEMU version. Learn how the QEMU task driver provides the highest level of workload isolation.
+page_title: Use the QEMU task driver in a job
+description: Nomad's QEMU task driver provides a generic virtual machine runner that can execute any regular QEMU image. Learn how to use the QEMU task driver in your jobs. Configure image path, driver interface, accelerator, graceful shutdown, guest agent, and port map.
---
-# QEMU task driver
+# Use the QEMU task driver in a job
Name: `qemu`
@@ -20,6 +20,9 @@ The `qemu` driver can execute any regular `qemu` image (e.g. `qcow`, `img`,
The driver requires the image to be accessible from the Nomad client via the
[`artifact` downloader](/nomad/docs/job-specification/artifact).
+Refer to [Configure the QEMU task driver](/nomad/docs/deploy/task-driver/qemu)
+for capabilities, client requirements, and plugin configuration.
+
## Task Configuration
```hcl
@@ -105,80 +108,5 @@ task "virtual" {
}
```
-## Capabilities
-
-The `qemu` driver implements the following [capabilities](/nomad/docs/concepts/plugins/task-drivers#capabilities-capabilities-error).
-
-| Feature | Implementation |
-| -------------------- | -------------- |
-| `nomad alloc signal` | false |
-| `nomad alloc exec` | false |
-| filesystem isolation | image |
-| network isolation | none |
-| volume mounting | none |
-
-## Client Requirements
-
-The `qemu` driver requires QEMU to be installed and in your system's `$PATH`.
-The task must also specify at least one artifact to download, as this is the only
-way to retrieve the image being run.
-
-## Client Attributes
-
-The `qemu` driver will set the following client attributes:
-
-- `driver.qemu` - Set to `1` if QEMU is found on the host node. Nomad determines
- this by executing `qemu-system-x86_64 -version` on the host and parsing the output
-- `driver.qemu.version` - Version of `qemu-system-x86_64`, ex: `2.4.0`
-
-Here is an example of using these properties in a job file:
-
-```hcl
-job "docs" {
- # Only run this job where the qemu version is higher than 1.2.3.
- constraint {
- attribute = "${driver.qemu.version}"
- operator = ">"
- value = "1.2.3"
- }
-}
-```
-
-## Plugin Options
-
-```hcl
-plugin "qemu" {
- config {
- image_paths = ["/mnt/image/paths"]
- args_allowlist = ["-drive", "-usbdevice"]
- }
-}
-```
-
-- `image_paths` (`[]string`: `[]`) - Specifies the host paths the QEMU
- driver is allowed to load images from.
-- `args_allowlist` (`[]string`: `[]`) - Specifies the command line
- flags that the [`args`] option is permitted to pass to QEMU. If
- unset, a job submitter can pass any command line flag into QEMU,
- including flags that provide the VM with access to host devices such
- as USB drives. Refer to the [QEMU documentation] for the available
- flags.
-
-## Resource Isolation
-
-Nomad uses QEMU to provide full software virtualization for virtual machine
-workloads. Nomad can use QEMU KVM's hardware-assisted virtualization to deliver
-better performance.
-
-Virtualization provides the highest level of isolation for workloads that
-require additional security, and resource use is constrained by the QEMU
-hypervisor rather than the host kernel. VM network traffic still flows through
-the host's interface(s).
-
-Note that the strong isolation provided by virtualization only applies
-to the workload once the VM is started. Operators should use the
-`args_allowlist` option to prevent job submitters from accessing
-devices and resources they are not allowed to access.
-
-[`args`]: /nomad/docs/drivers/qemu#args
+[`args`]: /nomad/docs/job-declare/task-driver/qemu#args
[QEMU documentation]: https://www.qemu.org/docs/master/system/invocation.html
diff --git a/website/content/docs/job-declare/task-driver/raw_exec.mdx b/website/content/docs/job-declare/task-driver/raw_exec.mdx
new file mode 100644
index 000000000..690b60b10
--- /dev/null
+++ b/website/content/docs/job-declare/task-driver/raw_exec.mdx
@@ -0,0 +1,109 @@
+---
+layout: docs
+page_title: Use the Raw Fork/Exec task driver in a job
+description: Nomad's Raw Exec task driver lets you execute commands with no resource isolation. Learn how to use the Raw Fork/Exec task driver in your jobs.
+---
+
+# Use the Raw Fork/Exec task driver in a job
+
+Name: `raw_exec`
+
+The `raw_exec` driver is used to execute a command for a task without any
+isolation. Further, the task is started as the same user as the Nomad process.
+As such, it should be used with extreme care and is disabled by default.
+
+Refer to [Configure the Raw Fork/Exec task
+driver](/nomad/docs/job-declare/task-driver/raw_exec) for capabilities, client
+requirements, and plugin configuration.
+
+## Task configuration
+
+```hcl
+task "webservice" {
+ driver = "raw_exec"
+
+ config {
+ command = "my-binary"
+ args = ["-flag", "1"]
+ }
+}
+```
+
+The `raw_exec` driver supports the following configuration in the job spec:
+
+- `command` - The command to execute. Must be provided. If executing a binary
+ that exists on the host, the path must be absolute. If executing a binary that
+ is downloaded from an [`artifact`](/nomad/docs/job-specification/artifact), the
+ path can be relative from the allocation's root directory.
+
+- `args` - (Optional) A list of arguments to the `command`. References
+ to environment variables or any [interpretable Nomad
+ variables](/nomad/docs/reference/runtime-variable-interpolation) will be interpreted before
+ launching the task.
+
+- `cgroup_v1_override` - (Optional) A map of controller names to paths. The
+ task will be added to these cgroups. The task will fail if these cgroups do
+ not exist. **WARNING:** May conflict with other Nomad driver's cgroups and
+ have unintended side effects.
+
+- `cgroup_v2_override` - (Optional) Adds the task to a unified cgroup path.
+ Paths may be relative to the cgroupfs root or absolute. **WARNING:** May
+ conflict with other Nomad driver's cgroups and have unintended side
+ effects.
+
+~> On Linux, you cannot set the `task.user` field on a task using the `raw_exec`
+driver if you have hardened the Nomad client according to the
+[production][hardening] guide. On Windows, when Nomad is running as a [system
+service][service], you may specify a less-privileged service user. For example,
+`NT AUTHORITY\LocalService`, `NT AUTHORITY\NetworkService`.
+
+- `oom_score_adj` - (Optional) A positive integer to indicate the likelihood of
+ the task being OOM killed (valid only for Linux). Defaults to 0.
+
+- `work_dir` - (Optional) Sets a custom working directory for the task. This
+ must be an absolute path. This will also change the working directory when
+ using `nomad alloc exec`.
+
+- `denied_envvars` - (Optional) Passes a list of environment variables that
+ the driver should scrub from the task environment. Supports globbing, with "*"
+ wildcard accepted as prefix and/or suffix.
+
+## Examples
+
+To run a binary present on the Node:
+
+```
+task "example" {
+ driver = "raw_exec"
+
+ config {
+ # When running a binary that exists on the host, the path must be absolute/
+ command = "/bin/sleep"
+ args = ["1"]
+ }
+}
+```
+
+To execute a binary downloaded from an [`artifact`](/nomad/docs/job-specification/artifact):
+
+```
+task "example" {
+ driver = "raw_exec"
+
+ config {
+ command = "name-of-my-binary"
+ }
+
+ artifact {
+ source = "https://internal.file.server/name-of-my-binary"
+ options {
+ checksum = "sha256:abd123445ds4555555555"
+ }
+ }
+}
+```
+
+[hardening]: /nomad/docs/deploy/production/requirements#user-permissions
+[service]: /nomad/docs/deploy/production/windows-service
+[plugin-options]: #plugin-options
+[plugin-block]: /nomad/docs/configuration/plugin
diff --git a/website/content/docs/job-declare/vault.mdx b/website/content/docs/job-declare/vault.mdx
new file mode 100644
index 000000000..87ba7fe28
--- /dev/null
+++ b/website/content/docs/job-declare/vault.mdx
@@ -0,0 +1,49 @@
+---
+layout: docs
+page_title: Use Vault in a job
+description: |-
+ Use Vault in your Nomad job.
+---
+
+# Use Vault in a job
+
+## Use a Vault namespace
+
+This example job specifies to use the `engineering` namespace in
+Vault. The job authenticates to Vault using its workload identity with the
+`nomad-workloads` Vault role, reads the value at secret/foo, and fetches the
+value for key `bar`.
+
+```hcl
+job "vault" {
+
+ group "demo" {
+ task "task" {
+ vault {
+ namespace = "engineering"
+ role = "nomad-workloads"
+ }
+
+ driver = "raw_exec"
+ config {
+ command = "/usr/bin/cat"
+ args = ["secrets/config.txt"]
+ }
+
+ template {
+ data = <`.
+
+For example, to use the configuration named `mynet`, you should set the task
+group's network mode to `cni/mynet`.
+
+```hcl
+job "docs" {
+ group "example" {
+ network {
+ mode = "cni/mynet"
+ }
+ }
+}
+```
+
+Nodes that have a network configuration defining a network named `mynet` in
+their `cni_config_dir` are eligible to run the workload. Nomad then schedules
+the workload on client nodes that have fingerprinted a CNI configuration with
+the given name.
+
+Nomad additionally supplies the following arguments via `CNI_ARGS` to the CNI
+network: `NOMAD_REGION`, `NOMAD_NAMESPACE`, `NOMAD_JOB_ID`, `NOMAD_GROUP_NAME`,
+and `NOMAD_ALLOC_ID`.
+
+Since the `CNI_ARGS` do not allow values to contain a semicolon, Nomad will not
+set keys where the value contains a semicolon (this could happen with the job
+ID). CNI plugins utilizing `NOMAD_*` CNI arguments are advised to apply a
+defensive policy or simply error out.
diff --git a/website/content/docs/job-networking/index.mdx b/website/content/docs/job-networking/index.mdx
new file mode 100644
index 000000000..ce2cb120b
--- /dev/null
+++ b/website/content/docs/job-networking/index.mdx
@@ -0,0 +1,12 @@
+---
+layout: docs
+page_title: Workload networking
+description: |-
+ This section provides guidance on networking your Nomad workloads. Topics include using a CNI network and Consul service discovery.
+---
+
+# Workload networking
+
+This section provides guidance on networking your Nomad workloads. Topics
+include using a CNI network and Consul service discovery. Refer to the [Nomad
+networking page](/nomad/docs/networking) to learn more about Nomad's networking capabilities.
diff --git a/website/content/docs/job-networking/service-discovery.mdx b/website/content/docs/job-networking/service-discovery.mdx
new file mode 100644
index 000000000..5ffe2df0b
--- /dev/null
+++ b/website/content/docs/job-networking/service-discovery.mdx
@@ -0,0 +1,10 @@
+---
+layout: docs
+page_title: Service Discovery
+description: |-
+ Nomad service discovery helps you automatically connect workloads. Compare Nomad's built-in service discovery feature to Consul service discovery, which adds a DSN interface and service mesh. Learn about health checks, configuring tags in job specification service blocks, and how to specify tags for canary and blue/green allocations.
+---
+
+# Service discovery
+
+@include 'service-discovery.mdx'
diff --git a/website/content/docs/job-run/index.mdx b/website/content/docs/job-run/index.mdx
new file mode 100644
index 000000000..9c5590e03
--- /dev/null
+++ b/website/content/docs/job-run/index.mdx
@@ -0,0 +1,46 @@
+---
+layout: docs
+page_title: Run Nomad jobs
+description: |-
+ This section provides guidance for running Nomad jobs. Inspect job, access logs for troubleshooting, collect resource utilization metrics, and create job versions.
+---
+
+# Run Nomad jobs
+
+This section provides guidance for running Nomad jobs. Inspect job, access logs
+for troubleshooting, collect resource utilization metrics, and create job
+versions.
+
+The following list is the general flow for operating a job in Nomad:
+
+1. Declare the job according to the [job specification](/nomad/docs/job-specification).
+1. Plan and review the changes with a Nomad server.
+1. Submit the job file to a Nomad server.
+1. (Optional) Review job status and logs.
+
+Refer to [Create and submit a job](/nomad/docs/job-declare/create-job) to learn
+how to create a job specification, review the job plan, and submit the job.
+
+## Run a job
+
+Execute the [`nomad job run` command](/nomad/commands/job/run) to run your job.
+
+Now that the job is scheduled, it may or may not be running. You need to inspect
+the allocation status and logs to make sure the job started correctly. Refer to
+the section on [inspecting state](/nomad/docs/job-run/inspect)
+details ways to examine this job's state.
+
+## Update a running job
+
+When updating a job, there are a number of [built-in update
+strategies](/nomad/docs/job-declare/strategy) which may be defined in the job
+file. The general flow for updating an existing job in Nomad is:
+
+1. Modify the existing job file with the desired changes.
+1. Plan and review the changes with a Nomad server.
+1. Submit the job file to a Nomad server.
+1. (Optional) Review job status and logs.
+
+Because the job specification defines the deployment strategy, the workflow
+remains the same regardless of whether this is an initial deployment or a
+long-running job.
diff --git a/website/content/docs/job-run/inspect.mdx b/website/content/docs/job-run/inspect.mdx
new file mode 100644
index 000000000..ca969e369
--- /dev/null
+++ b/website/content/docs/job-run/inspect.mdx
@@ -0,0 +1,212 @@
+---
+layout: docs
+page_title: Inspect running jobs
+description: |-
+ Inspect the status of a running job, the associated evaluation, and allocations to troubleshoot for errors with the Nomad CLI.
+---
+
+# Inspect running jobs
+
+A successful job submission is not an indication of a successfully-running job.
+This is the nature of a highly-optimistic scheduler. A successful job submission
+means the server was able to issue the proper scheduling commands. It does not
+indicate the job is actually running. To verify the job is running and healthy,
+you might need to inspect its state.
+
+This section will utilize the job named "docs", but
+these operations and command largely apply to all jobs in Nomad.
+
+## Query the job status
+
+After a job is submitted, you can query the status of that job using the job
+status command:
+
+```shell-session
+$ nomad job status
+ID Type Priority Status
+docs service 50 running
+```
+
+At a high level, you can observe that the job is currently running, but what
+does "running" actually mean. By supplying the name of a job to the job status
+command, you can ask Nomad for more detailed job information:
+
+```shell-session
+$ nomad job status docs
+ID = docs
+Name = docs
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+example 0 0 3 0 0 0
+
+Allocations
+ID Eval ID Node ID Task Group Desired Status Created At
+04d9627d 42d788a3 a1f934c9 example run running
+e7b8d4f5 42d788a3 012ea79b example run running
+5cbf23a1 42d788a3 1e1aa1e0 example run running
+```
+
+This output shows that there are three instances of this task running, each with
+its own allocation. For more information on the `status` command, please consult
+the [`nomad job status` command] documentation.
+
+## Fetch an evaluation's status
+
+You can think of an evaluation as a submission to the scheduler. An example
+below shows status output for a job where some allocations were placed
+successfully, but did not have enough resources to place all of the desired
+allocations.
+
+If you issue the status command with the `-evals` flag, the output will show
+that there is an outstanding evaluation for this hypothetical job:
+
+```shell-session
+$ nomad job status -evals docs
+ID = docs
+Name = docs
+Type = service
+Priority = 50
+Datacenters = dc1
+Status = running
+Periodic = false
+
+Evaluations
+ID Priority Triggered By Status Placement Failures
+5744eb15 50 job-register blocked N/A - In Progress
+8e38e6cf 50 job-register complete true
+
+Placement Failure
+Task Group "example":
+ * Resources exhausted on 1 nodes
+ * Dimension "cpu" exhausted on 1 nodes
+
+Allocations
+ID Eval ID Node ID Task Group Desired Status Created At
+12681940 8e38e6cf 4beef22f example run running
+395c5882 8e38e6cf 4beef22f example run running
+4d7c6f84 8e38e6cf 4beef22f example run running
+843b07b8 8e38e6cf 4beef22f example run running
+a8bc6d3e 8e38e6cf 4beef22f example run running
+b0beb907 8e38e6cf 4beef22f example run running
+da21c1fd 8e38e6cf 4beef22f example run running
+```
+
+The output states that the job has a "blocked" evaluation that is in progress.
+When Nomad can not place all the desired allocations, it creates a blocked
+evaluation that waits for more resources to become available.
+
+The `eval status` command enables examination of any evaluation in more detail.
+For the most part this should never be necessary. However, it can be useful to
+understand what triggered a specific evaluation and it's current status. Running
+it on the "complete" evaluation provides output similar to the following:
+
+```shell-session
+$ nomad eval status 8e38e6cf
+ID = 8e38e6cf
+Status = complete
+Status Description = complete
+Type = service
+TriggeredBy = job-register
+Job ID = docs
+Priority = 50
+Placement Failures = true
+
+Failed Placements
+Task Group "example" (failed to place 3 allocations):
+ * Resources exhausted on 1 nodes
+ * Dimension "cpu" exhausted on 1 nodes
+
+Evaluation "5744eb15" waiting for additional capacity to place remainder
+```
+
+This output indicates that the evaluation was created by a "job-register" event
+and that it had placement failures. The evaluation also has the information on
+why placements failed. Also output is the evaluation of any follow-up
+evaluations created.
+
+If you would like to learn more about this output, consult the documentation for
+[`nomad eval status` command].
+
+## Retrieve an allocation's status
+
+You can think of an allocation as an instruction to schedule. Like an
+application or service, an allocation has logs and state. The `alloc status`
+command gives the most recent events that occurred for a task, its resource
+usage, port allocations and more:
+
+```shell-session
+$ nomad alloc status 04d9627d
+ID = 04d9627d
+Eval ID = 42d788a3
+Name = docs.example[2]
+Node ID = a1f934c9
+Job ID = docs
+Client Status = running
+
+Task "server" is "running"
+Task Resources
+CPU Memory Disk Addresses
+0/100 MHz 728 KiB/10 MiB 300 MiB http: 10.1.1.196:5678
+
+Recent Events:
+Time Type Description
+10/09/16 00:36:06 UTC Started Task started by client
+10/09/16 00:36:05 UTC Received Task received by client
+```
+
+The [`nomad alloc status` command] is a good starting to point for debugging an
+application that did not start. Hypothetically assume a user meant to start a
+Docker container named "redis:2.8", but accidentally put a comma instead of a
+period, typing "redis:2,8".
+
+When the job is executed, it produces a failed allocation. The `nomad alloc status` command will give the reason why.
+
+```shell-session
+$ nomad alloc status 04d9627d
+ID = 04d9627d
+...
+
+Recent Events:
+Time Type Description
+06/28/16 15:50:22 UTC Not Restarting Error was unrecoverable
+06/28/16 15:50:22 UTC Driver Failure failed to create image: Failed to pull `redis:2,8`: API error (500): invalid tag format
+06/28/16 15:50:22 UTC Received Task received by client
+```
+
+Unfortunately not all failures are as visible in the allocation status output.
+If the `alloc status` command shows many restarts, there is likely an
+application-level issue during start up. For example:
+
+```shell-session
+$ nomad alloc status 04d9627d
+ID = 04d9627d
+...
+
+Recent Events:
+Time Type Description
+06/28/16 15:56:16 UTC Restarting Task restarting in 5.178426031s
+06/28/16 15:56:16 UTC Terminated Exit Code: 1, Exit Message: "Docker container exited with non-zero exit code: 1"
+06/28/16 15:56:16 UTC Started Task started by client
+06/28/16 15:56:00 UTC Restarting Task restarting in 5.00123931s
+06/28/16 15:56:00 UTC Terminated Exit Code: 1, Exit Message: "Docker container exited with non-zero exit code: 1"
+06/28/16 15:55:59 UTC Started Task started by client
+06/28/16 15:55:48 UTC Received Task received by client
+```
+
+To debug these failures, you can use the `nomad alloc logs` command, which is
+discussed in the [accessing logs] section of this documentation.
+
+For more information on the `alloc status` command, please consult the
+documentation for the [`nomad alloc status` command].
+
+[accessing logs]: /nomad/docs/job-run/logs
+[`nomad alloc status` command]: /nomad/commands/alloc/status
+[`nomad eval status` command]: /nomad/commands/eval/status
+[`nomad job status` command]: /nomad/commands/job/status
+
diff --git a/website/content/docs/job-run/logs.mdx b/website/content/docs/job-run/logs.mdx
new file mode 100644
index 000000000..e0c845e06
--- /dev/null
+++ b/website/content/docs/job-run/logs.mdx
@@ -0,0 +1,128 @@
+---
+layout: docs
+page_title: Access job logs for troubleshooting
+description: |-
+ Access logs of applications running in Nomad with the Nomad CLI or API.
+---
+
+# Access job logs for troubleshooting
+
+Viewing application logs is critical for debugging issues, examining performance
+problems, or even verifying the application started correctly. To make this
+as simple as possible, Nomad provides:
+
+- Job specification for [log rotation](/nomad/docs/job-specification/logs)
+- CLI command for [log viewing](/nomad/commands/alloc/logs)
+- API for programmatic [log access](/nomad/api-docs/client#stream-logs)
+
+This section will use the job named "docs", but
+these operations and command largely apply to all jobs in Nomad.
+
+As a reminder, here is the output of the run command from the previous example:
+
+```shell-session
+$ nomad job run docs.nomad.hcl
+==> Monitoring evaluation "42d788a3"
+ Evaluation triggered by job "docs"
+ Allocation "04d9627d" created: node "a1f934c9", group "example"
+ Allocation "e7b8d4f5" created: node "012ea79b", group "example"
+ Allocation "5cbf23a1" modified: node "1e1aa1e0", group "example"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "42d788a3" finished with status "complete"
+```
+
+The provided allocation ID (which is also available via the `nomad status`
+command) is required to access the application's logs. To access the logs of our
+application, issue the following command:
+
+```shell-session
+$ nomad alloc logs 04d9627d
+```
+
+The output will look something like this:
+
+```plaintext
+ 10.1.1.196:5678 10.1.1.196:33407 "GET / HTTP/1.1" 200 12 "curl/7.35.0" 21.809µs
+ 10.1.1.196:5678 10.1.1.196:33408 "GET / HTTP/1.1" 200 12 "curl/7.35.0" 20.241µs
+ 10.1.1.196:5678 10.1.1.196:33409 "GET / HTTP/1.1" 200 12 "curl/7.35.0" 13.629µs
+```
+
+By default, this will return the logs of the task. If more than one task is
+defined in the job file, the name of the task is a required argument:
+
+```shell-session
+$ nomad alloc logs 04d9627d server
+```
+
+The logs command supports both displaying the logs as well as following logs,
+blocking for more output, similar to `tail -f`. To follow the logs, use the
+appropriately named `-f` flag:
+
+```shell-session
+$ nomad alloc logs -f 04d9627d
+```
+
+This will stream logs to your console.
+
+If you are only interested in the "tail" of the log, use the `-tail` and `-n`
+flags:
+
+```shell-session
+$ nomad alloc logs -tail -n 25 04d9627d
+```
+
+This will show the last 25 lines. If you omit the `-n` flag, `-tail` will
+default to 10 lines.
+
+By default, only the logs on stdout are displayed. To show the log output from
+stderr, use the `-stderr` flag:
+
+```shell-session
+$ nomad alloc logs -stderr 04d9627d
+```
+
+## Consider the "log shipper" pattern
+
+While the logs command works well for quickly accessing application logs, it
+generally does not scale to large systems or systems that produce a lot of log
+output, especially for the long-term storage of logs. Nomad's retention of log
+files is best effort, so chatty applications should use a better log retention
+strategy.
+
+Since applications log to the `alloc/` directory, all tasks within the same task
+group have access to each others logs. Thus it is possible to have a task group
+as follows:
+
+```hcl
+group "my-group" {
+ task "server" {
+ # ...
+
+ # Setting the server task as the leader of the task group allows Nomad to
+ # signal the log shipper task to gracefully shutdown when the server exits.
+ leader = true
+ }
+
+ task "log-shipper" {
+ # ...
+ }
+}
+```
+
+In the above example, the `server` task is the application that should be run
+and will be producing the logs. The `log-shipper` reads those logs from the
+`alloc/logs/` directory and sends them to a longer-term storage solution such as
+Amazon S3 or an internal log aggregation system.
+
+When using the log shipper pattern, especially for batch jobs, the main task
+should be marked as the [leader task]. By marking the main task as a leader,
+when the task completes all other tasks within the group will be gracefully
+shutdown. This allows the log shipper to finish sending any logs and then
+exiting itself. The log shipper should set a high enough [`kill_timeout`] such
+that it can ship any remaining logs before exiting.
+
+[log rotation]: /nomad/docs/job-specification/logs
+[log viewing]: /nomad/commands/alloc/logs
+[log access]: /nomad/api-docs/client#stream-logs
+[leader task]: /nomad/docs/job-specification/task#leader
+[`kill_timeout`]: /nomad/docs/job-specification/task#kill_timeout
diff --git a/website/content/docs/job-run/utilization-metrics.mdx b/website/content/docs/job-run/utilization-metrics.mdx
new file mode 100644
index 000000000..76c243c7e
--- /dev/null
+++ b/website/content/docs/job-run/utilization-metrics.mdx
@@ -0,0 +1,91 @@
+---
+layout: docs
+page_title: Collect resource utilization metrics
+description: |-
+ Inspect the resource consumption and utilization information of a job with
+ the task drivers in Nomad.
+---
+
+# Collect resource utilization metrics
+
+Understanding the resource utilization of an application is important, and Nomad
+supports reporting detailed statistics in many of its drivers. The main
+interface for outputting resource utilization is the `alloc status` command with
+the `-stats` flag.
+
+This section will use the job named "docs", but
+these operations and command largely apply to all jobs in Nomad.
+
+Here is the output of the run command for the "docs" job.
+
+```shell-session
+$ nomad job run docs.nomad.hcl
+==> Monitoring evaluation "42d788a3"
+ Evaluation triggered by job "docs"
+ Allocation "04d9627d" created: node "a1f934c9", group "example"
+ Allocation "e7b8d4f5" created: node "012ea79b", group "example"
+ Allocation "5cbf23a1" modified: node "1e1aa1e0", group "example"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "42d788a3" finished with status "complete"
+```
+
+To fetch the detailed usage statistics, issue the following command. Your
+allocation id will be different; replace `04d9627d` with the allocation id from
+your running "docs" job:
+
+```shell-session
+$ nomad alloc status -stats 04d9627d
+ID = 04d9627d
+Eval ID = 42d788a3
+Name = docs.example[2]
+Node ID = a1f934c9
+Job ID = docs
+Client Status = running
+
+Task "server" is "running"
+Task Resources
+CPU Memory Disk Addresses
+75/100 MHz 784 KiB/10 MiB 300 MiB http: 10.1.1.196:5678
+
+Memory Stats
+Cache Max Usage RSS Swap
+56 KiB 1.3 MiB 784 KiB 0 B
+
+CPU Stats
+Percent Throttled Periods Throttled Time
+0.00% 0 0
+
+Recent Events:
+Time Type Description
+ Started Task started by client
+ Received Task received by client
+```
+
+The output indicates that the job is running near the limit of configured CPU
+but has plenty of memory headroom. You can use this information to alter the
+job's resources to better reflect its actual needs:
+
+```hcl
+resources {
+ cpu = 200
+ memory = 10
+}
+```
+
+Adjusting resources is very important for a variety of reasons:
+
+- Ensuring your application does not get OOM killed if it hits its memory limit.
+- Ensuring the application performs well by ensuring it has some CPU allowance.
+- Optimizing cluster density by reserving what you need and not over-allocating.
+
+While single point in time resource usage measurements are useful, it is often
+more useful to graph resource usage over time to better understand and estimate
+resource usage. Nomad supports outputting resource data to statsite and statsd
+and is the recommended way of monitoring resources. For more information about
+outputting telemetry, consult the [Telemetry Guide].
+
+For more advanced use cases, the resource usage data is also accessible via the
+client's HTTP API. Learn more about it in the [`allocation` API] documentation.
+
+[telemetry guide]:/nomad/docs/monitor
+[`allocation` api]: /nomad/api-docs/client
diff --git a/website/content/docs/job-run/versions.mdx b/website/content/docs/job-run/versions.mdx
new file mode 100644
index 000000000..592a687f0
--- /dev/null
+++ b/website/content/docs/job-run/versions.mdx
@@ -0,0 +1,552 @@
+---
+layout: docs
+page_title: Create and modify job versions
+description: |-
+ Create, modify, delete, compare, and revert job versions with the Nomad CLI, API, or UI.
+---
+
+# Create and modify job versions
+
+Nomad creates a new version for your job each time you run your job. A job can
+have an unlimited number of versions, and version history is stored in state.
+Over time, Nomad garbage collects dead versions that do not have a version tag. Saving a tag to a version prevents Nomad from garbage collecting that version.
+
+This guide demonstrates the following job version features:
+
+- Create, modify, and delete job version tags.
+- Compare versions.
+- Revert a running job to an older version, no matter how much time has passed.
+- Clone a version.
+
+## Prerequisites
+
+- This feature requires Nomad v1.9.0 and later.
+- You are familiar with [job versions and tags][job-concept].
+
+## Create the `hello-world` job
+
+The examples use a job named `hello-world`, which is one of Nomad's job
+templates.
+
+1. On the **Jobs** page, click **Run Job**.
+1. Click **Choose from template**.
+1. Select **Hello world**.
+1. Click **Apply**.
+1. Click **Plan**.
+1. Review the **Job Plan** output.
+1. Click **Run** to run the `hello-world` job.
+
+## Create a version tag
+
+When you create a version tag, you should provide Nomad with these attributes:
+
+- A tag name
+- A job name
+- A version number
+
+The following example creates a tag named `golden-version` for version zero of `hello-world`. It includes a description of the tag.
+
+
+
+
+Use the `nomad job tag apply [options] ` command to create a tag.
+
+```shell-session
+$ nomad job tag apply -version 0 -name "golden-version" \
+ -description "The version we can roll back to." \
+ hello-world
+
+Job version 0 tagged with name "golden-version"
+```
+
+Note that Nomad tags the latest version if you omit the version number.
+
+Refer to the [`job tag apply`][job-tag-apply-cli] command reference for details on
+including general options such as `namespace`.
+
+
+
+
+| Method | Path | Produces |
+| ------ | ----------------- | ------------------ |
+| `POST` | `/v1/job/:job_id/versions/:tag_name/tag` | `application/json` |
+
+This example assumes the Nomad API is accessible on `localhost:4646`.
+
+```shell-session
+$ curl -X POST \
+ localhost:4646/v1/job/hello-world/versions/golden-version/tag \
+ -H "Content-Type: application/json" -d \
+ '{"Version": 0, "Description": "The version we can roll back to."}'
+```
+
+The JSON response is similar to the following example.
+
+```json
+{
+ "Name":"golden-version",
+ "Description":"The version we can roll back to.",
+ "TaggedTime":1728325495829793000,
+ "Index":361,
+ "LastContact":0,
+ "KnownLeader":false,
+ "NextToken":""}
+```
+
+Refer to the Jobs HTTP API [Create Job Version Tag][job-tag-apply-api] reference for
+details on path and payload parameters.
+
+
+
+
+1. From the **Jobs** screen, click the **hello-world** job to display job details.
+1. Click **Versions**.
+1. Find **Version #0** in the list.
+1. Click **Tag this version**.
+1. Enter `golden version` in the **Tag Name** field and `The version we can roll
+ back to.` in the **Tag Description** field.
+1. Click **Save**.
+
+Version zero now has a `golden-version` tag.
+
+
+
+
+
+
+Using the CLI, you can run a new version of your job and create a tag for that
+new version. The following example runs a new version of the hello-world job and
+immediately tags that version.
+
+```shell-session
+$ nomad job run hello-world.nomad.hcl && \
+ nomad job tag apply -name "high-traffic-version" hello-world
+
+==> 2024-10-08T14:42:30-05:00: Monitoring evaluation "90714134"
+ 2024-10-08T14:42:30-05:00: Evaluation triggered by job "hello-world"
+ 2024-10-08T14:42:31-05:00: Evaluation within deployment: "192ecea1"
+ 2024-10-08T14:42:31-05:00: Allocation "ec85c1bd" created: node "d6ee954e", group "servers"
+ 2024-10-08T14:42:31-05:00: Evaluation status changed: "pending" -> "complete"
+==> 2024-10-08T14:42:31-05:00: Evaluation "90714134" finished with status "complete"
+==> 2024-10-08T14:42:31-05:00: Monitoring deployment "192ecea1"
+ ✓ Deployment "192ecea1" successful
+
+ 2024-10-08T14:42:48-05:00
+ ID = 192ecea1
+ Job ID = hello-world
+ Job Version = 4
+ Status = successful
+ Description = Deployment completed successfully
+
+ Deployed
+ Task Group Desired Placed Healthy Unhealthy Progress Deadline
+ servers 1 1 1 0 2024-10-08T14:52:46-05:00
+Job version 1 tagged with name "high-traffic-version"
+```
+
+## Modify a version tag
+
+The following example updates both the name and description of the `golden-version` tag for a hello-world job.
+
+
+
+
+Use the `nomad job tag apply [options] ` command to modify a tag's attributes.
+
+```shell-session
+$ nomad job tag apply -version 0 -name "golden-version-0" \
+ -description "Low traffic version." \
+ hello-world
+
+Job version 0 tagged with name "golden-version-0"
+```
+
+Refer to the [`job tag apply`][job-tag-apply-cli] command reference for details on
+including general options such as `namespace`.
+
+
+
+
+| Method | Path | Produces |
+| ------ | ----------------- | ------------------ |
+| `POST` | `/v1/job/:job_id/versions/:tag_name/tag` | `application/json` |
+
+This example assumes the Nomad API is accessible on `localhost:4646`.
+
+```shell-session
+$ curl -X POST \
+ localhost:4646/v1/job/hello-world/versions/golden-version-0/tag \
+ -H "Content-Type: application/json" -d \
+ '{"Version": 0, "Description": "Low traffic version."}'
+```
+
+The response is similar to the following.
+
+```json
+{
+ "Name":"golden-version-0",
+ "Description":"Low traffic version.",
+ "TaggedTime":1728407951089465000,
+ "Index":3460,
+ "LastContact":0,
+ "KnownLeader":false,
+ "NextToken":""}
+```
+
+See the Jobs HTTP API [Create Job Version Tag][job-tag-apply-api] reference for
+details on path and payload parameters.
+
+
+
+
+1. From the **Jobs** screen, click the **hello-world** job to display job details.
+1. Click **Versions**.
+1. Find **Version #0** in the list.
+1. Click **golden-version**.
+1. Edit the tag name and description.
+1. Click **Save**.
+
+
+
+
+## Delete a version tag
+
+The following example deletes the `golden-version` tag attached to the `hello-world` job.
+
+
+
+
+Use `nomad job tag unset -name "" ` to delete a tag from a version. This command requires a tag name and job ID.
+
+```shell-session
+$ nomad job tag unset -name "golden-version" hello-world
+
+removed from job "hello-world"
+```
+
+Refer to the [`job tag unset`][job-tag-unset-cli] command reference for details on
+including general options such as `namespace`.
+
+
+
+
+| Method | Path | Produces |
+| ------ | ----------------- | ------------------ |
+| `DELETE` | `/v1/job/:job_id/versions/:tag_name/tag` | `application/json` |
+
+This example assumes the Nomad API is accessible on `localhost:4646`.
+
+```shell-session
+$ curl -X DELETE \
+ localhost:4646/v1/job/hello-world/versions/golden-version/tag \
+ -H "Content-Type: application/json"
+```
+
+The response is similar to the following.
+
+```json
+{
+ "Name":"",
+ "Description":"",
+ "TaggedTime":0,
+ "Index":5135,
+ "LastContact":0,
+ "KnownLeader":false,
+ "NextToken":""
+}
+```
+
+Refer to the Jobs HTTP API [Delete Job Version Tag][job-tag-unset-api] reference for
+details on path and payload parameters.
+
+
+
+
+1. From the **Jobs** screen, click the **hello-world** job to display job details.
+1. Click **Versions**.
+1. Find **Version #0** in the list.
+1. Click **golden-version**.
+1. Click **Delete** to remove the tag.
+
+
+
+
+## Compare versions
+
+
+
+
+Use the [`nomad job history -p` command][nomad-job-history-cli] to compare
+different job versions. The `-p` option displays the differences between each
+version and the most recent version. You also have these options:
+
+- `-diff-version`: Specifies the version number of the job to compare against.
+ Mutually exclusive with the `-diff-tag` flag.
+- `-diff-tag`: Specifies the version of the job to compare against, referenced
+ by tag name. Defaults to the latest version. Mutually exclusive with `-diff-version`.
+
+### Show diff based on a version
+
+The `nomad job history -p -diff-version ` command compares all
+versions against the specified `diff-version`.
+
+The following example compares all job versions to version 4.
+
+```shell-session
+$ nomad job history -p -diff-version=4 hello-world
+```
+
+You can also perform a diff between two specific versions. This example compares
+ version 4 of the hello-world job with version 1 of the job.
+
+```shell-session
+$ nomad job history -p -version=4 -diff-version=1 hello-world
+```
+
+### Show diff based on a tag
+
+The `nomad job history -p -diff-tag ` command compares all
+versions against the specified `diff-tag`.
+
+The following example compares all job versions to the version tagged with the name `golden-version`.
+
+```shell-session
+$ nomad job history -p -diff-tag="golden-version" hello-world
+```
+
+You can also perform a diff between a tag and a version number. The following
+example compares the current version, `-version=4`, with the version tagged
+`golden-version`.
+
+```shell-session
+$ nomad job history -p -version=4 -diff-tag="golden-version" hello-world
+
+Version = 4
+Stable = true
+Submit Date = 2024-10-08T14:42:30-05:00
+Tag Name = high-traffic-version
+Diff =
++/- Job: "hello-world"
++/- Task Group: "servers"
+ + Network {
+ Hostname: ""
+ Mode: ""
+ + Dynamic Port {
+ + HostNetwork: "default"
+ + Label: "www"
+ + To: "8002"
+ }
+ }
+ - Network {
+ Hostname: ""
+ Mode: ""
+ - Dynamic Port {
+ - HostNetwork: "default"
+ - Label: "www"
+ - To: "8001"
+ }
+ }
+```
+
+
+
+
+You can get a version list with the `Diffs` field populated. To compare all
+versions to a specific version, use the `diff_version` query parameter.
+
+This example compares all versions to version one.
+
+```shell-session
+$ curl -X GET \
+ localhost:4646/v1/job/hello-world/versions?diffs=true&diff_version=1
+```
+
+Refer to the Jobs HTTP API [List Job Versions][job-list-diff-api] reference for
+details and complete examples.
+
+
+
+
+The job detail's **Versions** tab shows the list of versions.
+
+
+
+The two important elements are the **Diff against** dropdown, labeled "1", and
+the changes show or hide toggle, labeled "2".
+
+The **Diff against** dropdown contains versions or tags that change how the UI
+compares the versions against each other.
+
+
+
+The **Diff against previous version** option means that each version displays
+the difference with the previous version in the list. The **See Change**
+toggle displays the number of changes. Click the **See Change** arrow
+to review the actual difference.
+
+
+
+When you select a version or tag, the UI
+automatically displays the differences each version has with the selected
+version.
+
+
+
+
+
+
+## Revert to a version
+
+Use job tags to revert the current running job to a prior version.
+
+The following examples revert versions of the `hello-world` job to specific version number or tag names.
+
+
+
+
+Use the `nomad job revert [options] ` command to revert
+the current job to a prior version.
+
+This example reverts the job to version three.
+
+```shell-session
+$ nomad job revert hello-world 3
+```
+
+This example reverts the job to the version with the `golden-version` tag.
+
+```shell-session
+$ nomad job revert hello-world "golden-version"
+```
+
+Refer to the [`job revert`][job-revert-cli] command reference for more examples
+as well as details on including general options such as namespace.
+
+
+
+
+| Method | Path | Produces |
+| ------ | ------------------------ | ------------------ |
+| `POST` | `/v1/job/:job_id/revert` | `application/json` |
+
+You can revert a job to a previous version by specifying version number or the
+tag name.
+
+This example reverts the current job to version six.
+
+```shell-session
+$ curl -X POST \
+ localhost:4646/v1/job/hello-world/revert \
+ -H "Content-Type: application/json" -d \
+ '{"JobID": "hello-world", "JobVersion": 6}'
+```
+
+This example reverts the current job to the version tagged `golden-version`.
+
+```shell-session
+$ curl -X POST \
+ localhost:4646/v1/job/hello-world/revert \
+ -H "Content-Type: application/json" -d \
+ '{"JobID": "hello-world", "TaggedVersion": "golden-version"}'
+```
+
+The JSON response for both examples is similar to the following.
+
+```json
+{
+ "EvalID":"c3b8b0b1-85b5-34f9-de70-80d859c6466a",
+ "EvalCreateIndex":6442,
+ "JobModifyIndex":6442,
+ "Warnings":"",
+ "Index":6442,
+ "LastContact":0,
+ "KnownLeader":false,
+ "NextToken":""
+}
+```
+
+Refer to the Jobs HTTP API [Revert to older Job Version][job-revert-api]
+reference for details on path and payload parameters.
+
+
+
+
+In this example, you revert the current job to the version with the
+`golden-version` tag.
+
+
+
+1. From the **Jobs** screen, click the **hello-world** job to display job details.
+1. Click **Versions**.
+1. Find the version with the `golden-version` tag.
+1. Click **Revert Version**. The UI asks you to confirm.
+1. Click **Yes, Revert Version** to complete the reversion process.
+
+The UI then displays the **Overview** tab, where you can review the new version deployment.
+
+
+
+
+## Clone a version
+
+Use the web UI to clone a job version.
+
+You can use a cloned version for a new version of the same job or to create a new job.
+
+### Clone as new version
+
+In this example, you clone the `hello-world` job's `golden-version`, edit the
+job spec, plan, and then run the new version.
+
+1. From the **Jobs** screen, click the **hello-world** job to display job details.
+1. Click the **Versions** tab.
+1. Under the version with the `golden-version` tag, click **Clone and Edit**.
+1. Click **Clone as New Version of hello-world**.
+1. Edit the job definition.
+
+ Since this job spec was created using HCL, the UI displays the definition in the **Job Spec** tab.
+
+ Change the network port to `8080`.
+
+
+ If you choose to edit the JSON in the Full Definition tab,
+ the JSON definition replaces the HCL definition, so you lose the HCL
+ job spec.
+ We recommending using HCL for job specs.
+
+
+1. Click **Plan**.
+1. Review the plan output.
+1. Click **Run** to run the new version.
+
+The **Versions** tab displays the new version.
+
+### Clone as new job
+
+In this example, you clone the `hello-world` job's `golden-version`, edit the
+job name and network port, plan, and then run the new job.
+
+1. From the **Jobs** screen, click the **hello-world** job to display job details.
+1. Click the **Versions** tab.
+1. Under the version with the `golden-version` tag, click **Clone and Edit**.
+1. Click **Clone as New Job**.
+1. Edit the job spec.
+
+ Change the job name to `hello-earth` and the network port to `9080`. You must change the job name. Otherwise, Nomad creates a new version of the
+ original job.
+
+1. Click **Plan**.
+1. Review the plan output.
+1. Click **Run** to run the new job.
+
+Nomad loads the **Overview** of the `hello-earth` job so you can review the deployment.
+
+[job-concept]: /nomad/docs/concepts/job#job-versions
+[job-tag-apply-cli]: /nomad/commands/job/tag/apply
+[job-tag-apply-api]: /nomad/api-docs/jobs#create-job-version-tag
+[job-tag-unset-cli]: /nomad/commands/job/tag/unset
+[job-tag-unset-api]: /nomad/api-docs/jobs#delete-job-version-tag
+[nomad-job-history-cli]: /nomad/commands/job/history
+[job-list-diff-api]: /nomad/api-docs/jobs#list-job-versions
+[job-revert-cli]: /nomad/commands/job/revert
+[job-revert-api]: /nomad/api-docs/jobs#revert-to-older-job-version
diff --git a/website/content/docs/job-scheduling/affinity.mdx b/website/content/docs/job-scheduling/affinity.mdx
new file mode 100644
index 000000000..df43fef4e
--- /dev/null
+++ b/website/content/docs/job-scheduling/affinity.mdx
@@ -0,0 +1,250 @@
+---
+layout: docs
+page_title: Job placements with affinities
+description: >-
+ Configure affinities to express placement preferences for your jobs. Create a
+ job with an affinity, submit it to Nomad, and monitor it after placement.
+---
+
+# Job placements with affinities
+
+The [affinity][affinity-stanza] stanza allows operators to express placement
+preferences for their jobs on particular types of nodes. Note that there is a
+key difference between the [constraint][constraint] stanza and the affinity
+stanza. The constraint stanza strictly filters where jobs are run based on
+[attributes][attributes] and [client metadata][client-metadata]. If no nodes are
+found to match, the placement does not succeed. The affinity stanza acts like a
+"soft constraint." Nomad will attempt to match the desired affinity, but
+placement will succeed even if no nodes match the desired criteria. This is done
+in conjunction with scoring based on the Nomad scheduler's bin packing algorithm
+which you can read more about [here][scheduling].
+
+In this guide, you will encounter a sample application. Your application can run
+in datacenters `dc1` and `dc2`; however, you have a strong preference to run it in
+dc2. You will learn how to configure the job to inform the scheduler of your
+preference, while still allowing it to place your workload in `dc1` if the
+desired resources aren't available in dc2.
+
+By specify an affinity with the proper [weight], the Nomad scheduler can find
+the best nodes on which to place your job. The affinity weight will be included
+when scoring nodes for placement along with other factors like the bin-packing
+algorithm.
+
+### Prerequisites
+
+To perform the tasks described in this guide, you need to have a Nomad
+environment with Consul installed. You can use this [repository] to provision a
+sandbox environment. This guide will assume a cluster with one server node and
+three client nodes.
+
+
+
+ This guide is for demo purposes and is only using a single
+server node. In a production cluster, 3 or 5 server nodes are recommended.
+
+
+
+## Place one of the client nodes in a different datacenter
+
+You are going express your job placement preference based on the datacenter your
+nodes are located in. Choose one of your client nodes and edit
+`/etc/nomad.d/nomad.hcl` to change its location to `dc2`. A snippet of an
+example configuration file is show below with the required change is shown
+below.
+
+```hcl
+data_dir = "/opt/nomad/data"
+bind_addr = "0.0.0.0"
+datacenter = "dc2"
+
+# Enable the client
+client {
+ enabled = true
+# ...
+}
+```
+
+After making the change on your chosen client node, restart the Nomad service
+
+```shell-session
+$ sudo systemctl restart nomad
+```
+
+If everything worked correctly, one of your nodes will now show datacenter `dc2`
+when you run the [`nomad node status`][node-status] command.
+
+```shell-session
+$ nomad node status
+ID DC Name Class Drain Eligibility Status
+3592943e dc1 ip-172-31-27-159 false eligible ready
+3dea0188 dc1 ip-172-31-16-175 false eligible ready
+6b6e9518 dc2 ip-172-31-27-25 false eligible ready
+```
+
+## Create a job with an affinity
+
+Create a file with the name `redis.nomad.hcl` and place the following content in it:
+
+```hcl
+job "redis" {
+ datacenters = ["dc1", "dc2"]
+ type = "service"
+
+ affinity {
+ attribute = "${node.datacenter}"
+ value = "dc2"
+ weight = 100
+ }
+
+ group "cache1" {
+ count = 4
+
+ network {
+ port "db" {
+ to = 6379
+ }
+ }
+
+ service {
+ name = "redis-cache"
+ port = "db"
+
+ check {
+ name = "alive"
+ type = "tcp"
+ interval = "10s"
+ timeout = "2s"
+ }
+ }
+
+
+ task "redis" {
+ driver = "docker"
+
+ config {
+ image = "redis:latest"
+ ports = ["db"]
+ }
+ }
+ }
+}
+```
+
+Observe that the job uses the `affinity` stanza and specifies `dc2` as the value
+for the `${node.datacenter}` [attribute][attributes]. It also uses the value
+`100` for the [weight][weight] which will cause the Nomad scheduler to rank
+nodes in datacenter `dc2` with a higher score. Keep in mind that weights can
+range from -100 to 100, inclusive. Negative weights serve as anti-affinities
+which cause Nomad to avoid placing allocations on nodes that match the criteria.
+
+## Register the redis Nomad job
+
+Run the Nomad job with the following command:
+
+```shell-session
+$ nomad run redis.nomad.hcl
+==> Monitoring evaluation "11388ef2"
+ Evaluation triggered by job "redis"
+ Allocation "0dfcf0ba" created: node "6b6e9518", group "cache1"
+ Allocation "89a9aae9" created: node "3592943e", group "cache1"
+ Allocation "9a00f742" created: node "6b6e9518", group "cache1"
+ Allocation "fc0f21bc" created: node "3dea0188", group "cache1"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "11388ef2" finished with status "complete"
+```
+
+Note that two of the allocations in this example have been placed on node
+`6b6e9518`. This is the node configured to be in datacenter `dc2`. The Nomad
+scheduler selected this node because of the affinity specified. All of the
+allocations have not been placed on this node because the Nomad scheduler
+considers other factors in the scoring such as bin-packing. This helps avoid
+placing too many instances of the same job on a node and prevents reduced
+capacity during a node level failure. You will take a detailed look at the
+scoring in the next few steps.
+
+## Check the status of the job
+
+At this point, Check the status of the job and verify where the allocations
+have been placed. Run the following command:
+
+```shell-session
+$ nomad status redis
+```
+
+There should be four instances of the job running in the `Summary` section of
+the output as shown below:
+
+```plaintext
+...
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+cache1 0 0 4 0 0 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created Modified
+0dfcf0ba 6b6e9518 cache1 0 run running 1h44m ago 1h44m ago
+89a9aae9 3592943e cache1 0 run running 1h44m ago 1h44m ago
+9a00f742 6b6e9518 cache1 0 run running 1h44m ago 1h44m ago
+fc0f21bc 3dea0188 cache1 0 run running 1h44m ago 1h44m ago
+```
+
+You can cross-check this output with the results of the `nomad node status`
+command to verify that the majority of your workload has been placed on the node
+in `dc2`. In the case of the above output, that node is `6b6e9518`.
+
+## Obtain detailed scoring information on job placement
+
+The Nomad scheduler will not always place all of your workload on nodes you have
+specified in the `affinity` stanza even if the resources are available. This is
+because affinity scoring is combined with other metrics as well before making a
+scheduling decision. In this step, you will take a look at some of those other
+factors.
+
+Using the output from the previous step, find an allocation that has been placed
+on a node in `dc2` and use the [`nomad alloc status`][alloc status] command with
+the [`-verbose`][verbose] option to obtain detailed scoring information on it.
+In this example, the allocation ID to be inspected is `0dfcf0ba` (your
+allocation IDs will be different).
+
+```shell-session
+$ nomad alloc status -verbose 0dfcf0ba
+```
+
+The resulting output will show the `Placement Metrics` section at the bottom.
+
+```plaintext
+...
+Placement Metrics
+Node binpack job-anti-affinity node-reschedule-penalty node-affinity final score
+6b6e9518-d2a4-82c8-af3b-6805c8cdc29c 0.33 0 0 1 0.665
+3dea0188-ae06-ad98-64dd-a761ab2b1bf3 0.33 0 0 0 0.33
+3592943e-67e4-461f-d888-d5842372a4d4 0.33 0 0 0 0.33
+```
+
+Note that the results from the `binpack`, `job-anti-affinity`,
+`node-reschedule-penalty`, and `node-affinity` columns are combined to produce
+the numbers listed in the `final score` column for each node. The Nomad
+scheduler uses the final score for each node in deciding where to make
+placements.
+
+## Next steps
+
+Experiment with the weight provided in the `affinity` stanza (the value can be
+from -100 through 100) and observe how the final score given to each node
+changes (use the `nomad alloc status` command as shown in the previous step).
+
+### Reference material
+
+- The [affinity][affinity-stanza] stanza documentation
+- [Scheduling][scheduling] with Nomad
+
+[affinity-stanza]: /nomad/docs/job-specification/affinity
+[alloc status]: /nomad/commands/alloc/status
+[attributes]: /nomad/docs/reference/runtime-variable-interpolation#node-attributes
+[constraint]: /nomad/docs/job-specification/constraint
+[client-metadata]: /nomad/docs/configuration/client#meta
+[node-status]: /nomad/commands/node/status
+[scheduling]: /nomad/docs/concepts/scheduling/how-scheduling-works
+[verbose]: /nomad/commands/alloc/status#verbose
+[weight]: /nomad/docs/job-specification/affinity#weight
+[repository]: https://github.com/hashicorp/nomad/tree/master/terraform#provision-a-nomad-cluster-in-the-cloud
diff --git a/website/content/docs/job-scheduling/index.mdx b/website/content/docs/job-scheduling/index.mdx
new file mode 100644
index 000000000..922967e6b
--- /dev/null
+++ b/website/content/docs/job-scheduling/index.mdx
@@ -0,0 +1,33 @@
+---
+layout: docs
+page_title: Advanced job scheduling
+description: >-
+ Discover the advanced scheduling features available to Nomad jobs including affinity and spread.
+---
+
+# Advanced job scheduling
+
+The Nomad [scheduler][scheduling] uses a bin-packing algorithm to optimize the
+resource utilization and density of applications in your Nomad cluster. Nomad
+0.9 adds new features to allow operators more fine-grained control over
+allocation placement. This enables use cases similar to the following:
+
+- Expressing preference for a certain class of nodes for a specific application
+ via the [affinity stanza][affinity-stanza].
+
+- Spreading allocations across a datacenter, rack or any other node attribute or
+ metadata with the [spread stanza][spread-stanza].
+
+Please refer to the tutorials below for using affinity and spread in Nomad 0.9.
+
+- [Preemption][preemption-guide]
+- [Affinity][affinity-guide]
+- [Spread][spread-guide]
+
+[affinity-guide]: /nomad/docs/job-scheduling/affinity
+[affinity-stanza]: /nomad/docs/job-specification/affinity
+[preemption-guide]: /nomad/docs/job-scheduling/preemption
+[preemption-stanza]: /nomad/docs/job-specification/spread
+[scheduling]: /nomad/docs/concepts/scheduling/how-scheduling-works
+[spread-guide]: /nomad/docs/job-scheduling/spread
+[spread-stanza]: /nomad/docs/job-specification/spread
diff --git a/website/content/docs/job-scheduling/preemption.mdx b/website/content/docs/job-scheduling/preemption.mdx
new file mode 100644
index 000000000..24dffc0f4
--- /dev/null
+++ b/website/content/docs/job-scheduling/preemption.mdx
@@ -0,0 +1,502 @@
+---
+layout: docs
+page_title: Use preemption for job priority
+description: >-
+ Deploy a low priority job and a high priority job. Then use preemption
+ to run the higher priority job even when other jobs are running.
+---
+
+# Use preemption for job priority
+
+Preemption allows Nomad to evict running allocations to place allocations of a
+higher priority. Allocations of a job that are blocked temporarily go into
+"pending" status until the cluster has additional capacity to run them. This is
+useful when operators need to run relatively higher priority tasks sooner even
+under resource contention across the cluster.
+
+Nomad v0.9.0 added Preemption for [system][system-job] jobs. Nomad v0.9.3
+[Enterprise][enterprise] added preemption for [service][service-job] and
+[batch][batch-job] jobs. Nomad v0.12.0 made preemption an open source feature
+for all three job types.
+
+Preemption is enabled by default for system jobs. It can be enabled for service
+and batch jobs by sending a [payload][payload-preemption-config] with the
+appropriate options specified to the [scheduler configuration][update-scheduler]
+API endpoint.
+
+### Prerequisites
+
+To perform the tasks described in this guide, you need to have a Nomad
+environment with Consul installed. You can use this [repository] to provision a
+sandbox environment; however, you need to use Nomad v0.12.0 or higher or Nomad
+Enterprise v0.9.3 or higher.
+
+You need a cluster with one server node and three client nodes. To simulate
+resource contention, the nodes in this environment each have 1 GB RAM (For AWS,
+you can choose the [t2.micro][t2-micro] instance type).
+
+
+
+ This tutorial is for demo purposes and is only using a
+single server node. Three or five server nodes are recommended for a
+production cluster.
+
+
+
+## Create a job with low priority
+
+Start by creating a job with relatively lower priority into your Nomad cluster.
+One of the allocations from this job will be preempted in a subsequent
+deployment when there is a resource contention in the cluster. Copy the
+following job into a file and name it `webserver.nomad.hcl`.
+
+```hcl
+job "webserver" {
+ datacenters = ["dc1"]
+ type = "service"
+ priority = 40
+
+ group "webserver" {
+ count = 3
+ network {
+ port "http" {
+ to = 80
+ }
+ }
+
+ service {
+ name = "apache-webserver"
+ port = "http"
+
+ check {
+ name = "alive"
+ type = "http"
+ path = "/"
+ interval = "10s"
+ timeout = "2s"
+ }
+ }
+
+ task "apache" {
+ driver = "docker"
+
+ config {
+ image = "httpd:latest"
+ ports = ["http"]
+ }
+
+ resources {
+ memory = 600
+ }
+ }
+ }
+}
+```
+
+Note that the [count][count] is 3 and that each allocation is specifying 600 MB
+of [memory][memory]. Remember that each node only has 1 GB of RAM.
+
+## Run the low priority job
+
+Use the [`nomad job run` command][] to start the `webserver.nomad.hcl` job.
+
+```shell-session
+$ nomad job run webserver.nomad.hcl
+==> Monitoring evaluation "35159f00"
+ Evaluation triggered by job "webserver"
+ Evaluation within deployment: "278b2e10"
+ Allocation "0850e103" created: node "cf8487e2", group "webserver"
+ Allocation "551a7283" created: node "ad10ba3b", group "webserver"
+ Allocation "8a3d7e1e" created: node "18997de9", group "webserver"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "35159f00" finished with status "complete"
+```
+
+Check the status of the `webserver` job using the [`nomad job status` command][]
+at this point and verify that an allocation has been placed on each client node
+in the cluster.
+
+```shell-session
+$ nomad job status webserver
+ID = webserver
+Name = webserver
+Submit Date = 2021-02-11T19:18:29-05:00
+Type = service
+Priority = 40
+...
+Allocations
+ID Node ID Task Group Version Desired Status Created Modified
+0850e103 cf8487e2 webserver 0 run running 8s ago 2s ago
+551a7283 ad10ba3b webserver 0 run running 8s ago 2s ago
+8a3d7e1e 18997de9 webserver 0 run running 8s ago 1s ago
+```
+
+## Create a job with high priority
+
+Create another job with a [priority] greater than the "webserver" job. Copy the
+following into a file named `redis.nomad.hcl`.
+
+```hcl
+job "redis" {
+ datacenters = ["dc1"]
+ type = "service"
+ priority = 80
+
+ group "cache1" {
+ count = 1
+
+ network {
+ port "db" {
+ to = 6379
+ }
+ }
+
+ service {
+ name = "redis-cache"
+ port = "db"
+
+ check {
+ name = "alive"
+ type = "tcp"
+ interval = "10s"
+ timeout = "2s"
+ }
+ }
+
+ task "redis" {
+ driver = "docker"
+
+ config {
+ image = "redis:latest"
+ ports = ["db"]
+ }
+
+ resources {
+ memory = 700
+ }
+ }
+ }
+}
+```
+
+Note that this job has a priority of 80 (greater than the priority of the
+`webserver` job from earlier) and requires 700 MB of memory. This allocation
+will create a resource contention in the cluster since each node only has 1 GB
+of memory with a 600 MB allocation already placed on it.
+
+## Observe a run before and after enabling preemption
+
+### Try to run `redis.nomad.hcl`
+
+Remember that preemption for service and batch jobs is [not enabled by
+default][preemption-config]. This means that the `redis` job will be queued due
+to resource contention in the cluster. You can verify the resource contention
+before actually registering your job by running the [`nomad job plan` command][].
+
+```shell-session
+$ nomad job plan redis.nomad.hcl
++ Job: "redis"
++ Task Group: "cache1" (1 create)
+ + Task: "redis" (forces create)
+
+Scheduler dry-run:
+- WARNING: Failed to place all allocations.
+ Task Group "cache1" (failed to place 1 allocation):
+ * Resources exhausted on 3 nodes
+ * Dimension "memory" exhausted on 3 nodes
+...
+```
+
+Run the `redis.nomad.hcl` job with the [`nomad job run` command][]. Observe that the
+allocation was queued.
+
+```shell-session
+$ nomad job run redis.nomad.hcl
+==> Monitoring evaluation "3c6593b4"
+ Evaluation triggered by job "redis"
+ Evaluation within deployment: "ae55a4aa"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "3c6593b4" finished with status "complete" but failed to place all allocations:
+ Task Group "cache1" (failed to place 1 allocation):
+ * Resources exhausted on 3 nodes
+ * Dimension "memory" exhausted on 3 nodes
+ Evaluation "249fd21b" waiting for additional capacity to place remainder
+```
+
+You can also verify the allocation has been queued by now by fetching the status
+of the job using the [`nomad job status` command][].
+
+```shell-session
+$ nomad job status redis
+ID = redis
+Name = redis
+Submit Date = 2021-02-11T19:22:55-05:00
+Type = service
+Priority = 80
+...
+Placement Failure
+Task Group "cache1":
+ * Resources exhausted on 3 nodes
+ * Dimension "memory" exhausted on 3 nodes
+...
+Allocations
+No allocations placed
+```
+
+Stop the `redis` job for now. In the next steps, you will enable service job
+preemption and re-deploy. Use the [`nomad job stop` command][] with the `-purge`
+flag set.
+
+```shell-session
+$ nomad job stop -purge redis
+==> Monitoring evaluation "a9c9945d"
+ Evaluation triggered by job "redis"
+ Evaluation within deployment: "ae55a4aa"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "a9c9945d" finished with status "complete"
+```
+
+### Enable service job preemption
+
+Get the current [scheduler configuration][scheduler-configuration] using the
+Nomad API. Setting an environment variable with your cluster address makes the
+`curl` commands more reusable. Substitute in the proper address for your Nomad
+cluster.
+
+```shell-session
+$ export NOMAD_ADDR=http://127.0.0.1:4646
+```
+
+If you are enabling preemption in an ACL-enabled Nomad cluster, you will also
+need to [authenticate to the API][api-auth] with a Nomad token via the
+`X-Nomad-Token` header. In this case, you can use an environment variable to add
+the header option and your token value to the command. If you don't use tokens,
+skip this step. The `curl` commands will run correctly when the variable is
+unset.
+
+```shell-session
+$ export NOMAD_AUTH='--header "X-Nomad-Token: «replace with your token»"'
+```
+
+ACLs, consult the
+
+Now, fetch the configuration with the following `curl` command.
+
+```shell-session
+$ curl --silent ${NOMAD_AUTH} \
+ ${NOMAD_ADDR}/v1/operator/scheduler/configuration?pretty
+```
+
+```json
+{
+ "SchedulerConfig": {
+ "SchedulerAlgorithm": "binpack",
+ "PreemptionConfig": {
+ "SystemSchedulerEnabled": true,
+ "BatchSchedulerEnabled": false,
+ "ServiceSchedulerEnabled": false
+ },
+ "CreateIndex": 5,
+ "ModifyIndex": 5
+ },
+ "Index": 5,
+ "LastContact": 0,
+ "KnownLeader": true
+}
+```
+
+Note that [BatchSchedulerEnabled][batch-enabled] and
+[ServiceSchedulerEnabled][service-enabled] are both set to `false` by default.
+Since you are preempting service jobs in this guide, you need to set
+`ServiceSchedulerEnabled` to `true`. Do this by directly interacting
+with the [API][update-scheduler].
+
+Create the following JSON payload and place it in a file named `scheduler.json`:
+
+```json
+{
+ "PreemptionConfig": {
+ "SystemSchedulerEnabled": true,
+ "BatchSchedulerEnabled": false,
+ "ServiceSchedulerEnabled": true
+ }
+}
+```
+
+Note that [ServiceSchedulerEnabled][service-enabled] has been set to `true`.
+
+Run the following command to update the scheduler configuration:
+
+```shell-session
+$ curl --silent ${NOMAD_AUTH} \
+ --request POST --data @scheduler.json \
+ ${NOMAD_ADDR}/v1/operator/scheduler/configuration
+```
+
+You should now be able to inspect the scheduler configuration again and verify
+that preemption has been enabled for service jobs (output below is abbreviated):
+
+```shell-session
+$ curl --silent ${NOMAD_AUTH} \
+ ${NOMAD_ADDR}/v1/operator/scheduler/configuration?pretty
+```
+
+```plaintext
+...
+ "PreemptionConfig": {
+ "SystemSchedulerEnabled": true,
+ "BatchSchedulerEnabled": false,
+ "ServiceSchedulerEnabled": true
+ },
+...
+```
+
+### Try running the redis job again
+
+Now that you have enabled preemption on service jobs, deploying your `redis` job
+should evict one of the lower priority `webserver` allocations and place it into
+a queue. You can run `nomad plan` to output a preview of what will happen:
+
+```shell-session
+$ nomad job plan redis.nomad.hcl
++ Job: "redis"
++ Task Group: "cache1" (1 create)
+ + Task: "redis" (forces create)
+
+Scheduler dry-run:
+- All tasks successfully allocated.
+
+Preemptions:
+
+Alloc ID Job ID Task Group
+8a3d7e1e-40ee-f731-5135-247d8b7c2901 webserver webserver
+...
+```
+
+The preceding plan output shows that one of the `webserver` allocations will be
+evicted in order to place the requested `redis` instance.
+
+Now use the [`nomad job run` command][] to run the `redis.nomad.hcl` job file.
+
+```shell-session
+$ nomad job run redis.nomad.hcl
+==> Monitoring evaluation "fef3654f"
+ Evaluation triggered by job "redis"
+ Evaluation within deployment: "37b37a63"
+ Allocation "6ecc4bbe" created: node "cf8487e2", group "cache1"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "fef3654f" finished with status "complete"
+```
+
+Run the [`nomad job status` command][] on the `webserver` job to verify one of
+the allocations has been evicted.
+
+```shell-session
+$ nomad job status webserver
+ID = webserver
+Name = webserver
+Submit Date = 2021-02-11T19:18:29-05:00
+Type = service
+Priority = 40
+...
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+webserver 1 0 2 0 1 0
+
+Placement Failure
+Task Group "webserver":
+ * Resources exhausted on 3 nodes
+ * Dimension "memory" exhausted on 3 nodes
+...
+
+Allocations
+ID Node ID Task Group Version Desired Status Created Modified
+0850e103 cf8487e2 webserver 0 evict complete 21m17s ago 18s ago
+551a7283 ad10ba3b webserver 0 run running 21m17s ago 20m55s ago
+8a3d7e1e 18997de9 webserver 0 run running 21m17s ago 20m57s ago
+```
+
+### Stop the job
+
+Use the [`nomad job stop` command][] on the `redis` job. This will provide the
+capacity necessary to unblock the third `webserver` allocation.
+
+```shell-session
+$ nomad job stop redis
+==> Monitoring evaluation "df368cb1"
+ Evaluation triggered by job "redis"
+ Evaluation within deployment: "37b37a63"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "df368cb1" finished with status "complete"
+```
+
+Run the [`nomad job status` command][] on the `webserver` job. The output should
+now indicate that a new third allocation was created to replace the one that was
+preempted.
+
+```shell-session
+$ nomad job status webserver
+ID = webserver
+Name = webserver
+Submit Date = 2021-02-11T19:18:29-05:00
+Type = service
+Priority = 40
+Datacenters = dc1
+Namespace = default
+Status = running
+Periodic = false
+Parameterized = false
+
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+webserver 0 0 3 0 1 0
+
+Latest Deployment
+ID = 278b2e10
+Status = successful
+Description = Deployment completed successfully
+
+Deployed
+Task Group Desired Placed Healthy Unhealthy Progress Deadline
+webserver 3 3 3 0 2021-02-12T00:28:51Z
+
+Allocations
+ID Node ID Task Group Version Desired Status Created Modified
+4e212aec cf8487e2 webserver 0 run running 21s ago 3s ago
+0850e103 cf8487e2 webserver 0 evict complete 22m48s ago 1m49s ago
+551a7283 ad10ba3b webserver 0 run running 22m48s ago 22m26s ago
+8a3d7e1e 18997de9 webserver 0 run running 22m48s ago 22m28s ago
+```
+
+## Next steps
+
+The process you learned in this tutorial can also be applied to
+[batch][batch-enabled] jobs as well. Read more about preemption in the
+[Nomad documentation][preemption].
+
+### Reference material
+
+- [Preemption][preemption]
+
+[batch-enabled]: /nomad/api-docs/operator/scheduler#batchschedulerenabled-1
+[batch-job]: /nomad/docs/concepts/scheduling/schedulers#batch
+[count]: /nomad/docs/job-specification/group#count
+[enterprise]: /nomad/docs/enterprise
+[memory]: /nomad/docs/job-specification/resources#memory
+[payload-preemption-config]: //nomad/api-docs/operator/scheduler#preemptionconfig-1
+[preemption-config]: /nomad/api-docs/operator/scheduler#preemptionconfig-1
+[preemption]: /nomad/docs/concepts/scheduling/preemption
+[priority]: /nomad/docs/job-specification/job#priority
+[repository]: https://github.com/hashicorp/nomad/tree/master/terraform#provision-a-nomad-cluster-in-the-cloud
+[scheduler-configuration]: /nomad/api-docs/operator/scheduler#read-scheduler-configuration
+[service-enabled]: /nomad/api-docs/operator/scheduler#serviceschedulerenabled-1
+[service-job]: /nomad/docs/concepts/scheduling/schedulers#service
+[step-1]: #create-a-job-with-low-priority
+[system-job]: /nomad/docs/concepts/scheduling/schedulers#system
+[t2-micro]: https://aws.amazon.com/ec2/instance-types/
+[update-scheduler]: /nomad/api-docs/operator/scheduler#update-scheduler-configuration
+[`nomad job plan` command]: /nomad/commands/job/plan
+[`nomad job run` command]: /nomad/commands/job/run
+[`nomad job status` command]: /nomad/commands/job/status
+[`nomad job stop` command]: /nomad/commands/job/stop
+[api-auth]: /nomad/api-docs/#authentication
diff --git a/website/content/docs/job-scheduling/spread.mdx b/website/content/docs/job-scheduling/spread.mdx
new file mode 100644
index 000000000..6ca3c5091
--- /dev/null
+++ b/website/content/docs/job-scheduling/spread.mdx
@@ -0,0 +1,277 @@
+---
+layout: docs
+page_title: Use spread to increase failure tolerance
+description: >-
+ Create a job with the spread stanza to prevent application downtime
+ as a result of a physical domain failure in a datacenter or rack.
+---
+
+# Use spread to increase failure tolerance
+
+The Nomad scheduler uses a bin-packing algorithm when making job placements on
+nodes to optimize resource utilization and density of applications. Although bin
+packing ensures optimal resource utilization, it can lead to some nodes carrying
+a majority of allocations for a given job. This can cause cascading failures
+where the failure of a single node or a single data center can lead to
+application unavailability.
+
+The [spread stanza][spread-stanza] solves this problem by allowing operators to
+distribute their workloads in a customized way based on [attributes] and/or
+[client metadata][client-metadata]. By using spread criteria in their job
+specification, Nomad job operators can ensure that failures across a domain such
+as datacenter or rack don't affect application availability.
+
+Consider a Nomad application that needs to be deployed to multiple datacenters
+within a region. Datacenter `dc1` has four nodes while `dc2` has one node. This
+application has ten instances and seven of them must be deployed to `dc1` since
+it receives more user traffic and you need to make sure the application doesn't
+suffer downtime due to not enough running instances to process requests. The
+remaining 3 allocations can be deployed to `dc2`.
+
+Use the `spread` stanza in the Nomad [job specification][job-specification] to
+ensure the 70% of the workload is being placed in datacenter `dc1` and 30% is
+being placed in `dc2`. The Nomad operator can use the [percent] option with a
+[target] to customize the spread.
+
+### Prerequisites
+
+To perform the tasks described in this guide, you need to have a Nomad
+environment with Consul installed. You can use this [repository] to provision a
+sandbox environment. This guide will assume a cluster with one server node and
+five client nodes.
+
+
+
+ This guide is for demo purposes and is only using a single
+server node. In a production cluster, 3 or 5 server nodes are recommended.
+
+
+
+## Place one of the client nodes in a different datacenter
+
+In this guide, you are going to customize the spread for our job placement
+between the datacenters our nodes are located in. Choose one of your client
+nodes and edit `/etc/nomad.d/nomad.hcl` to change its location to `dc2`. A
+snippet of an example configuration file is show below with the required change
+is shown below.
+
+```hcl
+data_dir = "/opt/nomad/data"
+bind_addr = "0.0.0.0"
+datacenter = "dc2"
+
+# Enable the client
+client {
+ enabled = true
+# ...
+}
+```
+
+After making the change on your chosen client node, restart the Nomad service
+
+```shell-session
+$ sudo systemctl restart nomad
+```
+
+If everything is configured correctly, you should be able to run the [`nomad node status`][node-status] command and confirm that one of your nodes is now in
+datacenter `dc2`.
+
+```shell-session
+$ nomad node status
+ID DC Name Class Drain Eligibility Status
+5d16d949 dc2 ip-172-31-62-240 false eligible ready
+7b381152 dc1 ip-172-31-59-115 false eligible ready
+10cc48cc dc1 ip-172-31-58-46 false eligible ready
+93f1e628 dc1 ip-172-31-58-113 false eligible ready
+12894b80 dc1 ip-172-31-62-90 false eligible ready
+```
+
+## Create a job with the spread stanza
+
+Create a file with the name `redis.nomad.hcl` and place the following content in it:
+
+```hcl
+job "redis" {
+ datacenters = ["dc1", "dc2"]
+ type = "service"
+
+ spread {
+ attribute = "${node.datacenter}"
+ weight = 100
+
+ target "dc1" {
+ percent = 70
+ }
+
+ target "dc2" {
+ percent = 30
+ }
+ }
+
+ group "cache1" {
+ count = 10
+
+ network {
+ port "db" {
+ to = 6379
+ }
+ }
+
+ task "redis" {
+ driver = "docker"
+
+ config {
+ image = "redis:latest"
+
+ ports = ["db"]
+ }
+
+ service {
+ name = "redis-cache"
+ port = "db"
+
+ check {
+ name = "alive"
+ type = "tcp"
+ interval = "10s"
+ timeout = "2s"
+ }
+ }
+ }
+ }
+}
+```
+
+Note that the job specifies the `spread` stanza and specified the
+[datacenter][attributes] attribute while targeting `dc1` and `dc2` with the
+percent options. This will tell the Nomad scheduler to make an attempt to
+distribute 70% of the workload on `dc1` and 30% of the workload on `dc2`.
+
+## Register the redis.nomad.hcl job
+
+Run the Nomad job with the following command:
+
+```shell-session
+$ nomad run redis.nomad.hcl
+==> Monitoring evaluation "c3dc5ebd"
+ Evaluation triggered by job "redis"
+ Allocation "7a374183" created: node "5d16d949", group "cache1"
+ Allocation "f4361df1" created: node "7b381152", group "cache1"
+ Allocation "f7af42dc" created: node "5d16d949", group "cache1"
+ Allocation "0638edf2" created: node "10cc48cc", group "cache1"
+ Allocation "49bc6038" created: node "12894b80", group "cache1"
+ Allocation "c7e5679a" created: node "5d16d949", group "cache1"
+ Allocation "cf91bf65" created: node "7b381152", group "cache1"
+ Allocation "d16b606c" created: node "12894b80", group "cache1"
+ Allocation "27866df0" created: node "93f1e628", group "cache1"
+ Allocation "8531a6fc" created: node "7b381152", group "cache1"
+ Evaluation status changed: "pending" -> "complete"
+```
+
+Note that three of the ten allocations have been placed on node `5d16d949`. This
+is the node configured to be in datacenter `dc2`. The Nomad scheduler has
+distributed 30% of the workload to `dc2` as specified in the `spread` stanza.
+
+Keep in mind that the Nomad scheduler still factors in other components into the
+overall scoring of nodes when making placements, so you should not expect the
+spread stanza to strictly implement your distribution preferences like a
+[constraint][constraint-stanza]. Now, take a detailed look at the scoring in
+the next few steps.
+
+## Check the status of the job
+
+Check the status of the job and verify where allocations have been placed. Run
+the following command:
+
+```shell-session
+$ nomad status redis
+```
+
+The output should list ten running instances of your job in the `Summary`
+section as show below:
+
+```plaintext
+...
+Summary
+Task Group Queued Starting Running Failed Complete Lost
+cache1 0 0 10 0 0 0
+
+Allocations
+ID Node ID Task Group Version Desired Status Created Modified
+0638edf2 10cc48cc cache1 0 run running 2m20s ago 2m ago
+27866df0 93f1e628 cache1 0 run running 2m20s ago 1m57s ago
+49bc6038 12894b80 cache1 0 run running 2m20s ago 1m58s ago
+7a374183 5d16d949 cache1 0 run running 2m20s ago 2m1s ago
+8531a6fc 7b381152 cache1 0 run running 2m20s ago 2m2s ago
+c7e5679a 5d16d949 cache1 0 run running 2m20s ago 1m55s ago
+cf91bf65 7b381152 cache1 0 run running 2m20s ago 1m57s ago
+d16b606c 12894b80 cache1 0 run running 2m20s ago 2m1s ago
+f4361df1 7b381152 cache1 0 run running 2m20s ago 2m3s ago
+f7af42dc 5d16d949 cache1 0 run running 2m20s ago 1m54s ago
+```
+
+You can cross-check this output with the results of the `nomad node status`
+command to verify that 30% of your workload has been placed on the node in `dc2`
+(in our case, that node is `5d16d949`).
+
+## Obtain detailed scoring information on job placement
+
+The Nomad scheduler will not always spread your workload in the way you have
+specified in the `spread` stanza even if the resources are available. This is
+because spread scoring is factored in with other metrics as well before making a
+scheduling decision. In this step, you will take a look at some of those other
+factors.
+
+Using the output from the previous step, take any allocation that has been
+placed on a node and use the nomad [alloc status][alloc status] command with the
+[verbose][verbose] option to obtain detailed scoring information on it. In this
+example, the guide refers to allocation ID `0638edf2`—your allocation IDs will
+be different.
+
+```shell-session
+$ nomad alloc status -verbose 0638edf2
+```
+
+The resulting output will show the `Placement Metrics` section at the bottom.
+
+```plaintext
+...
+Placement Metrics
+Node node-affinity allocation-spread binpack job-anti-affinity node-reschedule-penalty final score
+10cc48cc-2913-af54-74d5-d7559f373ff2 0 0.429 0.33 0 0 0.379
+93f1e628-e509-b1ab-05b7-0944056f781d 0 0.429 0.515 -0.2 0 0.248
+12894b80-4943-4d5c-5716-c626c6b99be3 0 0.429 0.515 -0.2 0 0.248
+7b381152-3802-258b-4155-6d7dfb344dd4 0 0.429 0.515 -0.2 0 0.248
+5d16d949-85aa-3fd3-b5f4-51094cbeb77a 0 0.333 0.515 -0.2 0 0.216
+```
+
+Note that the results from the `allocation-spread`, `binpack`,
+`job-anti-affinity`, `node-reschedule-penalty`, and `node-affinity` columns are
+combined to produce the numbers listed in the `final score` column for each
+node. The Nomad scheduler uses the final score for each node in deciding where
+to make placements.
+
+## Next steps
+
+Change the values of the `percent` options on your targets in the `spread`
+stanza and observe how the placement behavior along with the final score given
+to each node changes (use the `nomad alloc status` command as shown in the
+previous step).
+
+### Reference material
+
+- The [spread][spread-stanza] stanza documentation
+- [Scheduling][scheduling] with Nomad
+
+[alloc status]: /nomad/commands/alloc/status
+[attributes]: /nomad/docs/reference/runtime-variable-interpolation
+[client-metadata]: /nomad/docs/configuration/client#meta
+[constraint-stanza]: /nomad/docs/job-specification/constraint
+[job-specification]: /nomad/docs/job-specification
+[node-status]: /nomad/commands/node/status
+[percent]: /nomad/docs/job-specification/spread#percent
+[repository]: https://github.com/hashicorp/nomad/tree/master/terraform#provision-a-nomad-cluster-in-the-cloud
+[scheduling]: /nomad/docs/concepts/scheduling/how-scheduling-works
+[spread-stanza]: /nomad/docs/job-specification/spread
+[target]: /nomad/docs/job-specification/spread#target
+[verbose]: /nomad/commands/alloc/status#verbose
diff --git a/website/content/docs/job-specification/affinity.mdx b/website/content/docs/job-specification/affinity.mdx
index 2d0a921b5..b51f2fc31 100644
--- a/website/content/docs/job-specification/affinity.mdx
+++ b/website/content/docs/job-specification/affinity.mdx
@@ -68,7 +68,7 @@ allocations.
- `attribute` `(string: "")` - Specifies the name or reference of the attribute
to examine for the affinity. This can be any of the [Nomad interpolated
- values](/nomad/docs/runtime/interpolation#interpreted_node_vars).
+ values](/nomad/docs/reference/runtime-variable-interpolation#interpreted_node_vars).
- `operator` `(string: "=")` - Specifies the comparison operator. The ordering is
compared lexically. Possible values include:
@@ -92,7 +92,7 @@ allocations.
- `value` `(string: "")` - Specifies the value to compare the attribute against
using the specified operation. This can be a literal value, another attribute,
or any [Nomad interpolated
- values](/nomad/docs/runtime/interpolation#interpreted_node_vars).
+ values](/nomad/docs/reference/runtime-variable-interpolation#interpreted_node_vars).
- `weight` `(integer: 50)` - Specifies a weight for the affinity. The weight is used
during scoring and must be an integer between -100 to 100. Negative weights act as
@@ -274,6 +274,6 @@ The placement score is affected by the following factors:
[group]: /nomad/docs/job-specification/group
[client-meta]: /nomad/docs/configuration/client#meta
[task]: /nomad/docs/job-specification/task
-[interpolation]: /nomad/docs/runtime/interpolation
-[node-variables]: /nomad/docs/runtime/interpolation#node-variables
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation
+[node-variables]: /nomad/docs/reference/runtime-variable-interpolation#node-variables
[constraint]: /nomad/docs/job-specification/constraint
diff --git a/website/content/docs/job-specification/artifact.mdx b/website/content/docs/job-specification/artifact.mdx
index 4ab868e67..211e600ca 100644
--- a/website/content/docs/job-specification/artifact.mdx
+++ b/website/content/docs/job-specification/artifact.mdx
@@ -136,7 +136,7 @@ artifact {
To download from a private repo, sshkey needs to be set. The key must be
base64-encoded string. On Linux, you can run `base64 -w0 ` to encode the
-file. Or use [HCL2](/nomad/docs/job-specification/hcl2)
+file. Or use [HCL2](/nomad/docs/reference/hcl2)
expressions to read and encode the key from a file on your machine:
```hcl
@@ -282,7 +282,7 @@ artifact {
[s3-bucket-addr]: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro 'Amazon S3 Bucket Addressing'
[s3-region-endpoints]: http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region 'Amazon S3 Region Endpoints'
[iam-instance-profiles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html 'EC2 IAM instance profiles'
-[task's working directory]: /nomad/docs/runtime/environment#task-directories 'Task Directories'
+[task's working directory]: /nomad/docs/reference/runtime-environment-settings#task-directories 'Task Directories'
[task_user]: /nomad/docs/job-specification/task#user
[filesystem internals]: /nomad/docs/concepts/filesystem#templates-artifacts-and-dispatch-payloads
[do_spaces]: https://www.digitalocean.com/products/spaces
diff --git a/website/content/docs/job-specification/connect.mdx b/website/content/docs/job-specification/connect.mdx
index 31cbb14e0..df7c21195 100644
--- a/website/content/docs/job-specification/connect.mdx
+++ b/website/content/docs/job-specification/connect.mdx
@@ -10,7 +10,7 @@ description: |-
The `connect` block allows configuring various options for
-[Consul Connect](/nomad/docs/integrations/consul-connect). It is
+[Consul Connect](/nomad/docs/networking/consul). It is
valid only within the context of a service definition at the task group
level. For using `connect` when Consul ACLs are enabled, be sure to read through
the [Secure Nomad Jobs with Consul Connect](/nomad/tutorials/integrate-consul/consul-service-mesh)
@@ -246,7 +246,7 @@ job "ingress-demo" {
[group]: /nomad/docs/job-specification/group "Nomad group Job Specification"
-[interpolation]: /nomad/docs/runtime/interpolation "Nomad interpolation"
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation "Nomad interpolation"
[job]: /nomad/docs/job-specification/job "Nomad job Job Specification"
diff --git a/website/content/docs/job-specification/constraint.mdx b/website/content/docs/job-specification/constraint.mdx
index 3622c9f1a..548c1b58c 100644
--- a/website/content/docs/job-specification/constraint.mdx
+++ b/website/content/docs/job-specification/constraint.mdx
@@ -69,7 +69,7 @@ allocations.
- `attribute` `(string: "")` - Specifies the name or reference of the attribute
to examine for the constraint. This can be any of the [Nomad interpolated
- values](/nomad/docs/runtime/interpolation#interpreted_node_vars).
+ values](/nomad/docs/reference/runtime-variable-interpolation#interpreted_node_vars).
- `operator` `(string: "=")` - Specifies the comparison operator. If the operator
is one of `>, >=, <, <=`, the ordering is compared numerically if the operands
@@ -99,7 +99,7 @@ allocations.
- `value` `(string: "")` - Specifies the value to compare the attribute against
using the specified operation. This can be a literal value, another attribute,
or any [Nomad interpolated
- values](/nomad/docs/runtime/interpolation#interpreted_node_vars).
+ values](/nomad/docs/reference/runtime-variable-interpolation#interpreted_node_vars).
### `operator` values
@@ -319,7 +319,7 @@ constraint {
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[client-meta]: /nomad/docs/configuration/client#meta 'Nomad meta Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
-[node-variables]: /nomad/docs/runtime/interpolation#node-variables- 'Nomad interpolation-Node variables'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
+[node-variables]: /nomad/docs/reference/runtime-variable-interpolation#node-variables- 'Nomad interpolation-Node variables'
[client-meta]: /nomad/docs/configuration/client#custom-metadata-and-node-class 'Nomad Custom Metadata and Node Class'
[semver2]: https://semver.org/spec/v2.0.0.html 'Semantic Versioning 2.0'
diff --git a/website/content/docs/job-specification/consul.mdx b/website/content/docs/job-specification/consul.mdx
index cdd835067..2279e0bac 100644
--- a/website/content/docs/job-specification/consul.mdx
+++ b/website/content/docs/job-specification/consul.mdx
@@ -281,16 +281,16 @@ job "docs" {
[`identity`]: /nomad/docs/job-specification/identity
[`consul.service_identity`]: /nomad/docs/configuration/consul#service_identity
[`consul.token`]: /nomad/docs/configuration/consul#token
-[Configuring Consul Authentication]: /nomad/docs/integrations/consul/acl#configuring-consul-authentication
-[Migrating to Using Workload Identity with Consul]: /nomad/docs/integrations/consul/acl#migrating-to-using-workload-identity-with-consul
+[Configuring Consul Authentication]: /nomad/docs/secure/acl/consul#configuring-consul-authentication
+[Migrating to Using Workload Identity with Consul]: /nomad/docs/secure/acl/consul#migrating-to-using-workload-identity-with-consul
[config_consul_namespace]: /nomad/docs/configuration/consul#namespace
[Consul Namespaces]: /consul/docs/enterprise/namespaces
[Consul Admin Partitions]: /consul/docs/enterprise/admin-partitions
[template]: /nomad/docs/job-specification/template "Nomad template Job Specification"
[`consul.name`]: /nomad/docs/configuration/consul#name
-[flag_consul_namespace]: /nomad/docs/commands/job/run#consul-namespace
+[flag_consul_namespace]: /nomad/commands/job/run#consul-namespace
[Connect]: /nomad/docs/job-specification/connect
[admin partition]: /consul/docs/enterprise/admin-partitions
[agent configuration reference]: /consul/docs/agent/config/config-files#partition-1
[Consul Enterprise]: /consul/docs/enterprise
-[Nomad Workload Identities]: /nomad/docs/integrations/consul/acl#nomad-workload-identities
+[Nomad Workload Identities]: /nomad/docs/secure/acl/consul#nomad-workload-identities
diff --git a/website/content/docs/job-specification/csi_plugin.mdx b/website/content/docs/job-specification/csi_plugin.mdx
index e6f173fcc..3c0440549 100644
--- a/website/content/docs/job-specification/csi_plugin.mdx
+++ b/website/content/docs/job-specification/csi_plugin.mdx
@@ -137,5 +137,5 @@ job "plugin-efs" {
[csi]: https://github.com/container-storage-interface/spec
[csi_volumes]: /nomad/docs/job-specification/volume
-[system]: /nomad/docs/schedulers#system
-[`topology_request`]: /nomad/docs/commands/volume/create#topology_request
+[system]: /nomad/docs/concepts/scheduling/schedulers#system
+[`topology_request`]: /nomad/commands/volume/create#topology_request
diff --git a/website/content/docs/job-specification/dispatch_payload.mdx b/website/content/docs/job-specification/dispatch_payload.mdx
index 1ae70337a..240a89804 100644
--- a/website/content/docs/job-specification/dispatch_payload.mdx
+++ b/website/content/docs/job-specification/dispatch_payload.mdx
@@ -44,5 +44,5 @@ dispatch_payload {
}
```
-[localdir]: /nomad/docs/runtime/environment#local 'Task Local Directory'
-[parameterized]: /nomad/docs/job-specification/parameterized 'Nomad parameterized Job Specification'
+[localdir]: /nomad/docs/reference/runtime-environment-settings#local
+[parameterized]: /nomad/docs/job-specification/parameterized
diff --git a/website/content/docs/job-specification/env.mdx b/website/content/docs/job-specification/env.mdx
index 72fc4909f..d60a9874f 100644
--- a/website/content/docs/job-specification/env.mdx
+++ b/website/content/docs/job-specification/env.mdx
@@ -2,7 +2,7 @@
layout: docs
page_title: env block in the job specification
description: |-
- Configure environment variables in the `env` block of the Nomad job specification.
+ Configure environment variables in the `env` block of the Nomad job specification.
---
# `env` block in the job specification
@@ -80,5 +80,5 @@ Nomad also supports populating dynamic environment variables from data stored in
HashiCorp Consul and Vault. To use this feature please see the documentation on
the [`template` block][template-env].
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
[template-env]: /nomad/docs/job-specification/template#environment-variables 'Nomad template Block'
diff --git a/website/content/docs/job-specification/gateway.mdx b/website/content/docs/job-specification/gateway.mdx
index 5f13d6931..911143247 100644
--- a/website/content/docs/job-specification/gateway.mdx
+++ b/website/content/docs/job-specification/gateway.mdx
@@ -2,7 +2,7 @@
layout: docs
page_title: gateway block in the job specification
description: |-
- Configure a Consul mesh, ingress, or terminating gateway in the `gateway` block of the Nomad job specification.
+ Configure a Consul mesh, ingress, or terminating gateway in the `gateway` block of the Nomad job specification.
---
# `gateway` block in the job specification
@@ -729,7 +729,7 @@ job "countdash-mesh-two" {
[proxy]: /nomad/docs/job-specification/gateway#proxy-parameters
[linked-service]: /nomad/docs/job-specification/gateway#linked-service-parameters
[listener]: /nomad/docs/job-specification/gateway#listener-parameters
-[interpolation]: /nomad/docs/runtime/interpolation
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation
[listener-service]: /nomad/docs/job-specification/gateway#listener-service-parameters
[service-default]: /consul/docs/connect/config-entries/service-defaults
[sidecar_task]: /nomad/docs/job-specification/sidecar_task
diff --git a/website/content/docs/job-specification/group.mdx b/website/content/docs/job-specification/group.mdx
index 6970191b6..77879a0ba 100644
--- a/website/content/docs/job-specification/group.mdx
+++ b/website/content/docs/job-specification/group.mdx
@@ -202,7 +202,7 @@ group "example" {
[job]: /nomad/docs/job-specification/job 'Nomad job Job Specification'
[constraint]: /nomad/docs/job-specification/constraint 'Nomad constraint Job Specification'
[consul]: /nomad/docs/job-specification/consul
-[consul_namespace]: /nomad/docs/commands/job/run#consul-namespace
+[consul_namespace]: /nomad/commands/job/run#consul-namespace
[spread]: /nomad/docs/job-specification/spread 'Nomad spread Job Specification'
[affinity]: /nomad/docs/job-specification/affinity 'Nomad affinity Job Specification'
[ephemeraldisk]: /nomad/docs/job-specification/ephemeral_disk 'Nomad ephemeral_disk Job Specification'
@@ -215,7 +215,7 @@ group "example" {
[disconnect]: /nomad/docs/job-specification/disconnect 'Nomad disconnect Job Specification'
[restart]: /nomad/docs/job-specification/restart 'Nomad restart Job Specification'
[service]: /nomad/docs/job-specification/service 'Nomad service Job Specification'
-[service_discovery]: /nomad/docs/integrations/consul-integration#service-discovery 'Nomad Service Discovery'
+[service_discovery]: /nomad/docs/networking/service-discovery 'Nomad Service Discovery'
[update]: /nomad/docs/job-specification/update 'Nomad update Job Specification'
[vault]: /nomad/docs/job-specification/vault 'Nomad vault Job Specification'
[volume]: /nomad/docs/job-specification/volume 'Nomad volume Job Specification'
diff --git a/website/content/docs/job-specification/identity.mdx b/website/content/docs/job-specification/identity.mdx
index bf8fe6d44..c339f647a 100644
--- a/website/content/docs/job-specification/identity.mdx
+++ b/website/content/docs/job-specification/identity.mdx
@@ -360,9 +360,9 @@ EOF
[`template`]: /nomad/docs/job-specification/template
[`vault.default_identity`]: /nomad/docs/configuration/vault#default_identity
[`vault`]: /nomad/docs/job-specification/vault
-[int_consul_wid]: /nomad/docs/integrations/consul/acl
-[int_vault_wid]: /nomad/docs/integrations/vault/acl
+[int_consul_wid]: /nomad/docs/secure/acl/consul
+[int_vault_wid]: /nomad/docs/secure/vault/acl
[taskapi]: /nomad/api-docs/task-api
[taskuser]: /nomad/docs/job-specification/task#user "Nomad task Block"
[windows]: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
-[task working directory]: /nomad/docs/runtime/environment#task-directories 'Task Directories'
+[task working directory]: /nomad/docs/reference/runtime-environment-settings#task-directories 'Task Directories'
diff --git a/website/content/docs/job-specification/job.mdx b/website/content/docs/job-specification/job.mdx
index ba208e2d8..5bf563da6 100644
--- a/website/content/docs/job-specification/job.mdx
+++ b/website/content/docs/job-specification/job.mdx
@@ -245,12 +245,12 @@ $ VAULT_TOKEN="..." nomad job run example.nomad.hcl
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[meta]: /nomad/docs/job-specification/meta 'Nomad meta Job Specification'
[migrate]: /nomad/docs/job-specification/migrate 'Nomad migrate Job Specification'
-[namespace]: /nomad/tutorials/manage-clusters/namespaces
+[namespace]: /nomad/docs/govern/namespaces
[parameterized]: /nomad/docs/job-specification/parameterized 'Nomad parameterized Job Specification'
[periodic]: /nomad/docs/job-specification/periodic 'Nomad periodic Job Specification'
-[region]: /nomad/tutorials/manage-clusters/federation
+[region]: //nomad/docs/deploy/clusters/federate-regions
[reschedule]: /nomad/docs/job-specification/reschedule 'Nomad reschedule Job Specification'
-[scheduler]: /nomad/docs/schedulers 'Nomad Scheduler Types'
+[scheduler]: /nomad/docs/concepts/scheduling/schedulers 'Nomad Scheduler Types'
[spread]: /nomad/docs/job-specification/spread 'Nomad spread Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
[update]: /nomad/docs/job-specification/update 'Nomad update Job Specification'
diff --git a/website/content/docs/job-specification/logs.mdx b/website/content/docs/job-specification/logs.mdx
index ec41b9b67..8640b3862 100644
--- a/website/content/docs/job-specification/logs.mdx
+++ b/website/content/docs/job-specification/logs.mdx
@@ -93,6 +93,6 @@ logs {
}
```
-[logs-command]: /nomad/docs/commands/alloc/logs 'Nomad logs command'
-[`disable_log_collection`]: /nomad/docs/drivers/docker#disable_log_collection
+[logs-command]: /nomad/commands/alloc/logs 'Nomad logs command'
+[`disable_log_collection`]: /nomad/docs/deploy/task-driver/docker#disable_log_collection
[ephemeral disk documentation]: /nomad/docs/job-specification/ephemeral_disk 'Nomad ephemeral disk Job Specification'
diff --git a/website/content/docs/job-specification/meta.mdx b/website/content/docs/job-specification/meta.mdx
index dd57b174f..159bbccb5 100644
--- a/website/content/docs/job-specification/meta.mdx
+++ b/website/content/docs/job-specification/meta.mdx
@@ -110,5 +110,5 @@ EOH
[job]: /nomad/docs/job-specification/job 'Nomad job Job Specification'
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
-[env_meta]: /nomad/docs/runtime/environment#meta-block-for-arbitrary-configuration
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
+[env_meta]: /nomad/docs/reference/runtime-environment-settings#meta-block-for-arbitrary-configuration
diff --git a/website/content/docs/job-specification/migrate.mdx b/website/content/docs/job-specification/migrate.mdx
index ddf15a112..2e9574936 100644
--- a/website/content/docs/job-specification/migrate.mdx
+++ b/website/content/docs/job-specification/migrate.mdx
@@ -49,7 +49,7 @@ block for allocations on that node. The `migrate` block is for job authors to
define how their services should be migrated, while the node drain deadline is
for system operators to put hard limits on how long a drain may take.
-See the [Workload Migration Guide](/nomad/tutorials/manage-clusters/node-drain) for details
+See the [Workload Migration Guide](/nomad/docs/manage/migrate-workloads) for details
on node draining.
## Parameters
@@ -82,8 +82,8 @@ on node draining.
[checks]: /nomad/docs/job-specification/service#check
[count]: /nomad/docs/job-specification/group#count
-[drain]: /nomad/docs/commands/node/drain
-[deadline]: /nomad/docs/commands/node/drain#deadline
+[drain]: /nomad/commands/node/drain
+[deadline]: /nomad/commands/node/drain#deadline
[replaces]: /nomad/docs/job-specification/disconnect#replace
[`restart`]: /nomad/docs/job-specification/restart
[reschedules]: /nomad/docs/job-specification/reschedule
diff --git a/website/content/docs/job-specification/multiregion.mdx b/website/content/docs/job-specification/multiregion.mdx
index 3269d121f..7c8255b23 100644
--- a/website/content/docs/job-specification/multiregion.mdx
+++ b/website/content/docs/job-specification/multiregion.mdx
@@ -277,13 +277,13 @@ group "worker" {
}
```
-[federated regions]: /nomad/tutorials/manage-clusters/federation
+[federated regions]: //nomad/docs/deploy/clusters/federate-regions
[`update` block]: /nomad/docs/job-specification/update
[update-auto-revert]: /nomad/docs/job-specification/update#auto_revert
[examples]: #examples
-[upgrade strategies]: /nomad/tutorials/job-updates
-[`nomad deployment unblock`]: /nomad/docs/commands/deployment/unblock
+[upgrade strategies]: /nomad/docs/job-declare/strategy/
+[`nomad deployment unblock`]: /nomad/commands/deployment/unblock
[parameterized job]: /nomad/docs/job-specification/parameterized
-[`job dispatch`]: /nomad/docs/commands/job/dispatch
+[`job dispatch`]: /nomad/commands/job/dispatch
[HTTP API]: /nomad/api-docs/jobs#dispatch-job
[time zone]: /nomad/docs/job-specification/periodic#time_zone
diff --git a/website/content/docs/job-specification/network.mdx b/website/content/docs/job-specification/network.mdx
index cb50d7c4f..bee4e5041 100644
--- a/website/content/docs/job-specification/network.mdx
+++ b/website/content/docs/job-specification/network.mdx
@@ -39,7 +39,7 @@ job "docs" {
When the `network` block is defined with `bridge` as the networking mode,
all tasks in the task group share the same network namespace. This is a prerequisite for
-[Consul Connect](/nomad/docs/integrations/consul-connect). Tasks running within a
+[Consul Connect](/nomad/docs/networking/consul). Tasks running within a
network namespace are not visible to applications outside the namespace on the same host.
This allows [Connect][]-enabled applications to bind only to localhost within the shared network stack,
and use the proxy for ingress and egress traffic.
@@ -81,7 +81,7 @@ All other operating systems use the `host` networking mode.
- `hostname` `(string: "")` - The hostname assigned to the network namespace. This
is currently only supported using the [Docker driver][docker-driver] and when the
[mode](#mode) is set to [`bridge`](#bridge). This parameter supports
- [interpolation](/nomad/docs/runtime/interpolation).
+ [interpolation](/nomad/docs/reference/runtime-variable-interpolation).
- `dns` ([DNSConfig](#dns-parameters): nil) - Sets the DNS
configuration for the allocations. By default all task drivers will inherit
@@ -133,7 +133,7 @@ The label of the port is just text - it has no special meaning to Nomad.
- `searches` `(array: nil)` - Sets the search list for hostname lookup
- `options` `(array: nil)` - Sets internal resolver variables.
-These parameters support [interpolation](/nomad/docs/runtime/interpolation).
+These parameters support [interpolation](/nomad/docs/reference/runtime-variable-interpolation).
## `cni` parameters
@@ -141,7 +141,7 @@ These parameters support [interpolation](/nomad/docs/runtime/interpolation).
These get turned into `CNI_ARGS` per the
[CNI spec](https://www.cni.dev/docs/spec/#parameters).
-These parameters support [interpolation](/nomad/docs/runtime/interpolation).
+These parameters support [interpolation](/nomad/docs/reference/runtime-variable-interpolation).
## Examples
@@ -364,7 +364,7 @@ network {
variables are set for group network ports.
[docs_networking_bridge]: /nomad/docs/networking#bridge-networking
-[docker-driver]: /nomad/docs/drivers/docker 'Nomad Docker Driver'
-[qemu-driver]: /nomad/docs/drivers/qemu 'Nomad QEMU Driver'
+[docker-driver]: /nomad/docs/job-declare/task-driver/docker 'Nomad Docker Driver'
+[qemu-driver]: /nomad/docs/job-declare/task-driver/qemu 'Nomad QEMU Driver'
[connect]: /nomad/docs/job-specification/connect 'Nomad Consul Connect Integration'
[`cni_path`]: /nomad/docs/configuration/client#cni_path
diff --git a/website/content/docs/job-specification/parameterized.mdx b/website/content/docs/job-specification/parameterized.mdx
index 41adc948f..6523cd647 100644
--- a/website/content/docs/job-specification/parameterized.mdx
+++ b/website/content/docs/job-specification/parameterized.mdx
@@ -213,9 +213,9 @@ $ nomad job periodic force sync/dispatch-1730972650-247c6e97
```
[batch-type]: /nomad/docs/job-specification/job#type 'Batch scheduler type'
-[dispatch command]: /nomad/docs/commands/job/dispatch 'Nomad Job Dispatch Command'
+[dispatch command]: /nomad/commands/job/dispatch 'Nomad Job Dispatch Command'
[resources]: /nomad/docs/job-specification/resources 'Nomad resources Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad Runtime Interpolation'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad Runtime Interpolation'
[dispatch_payload]: /nomad/docs/job-specification/dispatch_payload 'Nomad dispatch_payload Job Specification'
[multiregion]: /nomad/docs/job-specification/multiregion#parameterized-dispatch
[periodic]: /nomad/docs/job-specification/periodic
diff --git a/website/content/docs/job-specification/proxy.mdx b/website/content/docs/job-specification/proxy.mdx
index c1320fb75..4319dc850 100644
--- a/website/content/docs/job-specification/proxy.mdx
+++ b/website/content/docs/job-specification/proxy.mdx
@@ -97,11 +97,11 @@ sidecar_service {
}
```
-[Consul Connect]: /nomad/docs/integrations/consul-connect
+[Consul Connect]: /nomad/docs/networking/consul
[job]: /nomad/docs/job-specification/job 'Nomad job Job Specification'
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
-[runtime variable interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
+[runtime variable interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
[sidecar_service]: /nomad/docs/job-specification/sidecar_service 'Nomad sidecar service Specification'
[upstreams]: /nomad/docs/job-specification/upstreams 'Nomad upstream config Specification'
[expose]: /nomad/docs/job-specification/expose 'Nomad proxy expose configuration'
diff --git a/website/content/docs/job-specification/resources.mdx b/website/content/docs/job-specification/resources.mdx
index 104a3c5ae..396c4d0bc 100644
--- a/website/content/docs/job-specification/resources.mdx
+++ b/website/content/docs/job-specification/resources.mdx
@@ -160,10 +160,10 @@ resource utilization and considering the following suggestions:
[api_sched_config]: /nomad/api-docs/operator/scheduler#update-scheduler-configuration
[device]: /nomad/docs/job-specification/device 'Nomad device Job Specification'
-[docker_cpu]: /nomad/docs/drivers/docker#cpu
-[exec_cpu]: /nomad/docs/drivers/exec#cpu
+[docker_cpu]: /nomad/docs/deploy/task-driver/docker#cpu
+[exec_cpu]: /nomad/docs/deploy/task-driver/exec#cpu
[np_sched_config]: /nomad/docs/other-specifications/node-pool#memory_oversubscription_enabled
[quota_spec]: /nomad/docs/other-specifications/quota
[numa]: /nomad/docs/job-specification/numa 'Nomad NUMA Job Specification'
-[`secrets/`]: /nomad/docs/runtime/environment#secrets
-[concepts-cpu]: /nomad/docs/concepts/cpu
+[`secrets/`]: /nomad/docs/reference/runtime-environment-settings#secrets
+[concepts-cpu]: /nomad/docs/architecture/cpu
diff --git a/website/content/docs/job-specification/service.mdx b/website/content/docs/job-specification/service.mdx
index 0a9df0bf9..0c06814a7 100644
--- a/website/content/docs/job-specification/service.mdx
+++ b/website/content/docs/job-specification/service.mdx
@@ -318,7 +318,7 @@ network {
### Using driver address mode
-The [Docker](/nomad/docs/drivers/docker#network_mode) driver supports the `driver`
+The [Docker](/nomad/docs/job-declare/task-driver/docker#network_mode) driver supports the `driver`
setting for the `address_mode` parameter in both `service` and `check` blocks.
The driver address mode allows advertising and health checking the IP and port
assigned to a task by the driver. This way, if you're using a network plugin like
@@ -430,7 +430,7 @@ directly since Nomad isn't managing any port assignments.
### IPv6 Docker containers
-The [Docker](/nomad/docs/drivers/docker#advertise_ipv6_address) driver supports the
+The [Docker](/nomad/docs/job-declare/task-driver/docker#advertise_ipv6_address) driver supports the
`advertise_ipv6_address` parameter in its configuration.
Services will automatically advertise the IPv6 address when `advertise_ipv6_address`
@@ -536,10 +536,10 @@ advertise and check directly since Nomad isn't managing any port assignments.
[check_restart_block]: /nomad/docs/job-specification/check_restart
[consul_grpc]: /consul/api-docs/agent/check#grpc
[consul_passfail]: /consul/docs/discovery/checks#success-failures-before-passing-critical
-[service-discovery]: /nomad/docs/integrations/consul-integration#service-discovery 'Nomad Service Discovery'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad Runtime Interpolation'
+[service-discovery]: /nomad/docs/networking/service-discovery 'Nomad Service Discovery'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad Runtime Interpolation'
[network]: /nomad/docs/job-specification/network 'Nomad network Job Specification'
-[qemu]: /nomad/docs/drivers/qemu 'Nomad QEMU Driver'
+[qemu]: /nomad/docs/job-declare/task-driver/qemu 'Nomad QEMU Driver'
[restart_block]: /nomad/docs/job-specification/restart 'restart block'
[connect]: /nomad/docs/job-specification/connect 'Nomad Consul Connect Integration'
[kind]: /consul/api-docs/agent/service#kind
diff --git a/website/content/docs/job-specification/sidecar_service.mdx b/website/content/docs/job-specification/sidecar_service.mdx
index 16c94979e..9c622ce6b 100644
--- a/website/content/docs/job-specification/sidecar_service.mdx
+++ b/website/content/docs/job-specification/sidecar_service.mdx
@@ -12,7 +12,7 @@ description: |-
The `sidecar_service` block allows configuring various options for the sidecar
proxy managed by Nomad for [Consul
-Connect](/nomad/docs/integrations/consul-connect) integration. It is
+Connect](/nomad/docs/networking/consul) integration. It is
valid only within the context of a connect block.
```hcl
@@ -89,6 +89,6 @@ The following example includes specifying upstreams and meta.
[job]: /nomad/docs/job-specification/job 'Nomad job Job Specification'
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
[sidecar_service]: /nomad/docs/job-specification/sidecar_service 'Nomad sidecar service Specification'
[proxy]: /nomad/docs/job-specification/proxy 'Nomad sidecar proxy config Specification'
diff --git a/website/content/docs/job-specification/sidecar_task.mdx b/website/content/docs/job-specification/sidecar_task.mdx
index 3cefcac05..b2ea0256f 100644
--- a/website/content/docs/job-specification/sidecar_task.mdx
+++ b/website/content/docs/job-specification/sidecar_task.mdx
@@ -12,7 +12,7 @@ description: |-
The `sidecar_task` block allows configuring various options for the proxy
sidecar or Connect gateway managed by Nomad for the [Consul
-Connect](/nomad/docs/integrations/consul-connect) integration such as
+Connect](/nomad/docs/networking/consul) integration such as
resource requirements, kill timeouts and more as defined below. It is valid
only within the context of a [`connect`][connect] block.
@@ -179,7 +179,7 @@ The following example configures resources for the sidecar task and other config
[connect]: /nomad/docs/job-specification/connect 'Nomad connect Job Specification'
[gateway]: /nomad/docs/job-specification/gateway
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
[job]: /nomad/docs/job-specification/job 'Nomad job Job Specification'
[logs]: /nomad/docs/job-specification/logs 'Nomad logs Job Specification'
[resources]: /nomad/docs/job-specification/resources 'Nomad resources Job Specification'
diff --git a/website/content/docs/job-specification/spread.mdx b/website/content/docs/job-specification/spread.mdx
index ca34e3ae3..79d04f00b 100644
--- a/website/content/docs/job-specification/spread.mdx
+++ b/website/content/docs/job-specification/spread.mdx
@@ -78,7 +78,7 @@ allocations.
- `attribute` `(string: "")` - Specifies the name or reference of the attribute
to use. This can be any of the [Nomad interpolated
- values](/nomad/docs/runtime/interpolation#interpreted_node_vars).
+ values](/nomad/docs/reference/runtime-variable-interpolation#interpreted_node_vars).
- `target` ([target](#target-parameters): <required>) - Specifies one or more target
percentages for each value of the `attribute` in the spread block. If this is omitted,
@@ -88,7 +88,7 @@ allocations.
during scoring and must be an integer between 0 to 100. Weights can be used
when there is more than one spread or affinity block to express relative preference across them.
-## Parameters
+### Target parameters
- `value` `(string:"")` - Specifies a target value of the attribute from a `spread` block.
@@ -202,8 +202,8 @@ spread {
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[client-meta]: /nomad/docs/configuration/client#meta 'Nomad meta Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
-[node-variables]: /nomad/docs/runtime/interpolation#node-variables- 'Nomad interpolation-Node variables'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
+[node-variables]: /nomad/docs/reference/runtime-variable-interpolation#node-variables- 'Nomad interpolation-Node variables'
[constraint]: /nomad/docs/job-specification/constraint 'Nomad Constraint job Specification'
-[Key Metrics]: /nomad/docs/operations/metrics-reference#key-metrics
-[scheduler algorithm]: /nomad/docs/commands/operator/scheduler/set-config#scheduler-algorithm
+[Key Metrics]: /nomad/docs/reference/metrics#key-metrics
+[scheduler algorithm]: /nomad/commands/operator/scheduler/set-config#scheduler-algorithm
diff --git a/website/content/docs/job-specification/task.mdx b/website/content/docs/job-specification/task.mdx
index 3f681b913..3fe1b4da3 100644
--- a/website/content/docs/job-specification/task.mdx
+++ b/website/content/docs/job-specification/task.mdx
@@ -48,7 +48,7 @@ job "docs" {
task to have access to dispatch payloads.
- `driver` - Specifies the task driver that should be used to run the
- task. See the [driver documentation](/nomad/docs/drivers) for what
+ task. See the [driver documentation](/nomad/docs/job-declare/task-driver) for what
is available. Examples include `docker`, `qemu`, `java` and `exec`.
- `env` ([Env][]: nil) - Specifies environment variables that will
@@ -139,7 +139,7 @@ The following examples only show the `task` blocks. Remember that the
This example defines a task that starts a Docker container as a service. Docker
is just one of many drivers supported by Nomad. Read more about drivers in the
-[Nomad drivers documentation](/nomad/docs/drivers).
+[Nomad drivers documentation](/nomad/docs/job-declare/task-driver).
```hcl
task "server" {
@@ -225,16 +225,16 @@ task "server" {
[service]: /nomad/docs/job-specification/service 'Nomad service Job Specification'
[vault]: /nomad/docs/job-specification/vault 'Nomad vault Job Specification'
[volumemount]: /nomad/docs/job-specification/volume_mount 'Nomad volume_mount Job Specification'
-[exec]: /nomad/docs/drivers/exec 'Nomad exec Driver'
-[raw_exec]: /nomad/docs/drivers/raw_exec 'Nomad raw_exec Driver'
-[java]: /nomad/docs/drivers/java 'Nomad Java Driver'
-[docker]: /nomad/docs/drivers/docker 'Nomad Docker Driver'
+[exec]: /nomad/docs/job-declare/task-driver/exec 'Nomad exec Driver'
+[raw_exec]: /nomad/docs/job-declare/task-driver/raw_exec 'Nomad raw_exec Driver'
+[java]: /nomad/docs/job-declare/task-driver/java 'Nomad Java Driver'
+[docker]: /nomad/docs/job-declare/task-driver/docker 'Nomad Docker Driver'
[rkt]: /nomad/plugins/drivers/community/rkt 'Nomad rkt Driver'
-[service_discovery]: /nomad/docs/integrations/consul-integration#service-discovery 'Nomad Service Discovery'
+[service_discovery]: /nomad/docs/networking/service-discovery 'Nomad Service Discovery'
[template]: /nomad/docs/job-specification/template 'Nomad template Job Specification'
[user_drivers]: /nomad/docs/configuration/client#user-checked_drivers
[user_denylist]: /nomad/docs/configuration/client#user-denylist
[max_kill]: /nomad/docs/configuration/client#max_kill_timeout
[kill_signal]: /nomad/docs/job-specification/task#kill_signal
[Workload Identity]: /nomad/docs/concepts/workload-identity 'Nomad Workload Identity'
-[service]: /nomad/docs/install/windows-service
+[service]: /nomad/docs/deploy/production/windows-service
diff --git a/website/content/docs/job-specification/template.mdx b/website/content/docs/job-specification/template.mdx
index 61a8ce83f..3759dbfb8 100644
--- a/website/content/docs/job-specification/template.mdx
+++ b/website/content/docs/job-specification/template.mdx
@@ -818,12 +818,12 @@ options](/nomad/docs/configuration/client#options):
[nvars]: /nomad/docs/concepts/variables 'Nomad Variables'
[ct_api_tree]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#tree 'Consul Template API by HashiCorp - tree'
[gt]: https://pkg.go.dev/text/template 'Go template package'
-[gt_learn]: /nomad/tutorials/templates/go-template-syntax
+[gt_learn]: /nomad/docs/reference/go-template-syntax
[artifact]: /nomad/docs/job-specification/artifact 'Nomad artifact Job Specification'
-[env]: /nomad/docs/runtime/environment 'Nomad Runtime Environment'
-[nodevars]: /nomad/docs/runtime/interpolation#interpreted_node_vars 'Nomad Node Variables'
+[env]: /nomad/docs/reference/runtime-environment-settings 'Nomad Runtime Environment'
+[nodevars]: /nomad/docs/reference/runtime-variable-interpolation#interpreted_node_vars 'Nomad Node Variables'
[go-envparse]: https://github.com/hashicorp/go-envparse#readme 'The go-envparse Readme'
-[task working directory]: /nomad/docs/runtime/environment#task-directories 'Task Directories'
+[task working directory]: /nomad/docs/reference/runtime-environment-settings#task-directories 'Task Directories'
[filesystem internals]: /nomad/docs/concepts/filesystem#templates-artifacts-and-dispatch-payloads
[`client.template.wait_bounds`]: /nomad/docs/configuration/client#wait_bounds
[rhash]: https://en.wikipedia.org/wiki/Rendezvous_hashing
diff --git a/website/content/docs/job-specification/transparent_proxy.mdx b/website/content/docs/job-specification/transparent_proxy.mdx
index 5745a9b83..29f254469 100644
--- a/website/content/docs/job-specification/transparent_proxy.mdx
+++ b/website/content/docs/job-specification/transparent_proxy.mdx
@@ -162,7 +162,7 @@ sidecar_service {
[service intentions]: /consul/docs/connect/config-entries/service-intentions
[virtual IP]: /consul/docs/services/discovery/dns-static-lookups#service-virtual-ip-lookups
[`consul-cni`]: https://releases.hashicorp.com/consul-cni
-[cni_plugins]: /nomad/docs/networking/cni#cni-reference-plugins
+[cni_plugins]: /nomad/docs/job-networking/cni#cni-reference-plugins
[consul_dns_port]: /consul/docs/agent/config/config-files#dns_port
[`recursors`]: /consul/docs/agent/config/config-files#recursors
[port_labels]: /nomad/docs/job-specification/network#port-parameters
@@ -172,6 +172,6 @@ sidecar_service {
[`static`]: /nomad/docs/job-specification/network#static
[`outbound_listener_port`]: /consul/docs/connect/proxies/proxy-config-reference#outbound_listener_port
[`template`]: /nomad/docs/job-specification/template#consul-integration
-[`nomad node meta apply`]: /nomad/docs/commands/node/meta/apply
+[`nomad node meta apply`]: /nomad/commands/node/meta/apply
[`network.dns`]: /nomad/docs/job-specification/network#dns-parameters
-[Transparent Proxy]: /nomad/docs/integrations/consul/service-mesh#transparent-proxy
+[Transparent Proxy]: /nomad/docs/networking/consul/service-mesh#transparent-proxy
diff --git a/website/content/docs/job-specification/update.mdx b/website/content/docs/job-specification/update.mdx
index ef7b82c98..4e2b7fbf4 100644
--- a/website/content/docs/job-specification/update.mdx
+++ b/website/content/docs/job-specification/update.mdx
@@ -269,7 +269,7 @@ group "two" {
}
```
-[canary]: /nomad/tutorials/job-updates/job-blue-green-and-canary-deployments 'Nomad Canary Deployments'
+[canary]: /nomad/docs/job-declare/strategy/blue-green-canary 'Nomad Canary Deployments'
[checks]: /nomad/docs/job-specification/service#check
-[rolling]: /nomad/tutorials/job-updates/job-rolling-update 'Nomad Rolling Upgrades'
+[rolling]: /nomad/docs/job-declare/strategy/rolling 'Nomad Rolling Upgrades'
[strategies]: /nomad/tutorials/job-updates 'Nomad Update Strategies'
diff --git a/website/content/docs/job-specification/upstreams.mdx b/website/content/docs/job-specification/upstreams.mdx
index 91ec2aa11..80225985e 100644
--- a/website/content/docs/job-specification/upstreams.mdx
+++ b/website/content/docs/job-specification/upstreams.mdx
@@ -135,13 +135,13 @@ and a local bind port.
}
```
-[Consul Connect]: /nomad/docs/integrations/consul-connect
+[Consul Connect]: /nomad/docs/networking/consul
[Consul Connect Guide]: /consul/tutorials/get-started-vms/virtual-machine-gs-service-discovery
[`transparent_proxy`]: /nomad/docs/job-specification/transparent_proxy
[job]: /nomad/docs/job-specification/job 'Nomad job Job Specification'
[group]: /nomad/docs/job-specification/group 'Nomad group Job Specification'
[task]: /nomad/docs/job-specification/task 'Nomad task Job Specification'
-[interpolation]: /nomad/docs/runtime/interpolation 'Nomad interpolation'
+[interpolation]: /nomad/docs/reference/runtime-variable-interpolation 'Nomad interpolation'
[sidecar_service]: /nomad/docs/job-specification/sidecar_service 'Nomad sidecar service Specification'
[upstreams]: /nomad/docs/job-specification/upstreams 'Nomad upstream config Specification'
[service_defaults_mode]: /consul/docs/connect/config-entries/service-defaults#meshgateway
diff --git a/website/content/docs/job-specification/vault.mdx b/website/content/docs/job-specification/vault.mdx
index 1666d3c07..449608f0b 100644
--- a/website/content/docs/job-specification/vault.mdx
+++ b/website/content/docs/job-specification/vault.mdx
@@ -213,11 +213,11 @@ vault {
```
[`create_from_role`]: /nomad/docs/configuration/vault#create_from_role
-[docker]: /nomad/docs/drivers/docker "Docker Driver"
+[docker]: /nomad/docs/job-declare/task-driver/docker "Docker Driver"
[restart]: /nomad/docs/job-specification/restart "Nomad restart Job Specification"
[template]: /nomad/docs/job-specification/template "Nomad template Job Specification"
[vault]: https://www.vaultproject.io/ "Vault by HashiCorp"
[`vault.name`]: /nomad/docs/configuration/vault#name
[`vault_retry`]: /nomad/docs/configuration/client#vault_retry
-[Workload Identity with Vault]: /nomad/docs/integrations/vault/acl#nomad-workload-identities
-[legacy Vault authentication workflow]: /nomad/docs/v1.8.x/integrations/vault/acl#authentication-without-workload-identity-legacy
+[Workload Identity with Vault]: /nomad/docs/secure/vault/acl#nomad-workload-identities
+[legacy Vault authentication workflow]: /nomad/docs/v1.8.x/integrations/vault/acl
diff --git a/website/content/docs/job-specification/volume.mdx b/website/content/docs/job-specification/volume.mdx
index 26f8adf33..1af5d9801 100644
--- a/website/content/docs/job-specification/volume.mdx
+++ b/website/content/docs/job-specification/volume.mdx
@@ -238,12 +238,12 @@ ID Node ID Task Group Version Desired Status Created Modified
[volume_mount]: /nomad/docs/job-specification/volume_mount 'Nomad volume_mount Job Specification'
[host_volume]: /nomad/docs/configuration/client#host_volume-block
-[csi_volume]: /nomad/docs/commands/volume/register
+[csi_volume]: /nomad/commands/volume/register
[csi_plugin]: /nomad/docs/job-specification/csi_plugin
-[csi_volume]: /nomad/docs/commands/volume/register
-[attachment mode]: /nomad/docs/commands/volume/register#attachment_mode
-[volume registration]: /nomad/docs/commands/volume/register#mount_options
+[csi_volume]: /nomad/commands/volume/register
+[attachment mode]: /nomad/commands/volume/register#attachment_mode
+[volume registration]: /nomad/commands/volume/register#mount_options
[dynamic host volumes]: /nomad/docs/other-specifications/volume/host
[stateful deployments]: /nomad/docs/concepts/stateful-deployments
-[`volume create`]: /nomad/docs/commands/volume/create
-[`volume register`]: /nomad/docs/commands/volume/register
+[`volume create`]: /nomad/commands/volume/create
+[`volume register`]: /nomad/commands/volume/register
diff --git a/website/content/docs/job-specification/volume_mount.mdx b/website/content/docs/job-specification/volume_mount.mdx
index 9944f8022..007bd3d43 100644
--- a/website/content/docs/job-specification/volume_mount.mdx
+++ b/website/content/docs/job-specification/volume_mount.mdx
@@ -77,4 +77,4 @@ volumes, see [Volume Interpolation].
[volume]: /nomad/docs/job-specification/volume 'Nomad volume Job Specification'
[volume interpolation]: /nomad/docs/job-specification/volume#volume-interpolation
-[hcl2]: /nomad/docs/job-specification/hcl2
+[hcl2]: /nomad/docs/reference/hcl2
diff --git a/website/content/docs/manage/autopilot.mdx b/website/content/docs/manage/autopilot.mdx
new file mode 100644
index 000000000..a9e781b41
--- /dev/null
+++ b/website/content/docs/manage/autopilot.mdx
@@ -0,0 +1,244 @@
+---
+layout: docs
+page_title: Autopilot
+description: |-
+ Configure and use Autopilot features to help maintain your cluster. Monitor
+ server health, upgrade and clean up servers, and use redundancy zones.
+---
+
+# Autopilot
+
+Autopilot is a set of new features added in Nomad 0.8 to allow for automatic
+operator-friendly management of Nomad servers. It includes cleanup of dead
+servers, monitoring the state of the Raft cluster, and stable server
+introduction.
+
+To enable Autopilot features (with the exception of dead server cleanup), the
+`raft_protocol` setting in the [server stanza] must be set to 3 on all servers.
+
+## Configuration
+
+The configuration of Autopilot is loaded by the leader from the agent's
+[Autopilot settings] when initially bootstrapping the cluster:
+
+```hcl
+autopilot {
+ cleanup_dead_servers = true
+ last_contact_threshold = "200ms"
+ max_trailing_logs = 250
+ server_stabilization_time = "10s"
+ enable_redundancy_zones = false
+ disable_upgrade_migration = false
+ enable_custom_upgrades = false
+}
+
+```
+
+After bootstrapping, the configuration can be viewed or modified either via the
+[`operator autopilot`] subcommand or the
+[`/v1/operator/autopilot/configuration`] HTTP endpoint:
+
+View the configuration.
+
+```shell-session
+$ nomad operator autopilot get-config
+CleanupDeadServers = true
+LastContactThreshold = 200ms
+MaxTrailingLogs = 250
+ServerStabilizationTime = 10s
+EnableRedundancyZones = false
+DisableUpgradeMigration = false
+EnableCustomUpgrades = false
+```
+
+Update the configuration.
+
+```shell-session
+$ nomad operator autopilot set-config -cleanup-dead-servers=false
+Configuration updated!
+```
+
+View the configuration to confirm your changes.
+
+```shell-session
+$ nomad operator autopilot get-config
+CleanupDeadServers = false
+LastContactThreshold = 200ms
+MaxTrailingLogs = 250
+ServerStabilizationTime = 10s
+EnableRedundancyZones = false
+DisableUpgradeMigration = false
+EnableCustomUpgrades = false
+```
+
+## Dead server cleanup
+
+Dead servers will periodically be cleaned up and removed from the Raft peer set,
+to prevent them from interfering with the quorum size and leader elections. This
+cleanup will also happen whenever a new server is successfully added to the
+cluster.
+
+Prior to Autopilot, it would take 72 hours for dead servers to be automatically
+reaped, or operators had to script a `nomad force-leave`. If another server
+failure occurred, it could jeopardize the quorum, even if the failed Nomad
+server had been automatically replaced. Autopilot helps prevent these kinds of
+outages by quickly removing failed servers as soon as a replacement Nomad server
+comes online. When servers are removed by the cleanup process they will enter
+the "left" state.
+
+This option can be disabled by running `nomad operator autopilot set-config`
+with the `-cleanup-dead-servers=false` option.
+
+## Server health checking
+
+An internal health check runs on the leader to monitor the stability of servers.
+A server is considered healthy if all of the following conditions are true:
+
+- Its status according to Serf is 'Alive'
+
+- The time since its last contact with the current leader is below
+ `LastContactThreshold`
+
+- Its latest Raft term matches the leader's term
+
+- The number of Raft log entries it trails the leader by does not exceed
+ `MaxTrailingLogs`
+
+The status of these health checks can be viewed through the
+[`/v1/operator/autopilot/health`] HTTP endpoint, with a top level `Healthy`
+field indicating the overall status of the cluster:
+
+```shell-session
+$ curl localhost:4646/v1/operator/autopilot/health
+{
+ "Healthy": true,
+ "FailureTolerance": 0,
+ "Servers": [
+ {
+ "ID": "e349749b-3303-3ddf-959c-b5885a0e1f6e",
+ "Name": "node1",
+ "Address": "127.0.0.1:4647",
+ "SerfStatus": "alive",
+ "Version": "0.8.0",
+ "Leader": true,
+ "LastContact": "0s",
+ "LastTerm": 2,
+ "LastIndex": 10,
+ "Healthy": true,
+ "Voter": true,
+ "StableSince": "2017-03-28T18:28:52Z"
+ },
+ {
+ "ID": "e35bde83-4e9c-434f-a6ef-453f44ee21ea",
+ "Name": "node2",
+ "Address": "127.0.0.1:4747",
+ "SerfStatus": "alive",
+ "Version": "0.8.0",
+ "Leader": false,
+ "LastContact": "35.371007ms",
+ "LastTerm": 2,
+ "LastIndex": 10,
+ "Healthy": true,
+ "Voter": false,
+ "StableSince": "2017-03-28T18:29:10Z"
+ }
+ ]
+}
+
+```
+
+## Stable server introduction
+
+When a new server is added to the cluster, there is a waiting period where it
+must be healthy and stable for a certain amount of time before being promoted to
+a full, voting member. This can be configured via the `ServerStabilizationTime`
+setting.
+
+---
+
+~> The following Autopilot features are available only in [Nomad Enterprise]
+version 0.8.0 and later.
+
+## Server read and scheduling scaling
+
+With the [`non_voting_server`] option, a server can be explicitly marked as a
+non-voter and will never be promoted to a voting member. This can be useful when
+more read scaling is needed; being a non-voter means that the server will still
+have data replicated to it, but it will not be part of the quorum that the
+leader must wait for before committing log entries. Non voting servers can also
+act as scheduling workers to increase scheduling throughput in large clusters.
+
+## Redundancy zones
+
+Prior to Autopilot, it was difficult to deploy servers in a way that took
+advantage of isolated failure domains such as AWS Availability Zones; users
+would be forced to either have an overly-large quorum (2-3 nodes per AZ) or give
+up redundancy within an AZ by deploying only one server in each.
+
+If the `EnableRedundancyZones` setting is set, Nomad will use its value to look
+for a zone in each server's specified [`redundancy_zone`] field.
+
+Here's an example showing how to configure this:
+
+```hcl
+/* config.hcl */
+server {
+ redundancy_zone = "west-1"
+}
+```
+
+```shell-session
+$ nomad operator autopilot set-config -enable-redundancy-zones=true
+Configuration updated!
+```
+
+Nomad will then use these values to partition the servers by redundancy zone,
+and will aim to keep one voting server per zone. Extra servers in each zone will
+stay as non-voters on standby to be promoted if the active voter leaves or dies.
+
+## Upgrade migrations
+
+Autopilot in Nomad Enterprise supports upgrade migrations by default. To disable
+this functionality, set `DisableUpgradeMigration` to true.
+
+When a new server is added and Autopilot detects that its Nomad version is newer
+than that of the existing servers, Autopilot will avoid promoting the new server
+until enough newer-versioned servers have been added to the cluster. When the
+count of new servers equals or exceeds that of the old servers, Autopilot will
+begin promoting the new servers to voters and demoting the old servers. After
+this is finished, the old servers can be safely removed from the cluster.
+
+To check the Nomad version of the servers, either the [autopilot health]
+endpoint or the `nomad members`command can be used:
+
+```shell-session
+$ nomad server members
+Name Address Port Status Leader Protocol Build Datacenter Region
+node1 127.0.0.1 4648 alive true 3 0.7.1 dc1 global
+node2 127.0.0.1 4748 alive false 3 0.7.1 dc1 global
+node3 127.0.0.1 4848 alive false 3 0.7.1 dc1 global
+node4 127.0.0.1 4948 alive false 3 0.8.0 dc1 global
+```
+
+### Migrations without a Nomad version change
+
+The `EnableCustomUpgrades` field can be used to override the version information
+used during a migration, so that the migration logic can be used for updating
+the cluster when changing configuration.
+
+If the `EnableCustomUpgrades` setting is set to `true`, Nomad will use its value
+to look for a version in each server's specified [`upgrade_version`] tag. The
+upgrade logic will follow semantic versioning and the `upgrade_version` must be
+in the form of either `X`, `X.Y`, or `X.Y.Z`.
+
+[`/v1/operator/autopilot/configuration`]: /nomad/api-docs/operator/autopilot
+[`/v1/operator/autopilot/health`]: /nomad/api-docs/operator/autopilot#read-health
+[`non_voting_server`]: /nomad/docs/configuration/server#non_voting_server
+[`operator autopilot`]: /nomad/commands/operator
+[`redundancy_zone`]: /nomad/docs/configuration/server#redundancy_zone
+[`upgrade_version`]: /nomad/docs/configuration/server#upgrade_version
+[autopilot health]: /nomad/api-docs/operator/autopilot#read-health
+[autopilot settings]: /nomad/docs/configuration/autopilot
+[nomad enterprise]: https://www.hashicorp.com/products/nomad
+[server stanza]: /nomad/docs/configuration/server
+[version upgrade section]: /nomad/docs/upgrade/upgrade-specific#raft-protocol-version-compatibility
diff --git a/website/content/docs/manage/format-cli-output.mdx b/website/content/docs/manage/format-cli-output.mdx
new file mode 100644
index 000000000..0b99a8271
--- /dev/null
+++ b/website/content/docs/manage/format-cli-output.mdx
@@ -0,0 +1,415 @@
+---
+layout: docs
+page_title: Format CLI output with templates
+description: |-
+ Customize the output of Nomad CLI commands with Go template syntax. Practice
+ interacting with unfamiliar template contexts.
+---
+
+# Format CLI output with templates
+
+When using Nomad at an intermediate to advanced level, you'll need to interface with other systems or customize output generated by Nomad. The `-t` flag is a powerful way to pass a template in Go's text/template format to
+several of the Nomad commands that generate output based on the API. This allows
+you to filter and customize the output to meet your specific needs.
+
+The commands that allow for the -t flag are:
+
+- `nomad acl policy list`
+- `nomad acl token list`
+- `nomad alloc status`
+- `nomad deployment list`
+- `nomad deployment status`
+- `nomad eval status`
+- `nomad job deployments`
+- `nomad job history`
+- `nomad job inspect`
+- `nomad namespace list`
+- `nomad node status`
+- `nomad plugin status`
+- `nomad quota list`
+- `nomad volume status`
+
+This guide will teach you how to explore the objects that are returned to
+the template engine and how to use template syntax to format the output into
+a custom form.
+
+## Prerequisites
+
+This guide assumes the following:
+
+- Familiarity with Go's text/template syntax. You can learn more about it in the
+ [Go template syntax][go-template-syntax] reference.
+
+- That you are running these commands against a Nomad cluster with an active
+ workload. You can create a minimal environment using a dev agent, started with
+ `sudo nomad agent -dev`, then running at least one Nomad job. You can use
+ `nomad init -short` to create a sample Docker job or provide your own Nomad
+ job.
+
+## Note the shell-specific syntax
+
+When using the -t flag, you need to correctly handle string literals based on
+your shell environment. In a POSIX shell, you can run the following with a
+single quote:
+
+```shell-session
+$ nomad node status -t '{{printf "%#+v" .}}'
+```
+
+In a Windows shell (for example, PowerShell), use single
+quotes but escape the double quotes inside the parameter as follows:
+
+```powershell
+PS> nomad node status -t '{{printf \"%#+v\" .}}'
+```
+
+In this guide, you can select examples with the proper escaping using the
+tabs above the snippets.
+
+## Start discovering objects
+
+The `printf` function and the `"%#+v"` format string are critical tools for you
+in exploring an unfamiliar template context.
+
+Run the following command to output the context being passed to the template
+in Go object format.
+
+
+
+
+```shell-session
+$ nomad node status -t '{{printf "%#+v" .}}'
+```
+
+
+
+
+```powershell
+PS> nomad node status -t '{{printf \"%#+v\" .}}'
+```
+
+
+
+
+```plaintext
+[]*api.NodeListStub{(*api.NodeListStub)(0xc0003fa160), (*api.NodeListStub)(0xc0003fa0b0), (*api.NodeListStub)(0xc0003fa000)}
+```
+
+The output indicates that the context consists of a list (`[]`) of pointers
+(`*`) to `api.NodeListStub` objects. The list will also show one NodeListStub
+object per client node in your cluster's server state.
+
+You can explore these api.NodeListStub object by using the `range` control over
+the list.
+
+
+
+
+```shell-session
+$ nomad node status -t '{{range .}}{{printf "%#+v" .}}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad node status -t '{{range .}}{{printf \"%#+v\" .}}{{end}}'
+```
+
+
+
+
+```plaintext
+&api.NodeListStub{Address:"10.0.2.52", ID:"4f60bc83-71a2-7790-b120-4e55d0e6ed34", Datacenter:"dc1", Name:"nomad-client-2.node.consul", NodeClass:"", Version:"0.12.0", Drain:false, SchedulingEligibility:"eligible", Status:"ready", ...
+```
+
+If you have a lot of client nodes in your cluster state, this output will be
+unwieldy. In that case, you can use `with` and the index function to get the
+first list item.
+
+
+
+
+```shell-session
+$ nomad node status -t '{{with index . 0}}{{printf "%#+v" .}}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad node status -t '{{with index . 0}}{{printf \"%#+v\" .}}{{end}}'
+&api.NodeListStub{Address:"10.0.2.52", ID:"4f60bc83-71a2-7790-b120-4e55d0e6ed34", Datacenter:"dc1", Name:"nomad-client-2.node.consul", NodeClass:"", Version:"0.12.0", Drain:false, SchedulingEligibility:"eligible", Status:"ready", ...
+```
+
+
+
+
+```plaintext
+&api.NodeListStub{Address:"10.0.2.52", ID:"4f60bc83-71a2-7790-b120-4e55d0e6ed34", Datacenter:"dc1", Name:"nomad-client-2.node.consul", NodeClass:"", Version:"0.12.0", Drain:false, SchedulingEligibility:"eligible", Status:"ready", ...
+```
+
+Finally, output `Name` and `Version` for each client in the cluster.
+
+
+
+
+```shell-session
+$ nomad node status -t '{{range .}}{{printf "%s: %s\n" .Name .Version}}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad node status -t '{{range .}}{{printf \"%s: %s\n\" .Name .Version}}{{end}}'
+```
+
+
+
+
+```plaintext
+nomad-client-2.node.consul: 0.12.0
+nomad-client-3.node.consul: 0.12.0
+nomad-client-1.node.consul: 0.12.0
+```
+
+## Make quiet output
+
+Suppose you want to create a reduced version of the `nomad job status` output
+to show just the running job IDs in your cluster and nothing else.
+
+
+
+
+```shell-session
+$ nomad job inspect -t '{{range .}}{{if eq .Status "running"}}{{ println .Name}}{{end}}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad job inspect -t '{{range .}}{{if eq .Status \"running\"}}{{ println .Name}}{{end}}{{end}}'
+```
+
+
+
+
+Nomad will output the job IDs for every running job in your cluster. For example:
+
+```plaintext
+fabio
+sockshop-carts
+sockshop-catalogue
+sockshop-frontend
+sockshop-infra
+sockshop-orders
+sockshop-payment
+sockshop-shipping
+sockshop-user
+```
+
+### Challenge yourself
+
+Allocations have a slightly different shape. How might you create similar output
+from the `nomad alloc status` command? Make sure that your Nomad cluster has at
+least one allocation running and then use the printf technique from earlier to
+explore the values sent into the template.
+
+
+
+
+Print the context that you are passed from the command using the printf command.
+
+
+
+
+```shell-session
+$ nomad alloc status -t '{{printf "%#+v" . }}'
+```
+
+
+
+
+```powershell
+PS> nomad alloc status -t '{{printf \"%#+v\" . }}'
+```
+
+
+
+
+```plaintext
+[]*api.AllocationListStub ...
+```
+
+Note that the first thing that you receive is a list (`[]`) of pointers (`*`) to
+`AllocationListStub` objects.
+
+Use `range` to traverse each item in the list.
+
+
+
+
+```shell-session
+$ nomad alloc status -t '{{range .}}{{printf "%#+v" . }}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad alloc status -t '{{range .}}{{printf \"%#+v\" . }}{{end}}'
+```
+
+
+
+
+```plaintext
+&api.AllocationListStub{ID:"30663b68-4d8a-aada-4ad2-011b1acae3a1", EvalID:"c5eda90b-f675-048e-b2f7-9ced30e4916b", Name:"sockshop-user.userdb[0]", Namespace:"default", NodeID:"3be35c12-70aa-8816-195e-a4630a457727", NodeName:"nomad-client-3.node.consul", JobID:"sockshop-user", JobType:"service", JobVersion:0x0, ...
+```
+
+If you have a lot of allocations running, this could get unwieldy. In that case,
+you can use `with` and the index function to get the first list item.
+
+
+
+
+```shell-session
+$ nomad alloc status -t '{{with index . 0}}{{printf "%#+v" . }}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad alloc status -t '{{with index . 0}}{{printf \"%#+v\" . }}{{end}}'
+```
+
+
+
+
+```plaintext
+&api.AllocationListStub{ID:"30663b68-4d8a-aada-4ad2-011b1acae3a1", EvalID:"c5eda90b-f675-048e-b2f7-9ced30e4916b", Name:"sockshop-user.userdb[0]", Namespace:"default", NodeID:"3be35c12-70aa-8816-195e-a4630a457727", NodeName:"nomad-client-3.node.consul", JobID:"sockshop-user", JobType:"service", JobVersion:0x0, ...
+```
+
+The fields on the AllocationListStub object that give insight into the running
+state of an allocation are `DesiredStatus` and `ClientStatus`.
+
+-> **Did you know?** The definition of an [AllocationListStub][] object and
+valid values for the DesiredStatus and ClientStatus are located in Nomad's
+[api package][]. Take a moment to look at it and see what other information you
+might be interested in displaying with templates.
+
+Update your template to show items with a DesiredStatus of "run" and a client
+status of "running" or "pending."
+
+
+
+
+```shell-session
+$ nomad alloc status -t '{{range .}}{{if and (eq .DesiredStatus "run") (or (eq .ClientStatus "running") (eq .ClientStatus "pending"))}}{{println .ID}}{{end}}{{end}}'
+```
+
+
+
+
+```powershell
+PS> nomad alloc status -t '{{range .}}{{if and (eq .DesiredStatus \"run\") (or (eq .ClientStatus \"running\") (eq .ClientStatus \"pending\"))}}{{println .ID}}{{end}}{{end}}'
+```
+
+
+
+
+```plaintext
+30663b68-4d8a-aada-4ad2-011b1acae3a1
+11b916da-d679-1718-26f3-f6cd499bfdb8
+68bcb157-359f-9293-d091-5a8ef71475ad
+...
+```
+
+You now have a list of the IDs for all of the allocations running in your Nomad
+cluster.
+
+
+
+
+## Retrieve a template from file
+
+Using the command line to write templates becomes challenging
+as the template becomes more complex.
+
+By writing a template in its own file, you can use comments, span multiple lines, and indent conditionals in order to make them more readable to you and to other operators.
+
+Consider using some of these techniques
+to include the template data into the command.
+
+
+
+
+
+Create a file named running_jobs.tmpl with the following content.
+
+```plaintext
+{{- /*
+ Get Running Jobs
+ Run with `nomad job inspect -t "$(cat running_jobs.tmpl)"`
+*/ -}}
+{{- range . -}}
+ {{- if eq .Status "running" -}}
+ {{- println .Name -}}
+ {{- end -}}
+{{- end -}}
+```
+
+Now, use a subshell to read the file into a variable
+
+```shell-session
+$ nomad job inspect -t "$(cat running_jobs.tmpl)"
+```
+
+
+
+
+
+Create a file named running_jobs.tmpl with the following content.
+
+```plaintext
+{{- /*
+ Get Running Jobs
+ Run with:
+ $content=Get-Content running_jobs.tmpl -Raw; nomad job inspect -t $content
+*/ -}}
+{{- range . -}}
+ {{- if eq .Status \"running\" -}}
+ {{- println .Name -}}
+ {{- end -}}
+{{- end -}}
+```
+
+Now, use a subshell to read the file into a variable
+
+```powershell
+PS> $content=Get-Content running_jobs.tmpl -Raw; nomad job inspect -t $content
+```
+
+
+
+
+
+## Learn more
+
+In this guide, you learned how to:
+
+- Customize the output of several Nomad commands using Go's text/template
+ syntax.
+
+- Use the `printf` function to discover what is available in the template's
+ context.
+
+- Use a template definition contained in a file as part of the command.
+
+
+[go-template-syntax]: /nomad/docs/reference/go-template-syntax
+[allocationliststub]: https://godoc.org/github.com/hashicorp/nomad/api#AllocationListStub
+[api package]: https://godoc.org/github.com/hashicorp/nomad/api
diff --git a/website/content/docs/operations/garbage-collection.mdx b/website/content/docs/manage/garbage-collection.mdx
similarity index 98%
rename from website/content/docs/operations/garbage-collection.mdx
rename to website/content/docs/manage/garbage-collection.mdx
index 3fc2a5b84..f6fb5307c 100644
--- a/website/content/docs/operations/garbage-collection.mdx
+++ b/website/content/docs/manage/garbage-collection.mdx
@@ -186,7 +186,7 @@ allocation is terminal, the client garbage collection process communicates with
the task driver to ensure the task's resources have been cleaned up. Note that
the Docker task driver periodically cleans up its own resources. Refer to the
[Docker task driver plugin
-options](https://developer.hashicorp.com/nomad/docs/drivers/docker#gc) for
+options](https://developer.hashicorp.com/nomad/docs/deploy/task-driver/docker#gc) for
details.
When a task has configured restart attempts and the task fails, the Nomad client
@@ -210,5 +210,5 @@ disk space might not be fully reclaimed until fixed.
- [client Block in Agent Configuration](/nomad/docs/configuration/client)
- [server Block in Agent Configuration](/nomad/docs/configuration/server)
-- [the `nomad system gc` command reference](/nomad/docs/commands/system/gc)
+- [the `nomad system gc` command reference](/nomad/commands/system/gc)
- [System HTTP API Force GC](/nomad/api-docs/system#force-gc)
diff --git a/website/content/docs/manage/index.mdx b/website/content/docs/manage/index.mdx
new file mode 100644
index 000000000..ea2ddaf4c
--- /dev/null
+++ b/website/content/docs/manage/index.mdx
@@ -0,0 +1,10 @@
+---
+layout: docs
+page_title: Manage Nomad
+description: |-
+ This section provides guidance on the operational management of Nomad. Topics include garbage collection, key management, workload migration, outage recovery, enabling Autopilot, formatting command output, and using namespaces.
+---
+
+# Manage Nomad
+
+This section provides guidance on the operational management of Nomad. Topics include garbage collection, key management, workload migration, outage recovery, enabling Autopilot, formatting command output, and using namespaces.
diff --git a/website/content/docs/operations/key-management.mdx b/website/content/docs/manage/key-management.mdx
similarity index 94%
rename from website/content/docs/operations/key-management.mdx
rename to website/content/docs/manage/key-management.mdx
index c0b5b6e8f..25704c513 100644
--- a/website/content/docs/operations/key-management.mdx
+++ b/website/content/docs/manage/key-management.mdx
@@ -91,9 +91,9 @@ keyring rotate`][] once the servers have joined.
[variables]: /nomad/docs/concepts/variables
[workload identities]: /nomad/docs/concepts/workload-identity
-[client assertion JWTs]: /nomad/docs/concepts/acl/auth-methods/oidc#client-assertions
+[client assertion JWTs]: /nomad/docs/secure/authentication/oidc#client-assertions
[data directory]: /nomad/docs/configuration#data_dir
[`keyring`]: /nomad/docs/configuration/keyring
-[`nomad operator root keyring rotate -full`]: /nomad/docs/commands/operator/root/keyring-rotate
-[`nomad operator root keyring rotate`]: /nomad/docs/commands/operator/root/keyring-rotate
+[`nomad operator root keyring rotate -full`]: /nomad/commands/operator/root/keyring-rotate
+[`nomad operator root keyring rotate`]: /nomad/commands/operator/root/keyring-rotate
[`root_key_gc_interval`]: /nomad/docs/configuration/server#root_key_gc_interval
diff --git a/website/content/docs/manage/migrate-workloads.mdx b/website/content/docs/manage/migrate-workloads.mdx
new file mode 100644
index 000000000..041595a6e
--- /dev/null
+++ b/website/content/docs/manage/migrate-workloads.mdx
@@ -0,0 +1,361 @@
+---
+layout: docs
+page_title: Migrate workloads
+description: |-
+ Configure jobs to allow Nomad to migrate workloads during events like node
+ drains. Discover how to customize migration configuration for your
+ applications.
+---
+
+# Migrate workloads
+
+Migrating workloads and decommissioning nodes are a normal part of cluster
+operations for a variety of reasons: server maintenance, operating system
+upgrades, etc. Nomad offers a number of parameters for controlling how running
+jobs are migrated off of draining nodes.
+
+## Define how your job is migrated
+
+In Nomad 0.8, a [`migrate`][migrate] stanza was added to jobs to allow control
+over how allocations for a job are migrated off of a draining node. Below is an
+example job that runs a web service and has a Consul health check:
+
+```hcl
+job "webapp" {
+ datacenters = ["dc1"]
+
+ migrate {
+ max_parallel = 2
+ health_check = "checks"
+ min_healthy_time = "15s"
+ healthy_deadline = "5m"
+ }
+
+ group "webapp" {
+ count = 9
+
+ network {
+ port "http" {
+ to = 5678
+ }
+ }
+
+ task "webapp" {
+ driver = "docker"
+ config {
+ image = "hashicorp/http-echo:0.2.3"
+ args = ["-text", "ok"]
+ ports = ["http"]
+ }
+
+ service {
+ name = "webapp"
+ port = "http"
+ check {
+ name = "http-ok"
+ type = "http"
+ path = "/"
+ interval = "10s"
+ timeout = "2s"
+ }
+ }
+ }
+ }
+}
+```
+
+The above `migrate` stanza ensures only 2 allocations are stopped at a time to
+migrate during node drains. Even if multiple nodes running allocations for this
+job were draining at the same time, only 2 allocations would be migrated at a
+time.
+
+When the job is run it may be placed on multiple nodes. In the following
+example the 9 `webapp` allocations are spread across 2 nodes:
+
+```shell-session
+$ nomad run webapp.nomad.hcl
+==> Monitoring evaluation "5129bc74"
+ Evaluation triggered by job "webapp"
+ Allocation "5b4d6db5" created: node "46f1c6c4", group "webapp"
+ Allocation "670a715f" created: node "f7476465", group "webapp"
+ Allocation "78b6b393" created: node "46f1c6c4", group "webapp"
+ Allocation "85743ff5" created: node "f7476465", group "webapp"
+ Allocation "edf71a5d" created: node "f7476465", group "webapp"
+ Allocation "56f770c0" created: node "46f1c6c4", group "webapp"
+ Allocation "9a51a484" created: node "46f1c6c4", group "webapp"
+ Allocation "f6f6e64c" created: node "f7476465", group "webapp"
+ Allocation "fefe81d0" created: node "f7476465", group "webapp"
+ Evaluation status changed: "pending" -> "complete"
+==> Evaluation "5129bc74" finished with status "complete"
+```
+
+If one those nodes needed to be decommissioned, perhaps because of a hardware
+issue, then an operator would issue node drain to migrate the allocations off:
+
+```shell-session
+$ nomad node drain -enable -yes 46f1
+2018-04-11T23:41:56Z: Ctrl-C to stop monitoring: will not cancel the node drain
+2018-04-11T23:41:56Z: Node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" drain strategy set
+2018-04-11T23:41:57Z: Alloc "5b4d6db5-3fcb-eb7d-0415-23eefcd78b6a" marked for migration
+2018-04-11T23:41:57Z: Alloc "56f770c0-f8aa-4565-086d-01faa977f82d" marked for migration
+2018-04-11T23:41:57Z: Alloc "56f770c0-f8aa-4565-086d-01faa977f82d" draining
+2018-04-11T23:41:57Z: Alloc "5b4d6db5-3fcb-eb7d-0415-23eefcd78b6a" draining
+2018-04-11T23:42:03Z: Alloc "56f770c0-f8aa-4565-086d-01faa977f82d" status running -> complete
+2018-04-11T23:42:03Z: Alloc "5b4d6db5-3fcb-eb7d-0415-23eefcd78b6a" status running -> complete
+2018-04-11T23:42:22Z: Alloc "78b6b393-d29c-d8f8-e8e8-28931c0013ee" marked for migration
+2018-04-11T23:42:22Z: Alloc "78b6b393-d29c-d8f8-e8e8-28931c0013ee" draining
+2018-04-11T23:42:27Z: Alloc "78b6b393-d29c-d8f8-e8e8-28931c0013ee" status running -> complete
+2018-04-11T23:42:29Z: Alloc "9a51a484-8c43-aa4e-d60a-46cfd1450780" marked for migration
+2018-04-11T23:42:29Z: Alloc "9a51a484-8c43-aa4e-d60a-46cfd1450780" draining
+2018-04-11T23:42:29Z: Node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" has marked all allocations for migration
+2018-04-11T23:42:34Z: Alloc "9a51a484-8c43-aa4e-d60a-46cfd1450780" status running -> complete
+2018-04-11T23:42:34Z: All allocations on node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" have stopped.
+```
+
+There are a couple of important events to notice in the output. First, only two
+allocations are migrated initially:
+
+```plaintext
+2018-04-11T23:41:57Z: Alloc "5b4d6db5-3fcb-eb7d-0415-23eefcd78b6a" marked for migration
+2018-04-11T23:41:57Z: Alloc "56f770c0-f8aa-4565-086d-01faa977f82d" marked for migration
+```
+
+This is because `max_parallel = 2` in the job specification. The next
+allocation on the draining node waits to be migrated:
+
+```plaintext
+2018-04-11T23:42:22Z: Alloc "78b6b393-d29c-d8f8-e8e8-28931c0013ee" marked for migration
+```
+
+Note that this occurs 25 seconds after the initial migrations. The 25 second
+delay is because a replacement allocation took 10 seconds to become healthy and
+then the `min_healthy_time = "15s"` meant node draining waited an additional 15
+seconds. If the replacement allocation had failed within that time the node
+drain would not have continued until a replacement could be successfully made.
+
+### Verify drained node's scheduling eligibility
+
+Now that the example drain has finished you can inspect the state of the drained
+node:
+
+```shell-session
+$ nomad node status
+ID DC Name Class Drain Eligibility Status
+f7476465 dc1 nomad-1 false eligible ready
+96b52ad8 dc1 nomad-2 false eligible ready
+46f1c6c4 dc1 nomad-3 false ineligible ready
+```
+
+While node `46f1c6c4` has `Drain = false`, notice that its `Eligibility = ineligible`. Node scheduling eligibility is a new field in Nomad 0.8. When a
+node is ineligible for scheduling the scheduler will not consider it for new
+placements.
+
+While draining, a node will always be ineligible for scheduling. Once draining
+completes it will remain ineligible to prevent refilling a newly drained node.
+
+However, by default canceling a drain with the `-disable` option will reset a
+node to be eligible for scheduling. To cancel a drain and preserving the node's
+ineligible status use the `-keep-ineligible` option.
+
+Scheduling eligibility can be toggled independently of node drains by using the
+[`nomad node eligibility`][eligibility] command:
+
+```shell-session
+$ nomad node eligibility -disable 46f1
+Node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" scheduling eligibility set: ineligible for scheduling
+```
+
+### Use a drain deadline to force completion
+
+Sometimes a drain is unable to proceed and complete normally. This could be
+caused by not enough capacity existing in the cluster to replace the drained
+allocations or by replacement allocations failing to start successfully in a
+timely fashion.
+
+Operators may specify a deadline when enabling a node drain to prevent drains
+from not finishing. Once the deadline is reached, all remaining allocations on
+the node are stopped regardless of `migrate` stanza parameters.
+
+The default deadline is 1 hour and may be changed with the
+[`-deadline`][deadline] command line option. The [`-force`][force] option is an
+instant deadline: all allocations are immediately stopped. The
+[`-no-deadline`][no-deadline] option disables the deadline so a drain may
+continue indefinitely.
+
+Like all other drain parameters, a drain's deadline can be updated by making
+subsequent `nomad node drain ...` calls with updated values.
+
+## Plan a drain strategy for batch and system jobs
+
+So far you have only seen how draining works with service jobs. Both batch and
+system jobs are have different behaviors during node drains.
+
+### Drain batch jobs
+
+Node drains only migrate batch jobs once the drain's deadline has been reached.
+For node drains without a deadline the drain will not complete until all batch
+jobs on the node have completed (or failed).
+
+The goal of this behavior is to avoid losing progress a batch job has made by
+forcing it to exit early.
+
+### Keep system jobs running
+
+Node drains only stop system jobs once all other allocations have exited. This
+way if a node is running a log shipping daemon or metrics collector as a system
+job, it will continue to run as long as there are other allocations running.
+
+The [`-ignore-system`][ignore-system] option leaves system jobs running even
+after all other allocations have exited. This is useful when system jobs are
+used to monitor Nomad or the node itself.
+
+## Drain multiple nodes
+
+A common operation is to decommission an entire class of nodes at once. Prior
+to Nomad 0.7 this was a problematic operation as the first node to begin
+draining may migrate all of their allocations to the next node about to be
+drained. In pathological cases this could repeat on each node to be drained and
+cause allocations to be rescheduled repeatedly.
+
+As of Nomad 0.8 an operator can avoid this churn by marking nodes ineligible
+for scheduling before draining them using the [`nomad node eligibility`][eligibility] command.
+
+Mark a node as ineligible for scheduling with the `-disable` flag.
+
+```shell-session
+$ nomad node eligibility -disable 46f1
+Node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" scheduling eligibility set: ineligible for scheduling
+```
+
+```shell-session
+$ nomad node eligibility -disable 96b5
+Node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" scheduling eligibility set: ineligible for scheduling
+```
+
+Check node status to confirm eligibility.
+
+```shell-session
+$ nomad node status
+ID DC Name Class Drain Eligibility Status
+f7476465 dc1 nomad-1 false eligible ready
+46f1c6c4 dc1 nomad-2 false ineligible ready
+96b52ad8 dc1 nomad-3 false ineligible ready
+```
+
+Now that both `nomad-2` and `nomad-3` are ineligible for scheduling, they can
+be drained without risking placing allocations on an _about-to-be-drained_
+node.
+
+Toggling scheduling eligibility can be done totally independently of draining.
+For example when an operator wants to inspect the allocations currently running
+on a node without risking new allocations being scheduled and changing the
+node's state.
+
+Make current node ineligible for scheduling.
+
+```shell-session
+$ nomad node eligibility -self -disable
+Node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" scheduling eligibility set: ineligible for scheduling
+```
+
+Make current node eligible for scheduling again with the `-enable` flag.
+
+```shell-session
+$ nomad node eligibility -self -enable
+Node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" scheduling eligibility set: eligible for scheduling
+```
+
+### Example: migrating datacenters
+
+A more complete example of draining multiple nodes would be when migrating from
+an old datacenter (`dc1`) to a new datacenter (`dc2`):
+
+```shell-session
+$ nomad node status -allocs
+ID DC Name Class Drain Eligibility Status Running Allocs
+f7476465 dc1 nomad-1 false eligible ready 4
+46f1c6c4 dc1 nomad-2 false eligible ready 1
+96b52ad8 dc1 nomad-3 false eligible ready 4
+168bdd03 dc2 nomad-4 false eligible ready 0
+9ccb3306 dc2 nomad-5 false eligible ready 0
+7a7f9a37 dc2 nomad-6 false eligible ready 0
+```
+
+Before migrating ensure that all jobs in `dc1` have `datacenters = ["dc1", "dc2"]`. Then before draining, mark all nodes in `dc1` as ineligible for
+scheduling.
+
+Shell scripting can help automate manipulating multiple nodes at once.
+
+```shell-session
+$ nomad node status | awk '{ print $2 " " $1 }' | grep ^dc1 | awk '{ system("nomad node eligibility -disable "$2) }'
+Node "f7476465-4d6e-c0de-26d0-e383c49be941" scheduling eligibility set: ineligible for scheduling
+Node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" scheduling eligibility set: ineligible for scheduling
+Node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" scheduling eligibility set: ineligible for scheduling
+```
+
+Check status to confirm ineligibility.
+
+```shell-session
+$ nomad node status
+ID DC Name Class Drain Eligibility Status
+f7476465 dc1 nomad-1 false ineligible ready
+46f1c6c4 dc1 nomad-2 false ineligible ready
+96b52ad8 dc1 nomad-3 false ineligible ready
+168bdd03 dc2 nomad-4 false eligible ready
+9ccb3306 dc2 nomad-5 false eligible ready
+7a7f9a37 dc2 nomad-6 false eligible ready
+```
+
+Then drain each node in `dc1`.
+
+```shell-session
+$ nomad node drain -enable -yes -detach f7476465
+Node "f7476465-4d6e-c0de-26d0-e383c49be941" drain strategy set
+```
+
+Pass the ID for each node with the flags ``-enable -yes -detach` to initiate the drain.
+
+```shell-session
+$ nomad node drain -enable -yes -detach 46f1c6c4
+Node "46f1c6c4-a0e5-21f6-fd5c-d76c3d84e806" drain strategy set
+```
+
+For this example, only monitor the final node that is draining. Watching `nomad node status -allocs`
+is also a good way to monitor the status of drains.
+
+```shell-session
+$ nomad node drain -enable -yes 9ccb3306
+2018-04-12T22:08:00Z: Ctrl-C to stop monitoring: will not cancel the node drain
+2018-04-12T22:08:00Z: Node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" drain strategy set
+2018-04-12T22:08:15Z: Alloc "392ee2ec-d517-c170-e7b1-d93b2d44642c" marked for migration
+2018-04-12T22:08:16Z: Alloc "392ee2ec-d517-c170-e7b1-d93b2d44642c" draining
+2018-04-12T22:08:17Z: Alloc "6a833b3b-c062-1f5e-8dc2-8b6af18a5b94" marked for migration
+2018-04-12T22:08:17Z: Alloc "6a833b3b-c062-1f5e-8dc2-8b6af18a5b94" draining
+2018-04-12T22:08:21Z: Alloc "392ee2ec-d517-c170-e7b1-d93b2d44642c" status running -> complete
+2018-04-12T22:08:22Z: Alloc "6a833b3b-c062-1f5e-8dc2-8b6af18a5b94" status running -> complete
+2018-04-12T22:09:08Z: Alloc "d572d7a3-024b-fcb7-128b-1932a49c8d79" marked for migration
+2018-04-12T22:09:09Z: Alloc "d572d7a3-024b-fcb7-128b-1932a49c8d79" draining
+2018-04-12T22:09:14Z: Alloc "d572d7a3-024b-fcb7-128b-1932a49c8d79" status running -> complete
+2018-04-12T22:09:33Z: Alloc "f3f24277-4435-56a3-7ee1-1b1eff5e3aa1" marked for migration
+2018-04-12T22:09:33Z: Alloc "f3f24277-4435-56a3-7ee1-1b1eff5e3aa1" draining
+2018-04-12T22:09:33Z: Node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" has marked all allocations for migration
+2018-04-12T22:09:39Z: Alloc "f3f24277-4435-56a3-7ee1-1b1eff5e3aa1" status running -> complete
+2018-04-12T22:09:39Z: All allocations on node "96b52ad8-e9ad-1084-c14f-0e11f10772e4" have stopped.
+```
+
+Note that there was a 15 second delay between node `96b52ad8` starting to drain
+and having its first allocation migrated. The delay was due to 2 other
+allocations for the same job already being migrated from the other nodes. Once
+at least 8 out of the 9 allocations are running for the job, another allocation
+could begin draining.
+
+The final node drain command did not exit until 6 seconds after the `drain complete` message because the command line tool blocks until all allocations on
+the node have stopped. This allows operators to script shutting down a node
+once a drain command exits and know all services have already exited.
+
+[deadline]: /nomad/commands/node/drain#deadline
+[eligibility]: /nomad/commands/node/eligibility
+[force]: /nomad/commands/node/drain#force
+[ignore-system]: /nomad/commands/node/drain#ignore-system
+[migrate]: /nomad/docs/job-specification/migrate
+[no-deadline]: /nomad/commands/node/drain#no-deadline
diff --git a/website/content/docs/manage/outage-recovery.mdx b/website/content/docs/manage/outage-recovery.mdx
new file mode 100644
index 000000000..8f537382b
--- /dev/null
+++ b/website/content/docs/manage/outage-recovery.mdx
@@ -0,0 +1,252 @@
+---
+layout: docs
+page_title: Recover from an outage
+description: |-
+ Discover techniques and steps to recover from a single node failure,
+ multi-node failure, or a complete loss of quorum.
+---
+
+# Recover from an outage
+
+Don't panic. This is a critical first step.
+
+Depending on your [deployment configuration], it may take only a single server
+failure for cluster unavailability. Recovery requires an operator to intervene,
+but the process is straightforward.
+
+~> This guide is for recovery from a Nomad outage due to a majority of server
+nodes in a datacenter being lost. If you are looking to add or remove servers,
+consult the [bootstrapping guide].
+
+## Failure of a single server cluster
+
+If you had only a single server and it has failed, try to restore operation by
+restarting it. A single server configuration requires the
+[`-bootstrap-expect=1`] flag. If the server cannot be recovered, you need to
+bring up a new server. Consult the [bootstrapping guide] for more detail.
+
+In the case of an unrecoverable server failure in a single server cluster, data
+loss is inevitable since data was not replicated to any other servers. This is
+why a single server deploy is **never** recommended.
+
+## Failure of a server in a multi-server cluster
+
+If you think the failed server is recoverable, the easiest option is to bring it
+back online and have it rejoin the cluster with the same IP address. This will
+return the cluster to a fully healthy state. Similarly, even if you need to
+rebuild a new Nomad server to replace the failed node, you may wish to do that
+immediately. Keep in mind that the rebuilt server needs to have the same IP
+address as the failed server. Again, once this server is online and has
+rejoined, the cluster will return to a fully healthy state.
+
+Both of these strategies involve a potentially lengthy time to reboot or rebuild
+a failed server. If this is impractical or if building a new server with the
+same IP isn't an option, you need to remove the failed server. Usually, you can
+issue a [`nomad server force-leave`] command to remove the failed server if it
+is still a member of the cluster.
+
+
+
+ Your raft cluster will need to have a quorum of nodes available to
+perform any online modifications to the Raft peer information. Membership
+changes are written to the Raft log, and all Raft log writes require quorum.
+If this is impossible, continue to **Failure of Multiple Servers in a
+Multi-Server Cluster**
+
+
+
+If, for some reason, the Raft configuration continues to show any stale members,
+you can use the [`nomad operator raft remove-peer`] command to remove the stale
+peer server on the fly with no downtime.
+
+Once you have made the membership changes necessary, you should verify the
+current Raft state with the [`nomad operator raft list-peers`] command:
+
+```shell-session
+$ nomad operator raft list-peers
+Node ID Address State Voter
+nomad-server01.global 10.10.11.5:4647 10.10.11.5:4647 follower true
+nomad-server02.global 10.10.11.6:4647 10.10.11.6:4647 leader true
+nomad-server03.global 10.10.11.7:4647 10.10.11.7:4647 follower true
+```
+
+## Failure of multiple servers in a multi-server cluster
+
+In the event that multiple servers are lost, causing a loss of quorum and a
+complete outage, partial recovery is possible using data on the remaining
+servers in the cluster. There may be data loss in this situation because
+multiple servers were lost, so information about what's committed could be
+incomplete. The recovery process implicitly commits all outstanding Raft log
+entries, so it's also possible to commit data that was uncommitted before the
+failure.
+
+The [section below][] contains the details of the recovery procedure. You will
+include the remaining servers in the `raft/peers.json` recovery file. The
+cluster should be able to elect a leader once the remaining servers are all
+restarted with an identical `raft/peers.json` configuration.
+
+Any new servers you introduce later can be fresh with totally clean data
+directories and joined using Nomad's `server join` command.
+
+In extreme cases, it should be possible to recover with only a single remaining
+server by starting that single server with itself as the only peer in the
+`raft/peers.json` recovery file.
+
+The `raft/peers.json` recovery file is final, and a snapshot is taken after it
+is ingested, so you are guaranteed to start with your recovered configuration.
+This does implicitly commit all Raft log entries, so should only be used to
+recover from an outage, but it should allow recovery from any situation where
+there's some cluster data available.
+
+## Manual recovery using peers.json
+
+To begin, stop all remaining servers. You can attempt a graceful leave, but it
+will not work in most cases. Do not worry if the leave exits with an error. The
+cluster is in an unhealthy state, so this is expected.
+
+The `peers.json` file is not present by default and is only used when performing
+recovery. This file will be deleted after Nomad starts and ingests this file.
+
+Nomad automatically creates a `raft/peers.info` file on startup to mark that it
+is on the current version of Raft. Do not remove the `raft/peers.info`
+file at any time.
+
+Using `raft/peers.json` for recovery can cause uncommitted Raft log entries to
+be implicitly committed, so this should only be used after an outage where no
+other option is available to recover a lost server. Make sure you don't have any
+automated processes that will put the peers file in place on a periodic basis.
+
+The next step is to go to the [`-data-dir`][] of each Nomad server. Inside that
+directory, there will be a `raft/` sub-directory. Create a `raft/peers.json`
+file. Its contents will depend on the raft protocol version of your cluster.
+
+### Raft protocol 3 peers.json specification
+
+```json
+[
+ {
+ "id": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
+ "address": "10.1.0.1:4647",
+ "non_voter": false
+ },
+ {
+ "id": "8b6dda82-3103-11e7-93ae-92361f002671",
+ "address": "10.1.0.2:4647",
+ "non_voter": false
+ },
+ {
+ "id": "97e17742-3103-11e7-93ae-92361f002671",
+ "address": "10.1.0.3:4647",
+ "non_voter": false
+ }
+]
+```
+
+- `id` `(string: **required**)` - Specifies the `node ID` of the server. This
+ can be found in the logs when the server starts up, and it can also be found
+ inside the `node-id` file in the server's data directory.
+
+- `address` `(string: **required**)` - Specifies the IP and port of the server
+ in `ip:port` format. The port is the server's RPC port used for cluster
+ communications, typically 4647.
+
+- `non_voter` `(bool: _false_)` - This controls whether the server is a
+ non-voter, which is used in some advanced [Autopilot] configurations. If
+ omitted, it will default to false, which is typical for most clusters.
+
+You can use this `jq` filter to create a `peers.json` file with the list of `alive` servers. Check the generated output and make any necessary changes.
+
+```shell
+$ nomad server members -json | jq '[ .[] | select(.Status == "alive") | {id: .Tags.id, address: "\(.Tags.rpc_addr):\(.Tags.port)", non_voter: false} ]'
+```
+
+### Raft protocol 2 peers.json specification
+
+```json
+["10.0.1.8:4647", "10.0.1.6:4647", "10.0.1.7:4647"]
+```
+
+Raft protocol version 2 peers.json files contain a list of IP:Port addresses for
+each server. Note that the port should refer to the RPC port and not the HTTP
+API port.
+
+### Deploy peers.json to all server nodes
+
+Create entries for all remaining servers. You must confirm that servers you do
+not include here have indeed failed and will not later rejoin the cluster.
+
+Deploy this file is the same across all remaining server nodes.
+
+### Verify keyring on server nodes
+
+
+
+Prior to Nomad 1.9.0, [key material][Key material] was never stored in Raft. This meant that
+the `nomad agent snapshot save` command and snapshot agent did not save Nomad's
+keyring. If you are using versions prior to Nomad 1.9.0, you should make sure you have backed up the keyring of at least one
+server.
+
+
+
+Go to the [`-data-dir`][] of each Nomad server. Inside that directory, there
+will be a `keystore/` sub-directory with `.nks.json` files. Ensure that these
+files exist on at least one server before continuing.
+
+### Restart cluster nodes
+
+At this point, you can restart all the remaining servers. Log lines will be
+emitted as the servers ingest the recovery file:
+
+```plaintext
+...
+2016/08/16 14:39:20 [INFO] nomad: found peers.json file, recovering Raft configuration...
+2016/08/16 14:39:20 [INFO] nomad.fsm: snapshot created in 12.484µs
+2016/08/16 14:39:20 [INFO] snapshot: Creating new snapshot at /tmp/peers/raft/snapshots/2-5-1471383560779.tmp
+2016/08/16 14:39:20 [INFO] nomad: deleted peers.json file after successful recovery
+2016/08/16 14:39:20 [INFO] raft: Restored from snapshot 2-5-1471383560779
+2016/08/16 14:39:20 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:10.212.15.121:4647 Address:10.212.15.121:4647}]
+...
+```
+
+If any servers managed to perform a graceful leave, you may need to have them
+rejoin the cluster using the [`server join`] command:
+
+```shell-session
+$ nomad server join
+Successfully joined cluster by contacting 1 nodes.
+```
+
+It should be noted that any existing member can be used to rejoin the cluster as
+the gossip protocol will take care of discovering the server nodes.
+
+At this point, the cluster should be in an operable state again. One of the
+nodes should claim leadership and emit a log like:
+
+```plaintext
+[INFO] nomad: cluster leadership acquired
+```
+
+You can use the [`nomad operator raft list-peers`] command to inspect the Raft
+configuration:
+
+```shell-session
+$ nomad operator raft list-peers
+Node ID Address State Voter
+nomad-server01.global 10.10.11.5:4647 10.10.11.5:4647 follower true
+nomad-server02.global 10.10.11.6:4647 10.10.11.6:4647 leader true
+nomad-server03.global 10.10.11.7:4647 10.10.11.7:4647 follower true
+```
+
+[`-bootstrap-expect=1`]: /nomad/docs/configuration/server#bootstrap_expect
+[`-data-dir`]: /nomad/docs/configuration#data_dir
+[`nomad operator raft list-peers`]: /nomad/commands/operator/raft/list-peers
+[`nomad operator raft remove-peer`]: /nomad/commands/operator/raft/remove-peer
+[`nomad server force-leave`]: /nomad/commands/server/force-leave
+[`nomad server force-leave`]: /nomad/commands/server/force-leave
+[`server join`]: /nomad/commands/server/join
+[autopilot]: /nomad/docs/manage/autopilot
+[bootstrapping guide]: /nomad/docs/deploy/clusters/connect-nodes
+[deployment configuration]: /nomad/docs/architecture/cluster/consensus#deployment_table
+[section below]: #manual-recovery-using-peers-json
+[Key material]: /nomad/docs/manage/key-management
+[restore the keyring]: /nomad/docs/manage/key-management#restoring-the-keyring-from-backup
diff --git a/website/content/docs/monitor/cluster-topology.mdx b/website/content/docs/monitor/cluster-topology.mdx
new file mode 100644
index 000000000..4aedceea0
--- /dev/null
+++ b/website/content/docs/monitor/cluster-topology.mdx
@@ -0,0 +1,123 @@
+---
+layout: docs
+page_title: Cluster state topology
+description: |-
+ Discover and use the topology visualization of the Nomad web UI to observe
+ clients and active workloads on your cluster.
+---
+
+# Cluster state topology
+
+As a Nomad cluster grows, the exact state of allocations and clients can become a mystery. For the most part this is a good thing: it means Nomad is quietly scheduling workloads without any need for intervention. However, as an operator, it is reasonable to still want to know what is going on within your cluster.
+
+The topology visualization is a single view of an entire cluster. It helps you perform preventative maintenance and it can help you understand your cluster's particular behaviors.
+
+## Prerequisites
+
+This tutorial assumes basic familiarity with Nomad. You must have access to an existing cluster that is running one or more jobs.
+
+Here is what you will need for this guide:
+
+- An active Nomad >=1.0.0 cluster
+- Access to the cluster's web UI
+- Read permissions to one or more namespaces
+
+## Navigate to the topology visualization
+
+The global left-hand navigation of the web UI has a Topology link under the cluster section. This link will take you to the topology visualization.
+
+[![The left-hand Nomad UI navigation with the topology link highlighted][topo-viz-link]][topo-viz-link]
+
+## The elements of the visualization
+
+The left-hand information panel contains aggregate cluster statistics. This includes the sum total of memory and CPU (in MHz) available to Nomad. The percentages of memory and CPU tell how much of each resource has been reserved—not how much is currently utilized. For instance, if a Docker container is currently utilizing 30MiB of memory but the task declared the need for 500MiB in the job spec, then the topology visualization will count this allocation as 500MiB.
+
+These aggregate metrics are meant to give a rough sense of scale and can answer immediate forecasting questions. If your cluster is currently at 80% capacity of a total 200GiB of memory and you know your services will only grow in the next year, then you can conclude that the capacity of the cluster will also have to grow.
+
+Be careful not to assume there is room for your allocation just because the aggregate remaining resources are less than what your job requires. Since resources are aggregated but allocations must be placed on a single client, it's possible that no client has room for your allocation. If there is 1500MHz of CPU available across a cluster but only 500MHz available per client, then a task that needs 600MHz of CPU cannot be placed.
+
+[![The info panel of the topology visualization with aggregate cluster statistics included][cluster-panel]][cluster-panel]
+
+The main visualization organizes all of your datacenters and clients and brings focus to your allocations.
+
+The outermost section represents a datacenter (1). Each section is labeled by the datacenter name, capacity, and status. Clients are rendered within their respective datacenter. Clients will also be labeled by their name, capacity, and status (2). This also includes icon indicators of scheduling eligibility and drain state (3).
+
+[![The primary cluster view of the topology visualization. Annotation 1: the datacenter section. Annotation 2: the client name and details. Annotation 3: a lock icon indicator for scheduling ineligibility. Annotation 4: two rows of rectangles representing allocations.][cluster-view]][cluster-view]
+
+Clients across your entire fleet are sized vertically based on their capacity. Clients with more total capacity are taller. This makes scanning a cluster easier.
+
+Within each client container are two rows; one for each primary scheduling unit (CPU and memory). Each row will include each allocation on the client scaled proportionally to the amount of resources reserved for it (4). An allocation for a task group that requires 8GiB of memory on a client that has 32GiB total will occupy 25% of a client row.
+
+## Interact with the visualization
+
+The topology visualization is designed to presennt as much information as possible in a single view. More information can be expanded by hovering or clicking on specific elements.
+
+Hovering over allocations will open a tooltip that gives quick details including the specific allocation reservation requirements and the job the allocation belongs to.
+
+[![The allocation tooltip showing allocation information for the allocation under the cursor][allocation-tooltip]][allocation-tooltip]
+
+Clicking an allocation will select it and swap out the cluster aggregate statistics in the information panel with allocation information. This includes links to the allocation, the job the allocation belongs to, the client the allocation is running on, and the current resource utilization over time.
+
+[![The info panel of the topology visualization with allocation information included][alloc-info-panel]][alloc-info-panel]
+
+In addition to the information shown in the panel, when an allocation is selected, associations among all allocations for the same task group and job will be drawn. This helps convey the distribution of a single task group across a cluster.
+
+[![Lines drawn between allocations to show that they all belong to the same job and task group][alloc-associations]][alloc-associations]
+
+For large clusters, the topology visualization will hide the client labels. When this is the case, clicking a client will expand client details in the information panel.
+
+[![The info panel of the topology visualization with client information included][client-panel]][client-panel]
+
+## Effective use of the topology visualization
+
+The topology visualization is intended to be an open-ended exploration tool. Here are a few example explorations that the visualization is particularly well-suited for.
+
+### Identify excessive client provisioning
+
+Sometimes clients are provisioned separately from application sizing and placement. This can lead to a drift between the expected client requirements and the actual requirements. Clients with no allocations still cost money.
+
+This can be quickly detected with the topology visualization. Empty clients are highlighted in red and labeled as empty.
+
+[![An empty client in the cluster view emphasized in red][empty-clients]][empty-clients]
+
+~> Is this a problem you have? Consider using [horizontal cluster autoscaling](https://github.com/hashicorp/nomad-autoscaler).
+
+### Spot potentially hazardous or flaky allocation distributions
+
+Nomad will automatically place allocations based on the requirements and constraints declared in the job spec. It is not uncommon for jobs to have missing constraints due to human error or unknown caveats. This class of error will often make itself known when the task starts, but sometimes the error is invisible and only surfaces through a peculiar error rate.
+
+For instance, imagine a service Service A that has five allocations. Four are in datacenter West and one is in datacenter East. Service A must talk to Service B, but due to networking rules, they cannot communicate across the datacenter boundary. If Service B is in datacenter West, then 80% of Service A traffic (assuming a uniform distribution) will work as intended while the remaining 20% will error. Or worse than error: silently behave incorrectly.
+
+This is easily remedied with a datacenter constraint in the job spec, but the problem must first be identified. Since the topology visualization will associate all allocations for Service A, this can be quickly spotted.
+
+[![Allocations associated across datacenters][alloc-associations-across-dcs]][alloc-associations-across-dcs]
+
+### Find noisy neighbor risks
+
+By default, tasks in Nomad have soft CPU limits. This lets tasks occasionally spike over their allotted CPU while still allowing for efficient bin-packing of allocations on a single client.
+
+It is possible for many allocations on a single client to exceed their CPU soft-limit—or for one allocation to greatly exceed it—starving other allocations of CPU. This can cause degraded performance and anomalous errors to arise from untested race conditions or timeouts. In this case, the problematic allocation is only problematic due to the external circumstances of the client it was scheduled on.
+
+The topology visualization makes it very clear when an important allocation is scheduled alongside many other allocations on a densely packed client. This alone doesn't mean there is a noisy neighbor problem, but it might be enough to defensively modify the job spec. Adding more CPU headroom or constraints can help stabilize the service.
+
+[![A single client in the topology visualization with many allocations][client-with-many-allocs]][client-with-many-allocs]
+
+## Next steps
+
+The topology visualization is a useful tool for learning to use Nomad and for understanding your cluster at a moment in time. It does _not_ show historical allocation reservation information.
+
+To get deeper utilization and historical data, you will need to set up a monitoring stack using Nomad's telemetry data. The topology visualization may inform your own custom dashboards as you invest in setting up operations tooling for your specific needs.
+
+1. [Use Prometheus to monitor Nomad metrics](/nomad/tutorials/manage-clusters/prometheus-metrics)
+2. [Review the full set of metrics Nomad exports](/nomad/docs/reference/metrics)
+
+[topo-viz-link]: /img/monitor/topo-viz/topo-viz-link.png
+[cluster-panel]: /img/monitor/topo-viz/cluster-panel.png
+[cluster-view]: /img/monitor/topo-viz/cluster-view.png
+[allocation-tooltip]: /img/monitor/topo-viz/allocation-tooltip.png
+[alloc-info-panel]: /img/monitor/topo-viz/allocation-panel.png
+[alloc-associations]: /img/monitor/topo-viz/allocation-associations.png
+[client-panel]: /img/monitor/topo-viz/client-panel.png
+[empty-clients]: /img/monitor/topo-viz/empty-clients.png
+[alloc-associations-across-dcs]: /img/monitor/topo-viz/alloc-associations-across-dcs.png
+[client-with-many-allocs]: /img/monitor/topo-viz/client-with-many-allocs.png
diff --git a/website/content/docs/monitor/event-stream.mdx b/website/content/docs/monitor/event-stream.mdx
new file mode 100644
index 000000000..28933c387
--- /dev/null
+++ b/website/content/docs/monitor/event-stream.mdx
@@ -0,0 +1,99 @@
+---
+layout: docs
+page_title: Monitor Nomad's event stream
+description: |-
+ Subscribe to Nomad's event stream to observe activities in your Nomad cluster.
+---
+
+# Monitor Nomad's event stream
+
+The event stream provides a way to subscribe to Job, Allocation, Evaluation,
+Deployment, and Node changes in near real time. Whenever a state change occurs in
+Nomad via Nomad's Finite State Machine (FSM) a set of events for each updated
+object are created.
+
+Currently, Nomad users must take a number of steps to build a mental model of
+what recent actions have occurred in their cluster. Individual log statements
+often provide a small fragment of information related to a unit of work within
+Nomad. Logs can also be interlaced with other unrelated logs, complicating the
+process of understanding and building context around the issue a user is trying
+to identify. Log statements may also be too specific to a smaller piece of work
+that took place and the larger context around the log or action is missed or
+hard to infer.
+
+Another pain point is that the value of log statements depend on how they are
+managed by an organization. Larger teams with external log aggregators find
+more value out of standard logging than a smaller team who manually scans
+through files to debug issues. Today, an operator might combine the information
+returned by `/v1/nodes`, `/v1/evaluations`, `/v1/allocations`, and then
+`/v1/nodes` again using the Nomad API to try to figure out what exactly
+happened.
+
+This complex workflow has led to a lack of prescriptive guidance when working
+with customers and users on how to best monitor and debug their Nomad clusters.
+Third party tools such as `nomad-firehose` have also emerged to try to solve
+the issue by continuously scraping endpoints to react to changes within Nomad.
+
+The event stream provides a first-class solution to receiving a stream of events
+in Nomad and provides users a much better understanding of how their cluster is
+operating out of the box.
+
+## Access the event stream
+
+The event stream currently exists in the API, so users can access the new event
+stream endpoint from the below command.
+
+```shell-session
+$ curl -s -v -N http://127.0.0.1:4646/v1/event/stream
+```
+
+## Subscribe to all or certain events
+
+Filter on certain topics by specifying a filter key. This example listens
+for Node events only relating to that particular node's ID. It also listens
+to all Deployment events and Job events related to a job named web.
+
+```shell-session
+$ curl -s -v -N \
+ --data-urlencode "topic=Node:ccc4ce56-7f0a-4124-b8b1-a4015aa82c40" \
+ --data-urlencode "topic=Deployment" \
+ --data-urlencode "topic=Job:web" \
+ http://127.0.0.1:4646/v1/event/stream
+```
+
+## What is in an event?
+
+Each event contains a `Topic`, `Type`, `Key`, `Namespace`, `FilterKeys`, `Index`,
+and `Payload`. The contents of the Payload depend on the event Topic. An event
+for the Node Topic contains a Node object. For example:
+
+```json
+{
+ "Topic": "Node",
+ "Type": "NodeRegistration",
+ "Key": "afb9c810-d701-875a-b2a6-f2631d7c2f60",
+ "Namespace": "",
+ "FilterKeys": null,
+ "Index": 7,
+ "Payload": {
+ "Node": {
+ "//": "...entire node object"
+ }
+ }
+}
+```
+
+## Develop using event stream
+
+Here are some patterns of how you might use Nomad's event stream.
+
+- Subscribe to all or subset of cluster events
+
+- Add an additional tool in your regular debugging & monitoring workflow as an
+ SRE to gauge the qualitative state and health of your cluster.
+
+- Trace through a specific job deployment as it upgrades from an evaluation to a
+ deployment and uncover any blockers in the path for the scheduler.
+
+- Build a slack bot integration to send deploy notifications.
+ - https://github.com/drewbailey/nomad-deploy-notifier
diff --git a/website/content/docs/operations/monitoring-nomad.mdx b/website/content/docs/monitor/index.mdx
similarity index 96%
rename from website/content/docs/operations/monitoring-nomad.mdx
rename to website/content/docs/monitor/index.mdx
index 41a8f01bf..5e2352103 100644
--- a/website/content/docs/operations/monitoring-nomad.mdx
+++ b/website/content/docs/monitor/index.mdx
@@ -291,14 +291,14 @@ latency and packet loss for the [Serf] address.
[alerting-rules]: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
[alertmanager]: https://prometheus.io/docs/alerting/alertmanager/
-[allocation-metrics]: /nomad/docs/operations/metrics-reference#allocation-metrics
+[allocation-metrics]: /nomad/docs/reference/metrics#allocation-metrics
[circonus-telem]: /nomad/docs/configuration/telemetry#circonus-apica
[collection-interval]: /nomad/docs/configuration/telemetry#collection_interval
[datadog-alerting]: https://www.datadoghq.com/blog/monitoring-101-alerting/
[datadog-telem]: /nomad/docs/configuration/telemetry#datadog
-[draining]: /nomad/tutorials/manage-clusters/node-drain
+[draining]: /nomad/docs/manage/migrate-workloads
[gh-11830]: https://github.com/hashicorp/nomad/pull/11830
-[metric-types]: /nomad/docs/operations/metrics-reference#metric-types
+[metric-types]: /nomad/docs/reference/metrics#metric-types
[metrics-api-endpoint]: /nomad/api-docs/metrics
[prometheus-telem]: /nomad/docs/configuration/telemetry#prometheus
[`plan_rejection_tracker`]: /nomad/docs/configuration/server#plan_rejection_tracker
@@ -306,8 +306,8 @@ latency and packet loss for the [Serf] address.
[statsd-exporter]: https://github.com/prometheus/statsd_exporter
[statsd-telem]: /nomad/docs/configuration/telemetry#statsd
[statsite-telem]: /nomad/docs/configuration/telemetry#statsite
-[tagged-metrics]: /nomad/docs/operations/metrics-reference#tagged-metrics
+[tagged-metrics]: /nomad/docs/reference/metrics#tagged-metrics
[telemetry-block]: /nomad/docs/configuration/telemetry
-[Consensus Protocol (Raft)]: /nomad/docs/operations/monitoring-nomad#consensus-protocol-raft
-[Job Summary Metrics]: /nomad/docs/operations/metrics-reference#job-summary-metrics
-[Scheduling]: /nomad/docs/concepts/scheduling/scheduling
+[Consensus Protocol (Raft)]: /nomad/docs/monitor#raft-consensus-protocol
+[Job Summary Metrics]: /nomad/docs/reference/metrics#job-summary-metrics
+[Scheduling]: /nomad/docs/concepts/scheduling/how-scheduling-works
diff --git a/website/content/docs/monitor/inspect-cluster.mdx b/website/content/docs/monitor/inspect-cluster.mdx
new file mode 100644
index 000000000..61d307c51
--- /dev/null
+++ b/website/content/docs/monitor/inspect-cluster.mdx
@@ -0,0 +1,172 @@
+---
+layout: docs
+page_title: Inspect the cluster
+description: |-
+ View the server and client nodes, inspect an individual server or client node,
+ list allocations, and review client events from the Nomad web UI.
+---
+
+# Inspect the cluster
+
+The Web UI can be a powerful tool for monitoring the state of the Nomad cluster
+from an operator's perspective. This includes showing all client nodes, showing
+driver health for client nodes, driver status, resource utilization, allocations
+by client node, and more.
+
+## View cluster clients
+
+From any page, the Clients List page can be accessed from the left-hand
+navigation bar. On narrow screens this navigation bar may need to be opened from
+the top-right menu button. The table lists every client in the cluster and is
+searchable, sortable, and filterable. Each client row in the table shows basic
+information, such as the Node ID, name, state, address, datacenter, and how many
+allocations are running in it.
+
+This view will also live-update as the states of client nodes change.
+
+[![Clients List][img-clients-list]][img-clients-list]
+
+## Filter the client view
+
+If your Nomad cluster has many client nodes, it can be useful to filter the list
+of all client nodes down to only those matching certain facets. The Web UI has
+three facets you can filter by:
+
+1. **Class:** The node of the client, including a dynamically generated list
+ based on the node class of each client node in the cluster.
+
+1. **State:** The state of the cluster, including Initializing, Ready, Down,
+ Ineligible, and Draining.
+
+1. **Datacenter:** The datacenter the client node is in, including a dynamically
+ generated list based on all the datacenters in the cluster.
+
+[![Clients filters][img-clients-filters]][img-clients-filters]
+
+## Inspect an individual client
+
+From the Clients List page, clicking a client node in the table will direct you
+to the Client Detail page for the client node. This page includes all
+information about the client node is live-updated to always present up-to-date
+information.
+
+[![Client Detail][img-client-detail]][img-client-detail]
+
+## Monitor resource utilization
+
+Nomad has APIs for reading point-in-time resource utilization metrics for client
+nodes. The Web UI uses these metrics to create time-series graphics for the
+current session.
+
+When viewing a client node, resource utilization will automatically start
+logging.
+
+[![Client Resource Utilization][img-client-resource-utilization]][img-client-resource-utilization]
+
+## List client allocations
+
+Allocations belong to jobs and are placed on client nodes. The Client Detail
+page will list all allocations for a client node, including completed, failed,
+and lost allocations, until they are garbage-collected.
+
+This is presented in a searchable table which can additionally be filtered to
+only preempted allocations.
+
+[![Client Allocations][img-client-allocations]][img-client-allocations]
+
+## Review client events
+
+Client nodes will also emit events on meaningful state changes, such as when the
+node becomes ready for scheduling or when a driver becomes unhealthy.
+
+[![Client Events][img-client-events]][img-client-events]
+
+## Check client driver status
+
+Task drivers are additional services running on a client node. Nomad will
+fingerprint and communicate with the task driver to determine if the driver is
+available and healthy. This information is reported through the Web UI on the
+Client Detail page.
+
+[![Client Driver Status][img-client-driver-status]][img-client-driver-status]
+
+## View client attributes
+
+In order to allow job authors to constrain the placement of their jobs, Nomad
+fingerprints the hardware of the node the client agent is running on. This is a
+deeply nested document of properties that the Web UI presents in a scannable
+way.
+
+In addition to the hardware attributes, Nomad operators can annotate a client
+node with [metadata] as part of the client configuration. This metadata is also
+presented on the Client Detail page.
+
+[![Client Attributes][img-client-attributes]][img-client-attributes]
+
+## Monitor a node drain
+
+A routine part of maintaining a Nomad cluster is draining nodes of allocations.
+This can be in preparation of performing operating system upgrades or
+decommissioning an old node in favor of a new VM.
+
+Drains are [performed from the CLI], but the status of a drain can be monitored
+from the Web UI. A client node will state if it is actively draining or
+ineligible for scheduling.
+
+Since drains can be configured in a variety of ways, the Client Detail page will
+also present the details of how the drain is performed.
+
+[![Client Drain][img-client-drain]][img-client-drain]
+
+## View cluster servers
+
+Whereas client nodes are used to run your jobs, server nodes are used to run
+Nomad and maintain availability. From any page, the Servers List page can be
+accessed from the left-hand navigation bar.
+
+The table lists every server node in your cluster. This will be a small list—
+[typically three or five].
+
+[![Servers List][img-servers-list]][img-servers-list]
+
+## Inspect an individual server
+
+Clicking a server node on the Servers List will expand the tags table for the
+server node.
+
+[![Server Detail][img-server-detail]][img-server-detail]
+
+## Secure the UI
+
+Depending on the size of your team and the details of you Nomad deployment, you
+may wish to control which features different internal users have access to. This
+includes limiting who has access to list and manage client nodes and list and
+manage server nodes. You can enforce this with Nomad's access control list
+system.
+
+By default, all features—read and write—are available to all users of the Web
+UI. Check out the [Securing the Web UI with ACLs] tutorial to learn how to prevent
+anonymous users from having write permissions as well as how to continue to use
+Web UI write features as a privileged user.
+
+## Continue your exploration
+
+Now that you have explored how to inspect the state of your cluster through the
+Nomad UI, you will next learn some considerations you should keep in mind when
+using the Nomad UI.
+
+[img-client-allocations]: /img/monitor/guide-ui-img-client-allocations.png
+[img-client-attributes]: /img/monitor/guide-ui-img-client-attributes.png
+[img-client-detail]: /img/monitor/guide-ui-img-client-detail.png
+[img-client-drain]: /img/monitor/guide-ui-img-client-drain.png
+[img-client-driver-status]: /img/monitor/guide-ui-img-client-driver-status.png
+[img-client-events]: /img/monitor/guide-ui-img-client-events.png
+[img-client-resource-utilization]: /img/monitor/guide-ui-img-client-resource-utilization.png
+[img-clients-filters]: /img/monitor/guide-ui-img-clients-filters.png
+[img-clients-list]: /img/monitor/guide-ui-img-clients-list.png
+[img-server-detail]: /img/monitor/guide-ui-img-server-detail.png
+[img-servers-list]: /img/monitor/guide-ui-img-servers-list.png
+[metadata]: /nomad/docs/configuration/client#meta
+[performed from the cli]: /nomad/docs/manage/migrate-workloads
+[securing the web ui with acls]: /nomad/tutorials/access-control
+[typically three or five]: /nomad/docs/architecture/cluster/consensus#deployment-table
diff --git a/website/content/docs/monitor/inspect-workloads.mdx b/website/content/docs/monitor/inspect-workloads.mdx
new file mode 100644
index 000000000..81408120a
--- /dev/null
+++ b/website/content/docs/monitor/inspect-workloads.mdx
@@ -0,0 +1,221 @@
+---
+layout: docs
+page_title: Inspect job workloads
+description: |-
+ Inspect jobs, allocations, and tasks in the Nomad web UI and interact
+ with these objects to perform operations like restart an allocation or
+ stop a job.
+---
+
+# Inspect job workloads
+
+The Web UI can be a powerful companion when monitoring and debugging jobs
+running in Nomad. The Web UI will list all jobs, link jobs to allocations,
+allocations to client nodes, client nodes to driver health, and much more.
+
+## List jobs
+
+The first page you will arrive at in the Web UI is the Jobs List page. Here you
+will find every job for a namespace in a region. The table of jobs is
+searchable, sortable, and filterable. Each job row in the table shows basic
+information, such as job name, status, type, and priority, as well as richer
+information such as a visual representation of all allocation statuses.
+
+This view will also live-update as jobs get submitted, get purged, and change
+status.
+
+[![Jobs List][img-jobs-list]][img-jobs-list]
+
+## Filter job view
+
+If your Nomad cluster has many jobs, it can be useful to filter the list of all
+jobs down to only those matching certain facets. The Web UI has four facets you
+can filter by:
+
+1. **Type:** The type of job, including Batch, Parameterized, Periodic, Service,
+ and System.
+
+1. **Status:** The status of the job, including Pending, Running, and Dead.
+
+1. **Datacenter:** The datacenter the job is running in, including a dynamically
+ generated list based on the jobs in the namespace.
+
+1. **Prefix:** The possible common naming prefix for a job, including a
+ dynamically generated list based on job names up to the first occurrence of
+ `-`, `.`, and `_`. Only prefixes that match multiple jobs are included.
+
+[![Job Filters][img-job-filters]][img-job-filters]
+
+## Inspect an allocation
+
+In Nomad, allocations are the schedulable units of work. This is where runtime
+metrics begin to surface. An allocation is composed of one or more tasks, and
+the utilization metrics for tasks are aggregated so they can be observed at the
+allocation level.
+
+### Monitor resource utilization
+
+Nomad has APIs for reading point-in-time resource utilization metrics for tasks
+and allocations. The Web UI uses these metrics to create time-series graphs for
+the current session.
+
+When viewing an allocation, resource utilization will automatically start
+logging.
+
+[![Allocation Resource Utilization][img-alloc-resource-utilization]][img-alloc-resource-utilization]
+
+### Review task events
+
+When Nomad places, prepares, and starts a task, a series of task events are
+emitted to help debug issues in the event that the task fails to start.
+
+Task events are listed on the Task Detail page and live-update as Nomad handles
+managing the task.
+
+[![Task Events][img-task-events]][img-task-events]
+
+### View rescheduled allocations
+
+Allocations will be placed on any client node that satisfies the constraints of
+the job definition. There are events, however, that will cause Nomad to
+reschedule allocations, (e.g., node failures).
+
+Allocations can be configured [in the job definition to reschedule] to a
+different client node if the allocation ends in a failed status. This will
+happen after the task has exhausted its [local restart attempts].
+
+The end result of this automatic procedure is a failed allocation and that
+failed allocation's rescheduled successor. Since Nomad handles all of this
+automatically, the Web UI makes sure to explain the state of allocations through
+icons and linking previous and next allocations in a reschedule chain.
+
+[![Allocation Reschedule Icon][img-alloc-reschedule-icon]][img-alloc-reschedule-icon]
+
+[![Allocation Reschedule Details][img-alloc-reschedule-details]][img-alloc-reschedule-details]
+
+### Unhealthy driver
+
+Given the nature of long-lived processes, it's possible for the state of the
+client node an allocation is scheduled on to change during the lifespan of the
+allocation. Nomad attempts to monitor pertinent conditions including driver
+health.
+
+The Web UI denotes when a driver an allocation depends on is unhealthy on the
+client node the allocation is running on.
+
+[![Allocation Unhealthy Driver][img-alloc-unhealthy-driver]][img-alloc-unhealthy-driver]
+
+### Preempted allocations
+
+Much like how Nomad will automatically reschedule allocations, Nomad will
+automatically preempt allocations when necessary. When monitoring allocations in
+Nomad, it's useful to know what allocations were preempted and what job caused
+the preemption.
+
+The Web UI makes sure to tell this full story by showing which allocation caused
+an allocation to be preempted as well as the opposite: what allocations an
+allocation preempted. This makes it possible to traverse down from a job to a
+preempted allocation, to the allocation that caused the preemption, to the job
+that the preempting allocation is for.
+
+[![Allocation Preempter][img-alloc-preempter]][img-alloc-preempter]
+
+[![Allocation Preempted][img-alloc-preempted]][img-alloc-preempted]
+
+## Review task logs
+
+A task will typically emit log information to `stdout` and `stderr`. Nomad
+captures these logs and exposes them through an API. The Web UI uses these APIs
+to offer `head`, `tail`, and streaming logs from the browser.
+
+The Web UI will first attempt to directly connect to the client node the task is
+running on. Typically, client nodes are not accessible from the public internet.
+If this is the case, the Web UI will fall back and proxy to the client node from
+the server node with no loss of functionality.
+
+[![Task Logs][img-task-logs]][img-task-logs]
+
+~> Not all browsers support streaming HTTP requests. In the event that streaming
+is not supported, logs will still be followed using interval polling.
+
+## Restart or stop an allocation or task
+
+Nomad allows for restarting and stopping individual allocations and tasks. When
+a task is restarted, Nomad will perform a local restart of the task. When an
+allocation is stopped, Nomad will mark the allocation as complete and perform a
+reschedule onto a different client node.
+
+Both of these features are also available in the Web UI.
+
+[![Allocation Stop and Restart][img-alloc-stop-restart]][img-alloc-stop-restart]
+
+## Force a periodic instance
+
+Periodic jobs are configured like a cron job. Sometimes, you might want to start
+the job before the its next scheduled run time. Nomad calls this a [periodic
+force] and it can be done from the Web UI on the Job Overview page for a
+periodic job.
+
+[![Periodic Force][img-periodic-force]][img-periodic-force]
+
+## Submit a new version of a job
+
+From the Job Definition page, a job can be edited. After clicking the Edit
+button in the top-right corner of the code window, the job definition JSON
+becomes editable. The edits can then be planned and scheduled.
+
+[![Job Definition Edit][img-job-definition-edit]][img-job-definition-edit]
+
+~> Since each job within a namespace must have a unique name, it is possible to
+submit a new version of a job from the Run Job screen. Always review the plan
+output.
+
+## Monitor a deployment
+
+When a system or service job includes the [`update` stanza], a deployment is
+created upon job submission. Job deployments can be monitored in realtime from
+the Web UI.
+
+The Web UI will show as new allocations become placed, tallying towards the
+expected total, and tally allocations as they become healthy or unhealthy.
+
+Optionally, a job may use canary deployments to allow for additional health
+checks or manual testing before a full roll out. If a job uses canaries and is
+not configured to automatically promote the canary, the canary promotion
+operation can be done from the Job Overview page in the Web UI.
+
+[![Job Deployment with Canary Promotion][img-job-deployment-canary]][img-job-deployment-canary]
+
+## Stop a job
+
+Jobs can be stopped from the Job Overview page. Stopping a job will gracefully
+stop all allocations, marking them as complete, and freeing up resources in the
+cluster.
+
+[![Job Stop][img-job-stop]][img-job-stop]
+
+## Continue your exploration
+
+Now that you have explored operations that can be performed with jobs through
+the Nomad UI, learn how to inspect the state of your cluster using the Nomad UI.
+
+[`update` stanza]: /nomad/docs/job-specification/update
+[img-alloc-preempted]: /img/monitor/guide-ui-img-alloc-preempted.png
+[img-alloc-preempter]: /img/monitor/guide-ui-img-alloc-preempter.png
+[img-alloc-reschedule-details]: /img/monitor/guide-ui-img-alloc-reschedule-details.png
+[img-alloc-reschedule-icon]: /img/monitor/guide-ui-img-alloc-reschedule-icon.png
+[img-alloc-resource-utilization]: /img/monitor/guide-ui-img-alloc-resource-utilization.png
+[img-alloc-stop-restart]: /img/monitor/guide-ui-img-alloc-stop-restart.png
+[img-alloc-unhealthy-driver]: /img/monitor/guide-ui-img-alloc-unhealthy-driver.png
+[img-job-definition-edit]: /img/monitor/guide-ui-img-job-definition-edit.png
+[img-job-deployment-canary]: /img/monitor/guide-ui-img-job-deployment-canary.png
+[img-job-filters]: /img/monitor/guide-ui-img-job-filters.png
+[img-job-stop]: /img/monitor/guide-ui-img-job-stop.png
+[img-jobs-list]: /img/monitor/guide-ui-jobs-list.png
+[img-periodic-force]: /img/monitor/guide-ui-img-periodic-force.png
+[img-task-events]: /img/monitor/guide-ui-img-task-events.png
+[img-task-logs]: /img/monitor/guide-ui-img-task-logs.png
+[in the job definition to reschedule]: /nomad/docs/job-specification/reschedule
+[local restart attempts]: /nomad/docs/job-specification/restart
+[periodic force]: /nomad/commands/job/periodic-force
+[securing the web ui with acls]: /nomad/tutorials/access-control
diff --git a/website/content/docs/networking/cni.mdx b/website/content/docs/networking/cni.mdx
index 19376bddb..d81072b3c 100644
--- a/website/content/docs/networking/cni.mdx
+++ b/website/content/docs/networking/cni.mdx
@@ -39,8 +39,8 @@ Perform the following on each Nomad client:
1. [Create a bridge mode configuration](#create-a-cni-bridge-mode-configuration).
1. [Configure Nomad clients](#configure-nomad-clients).
-After you configure and restart your Nomad clients, [use a CNI network with a
-job](#use-a-cni-network-with-a-job).
+After you configure and restart your Nomad clients, refer to [Use a CNI network
+with a job][] for job configuration.
### Install CNI reference plugins
@@ -242,24 +242,13 @@ client {