# InkChain docs: a Nextra site whose build instructions point at a missing Dockerfile

> The inkonchain/docs repository is the documentation site application for InkChain, built on Next.js with Nextra, a pnpm workspace pinned through Volta, and four pull request checks. Two things undercut the quick start: the repository root contains no Dockerfile for the documented `docker build` to consume, and the project is still on the Pages Router because of stated compatibility limits.

**inkonchain/docs** — Ink Documentation

- Repository: https://github.com/inkonchain/docs
- Website: https://docs.inkonchain.com
- Stars: 36,488 · Forks: 484
- Language: MDX
- License: not declared
- Published: 2026-08-17 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/inkonchain-docs

## The first instruction builds an image the root cannot supply

The quick start opens with two steps:

```
docker build -t docs .
```

then

```
docker run -p 3000:3000 docs
```

The context is the current directory, so the build depends entirely on what the repository root provides. Enumerating that root gives .eslintrc.js, .npmrc, .nvmrc, cspell.json, next.config.mjs, package.json, pnpm-lock.yaml, theme.config.tsx, tsconfig.json, and directories for src, public, cspell, and .github. No Dockerfile appears among them. So the container path cannot be reproduced from the entry point as written, and the failure arrives at the first build rather than at a documented missing file, because the missing file is the one the build itself looks for. Anyone planning to run the published site in a container has to author that image themselves, which means choosing a base image, installing pnpm, and deciding whether the lockfile is honored.

## The container path and the local path do not share a setup story

Local development is a three step sequence with two commands in it:

```
pnpm install
```

followed by

```
pnpm run dev
```

The dependency step is pinned: the packageManager field declares pnpm@9.12.3, and a volta block pins both tools. The Docker path in the quick start skips all of it, going straight to a build from the current directory, and it is the only place in the file where a Node version is not mentioned. The practical consequence is that the two documented routes can drift apart silently, since one is checked against a lockfile and a pinned package manager while the other is whatever the image contains. Teams that standardize on containers will find themselves maintaining a second source of truth for the toolchain, and the repository gives them no file to start from.

## Node v20.11.0 in the text, 22.14.0 in the toolchain pin

Two version statements govern the runtime, and they answer different questions. The requirements section gives a floor:

```
**Node.js**: v20.11.0 or higher
```

The toolchain pin in package.json is a fixed point:

```json
  "volta": {
    "node": "22.14.0",
    "pnpm": "9.12.3"
  },
```

A .nvmrc file sits in the root as well, though its contents are not stated in the repository documentation, so a third source exists without a published value. That is fine for contributors who let Volta or the nvm file choose, and it is a genuine ambiguity for everyone else. Someone on Node 20 satisfies the written requirement, installs, and can still hit a build that was developed and locked against 22.14.0, and nothing in the file explains the gap between the two numbers. Pick one and record it in your own CI rather than assuming the floor is what the project tests against.

## pnpm run lint is four checks joined by &&

The lint entry point is a chain, not a single tool:

```json
    "lint": "pnpm run lint:js && pnpm run lint:mdx && pnpm run format:js:check && pnpm run spellcheck:lint",
```

and the fixing variant mirrors it in the same order:

```json
    "lint:fix": "pnpm run lint:js:fix && pnpm run lint:mdx:fix && pnpm run format:js && pnpm run spellcheck:fix",
```

Each stage is a different tool with a different file scope. JavaScript and TypeScript are checked with `eslint ./src theme.config.tsx --ext js,jsx,ts,tsx`, which is why the Nextra theme file is linted alongside the source directory. Markdown goes through `remark . --quiet --frail`, where the frail flag turns warnings into failures. Prettier checks `"**/*.{ts,tsx,css,scss}"`, so stylesheets are formatted but Markdown is not. Because the stages are joined with `&&`, the first failing stage hides the rest, which means a run that stops on a spelling issue never tells you whether the formatter is also unhappy.

## Both emphasis and strong are configured to a single asterisk

The remark configuration rewrites the usual Markdown conventions. Its settings block is:

```json
    "settings": {
      "emphasis": "*",
      "strong": "*"
    },
```

Setting both markers to `*` means a single asterisk is the canonical emphasis form and a single asterisk is also the canonical strong form, with no doubled marker used for either. Combined with the remark-preset-lint-recommended and remark-preset-lint-consistent plugins, plus rules for frontmatter schema, heading style, list item indent, table cell padding, table pipe alignment, table pipes, and unordered list marker style, the markdown you write is normalized on the way in and policed on every pull request. The consequence for authors is that hand written bold with two asterisks will be rewritten, and a heading that uses a style other than the one the rule expects will fail the check rather than render differently.

## spellcheck:fix prints a word list that a human must then commit

Spelling is enforced on MDX only, and the two halves of the workflow are asymmetric:

```json
    "spellcheck:lint": "cspell lint \"**/*.mdx\"",
    "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq"
```

The fix command does not edit the documents. It collects unknown words, sorts them, and prints them, so the intended workflow is: run it, then paste the output into the whitelist file at `./cspell/project-words.txt`, which the CI documentation names as the place to add unique terms such as InkChain. A cspell.json configuration and a cspell directory sit in the root. The consequence is that every new product term or identifier in the documentation costs a manual edit, and a contributor who only runs the automated fix will see the check fail again on the same word with nothing in their working tree explaining why.

## Amplify deploys every pull request and main, and nothing documents a rollback

Deployment is continuous on both sides of the merge. Every new pull request gets a temporary environment built on AWS Amplify, with the URL surfaced in the PR checks so reviewers can read the change on a live site. The main branch is configured for automatic deployment, so every merge produces a new build without manual action. Four checks gate that pipeline, js-lint, md-lint, format, and spell-check, matching the script chain described above. What is not described is a test job: the scripts contain no test command and no test framework appears in the tooling list, so nothing verifies that a documentation change renders. There is also no stated rollback, no pinned Amplify branch naming, and no recorded build command, which means the build settings that work here live in the Amplify console rather than in the repository.

## Two ESLint configurations and a theme file that lints as source

The root carries both eras of ESLint configuration, .eslintrc.js and eslint.config.js, alongside .prettierrc, postcss.config.js, and tailwind.config.js. Formatting and linting are therefore configured in four places before any application code is considered. The Next.js surface is described by next.config.mjs and next-env.d.ts, with global-env.d.ts for ambient types, while the Nextra layer is theme.config.tsx, which sits outside src/ and is the one non source file the lint script names explicitly. The build chain is short: `next dev`, `next build`, then a postbuild hook that runs next-sitemap, and a `next start` for serving, with the pinned dependencies including next 15.5.24, next-sitemap 4.2.3, next-themes 0.4.6, and clsx 2.1.1. Sitemap generation, in other words, is a build step you inherit rather than a choice.

## Conclusion

Adopt this repository if your documentation work is MDX under Nextra and you are willing to stay on the Pages Router, which the project itself attributes to compatibility limitations. Do not adopt it expecting a container workflow you can reproduce from the entry point, or a test suite to catch content regressions, because the scripts contain no test command and the root carries no Dockerfile. Before you build on it, confirm the container path against your own Dockerfile, settle which Node version your team standardizes on given the README minimum and the Volta pin, and check that Amplify build settings match the pnpm version the lockfile expects.

## FAQ

### What do I need to run the InkChain docs site locally?

Node.js v20.11.0 or higher, then pnpm install followed by pnpm run dev, which maps to next dev. The package manifest pins the toolchain further with volta at Node 22.14.0 and pnpm 9.12.3, and declares pnpm@9.12.3 as the packageManager.

### How do I build a Docker image for the InkChain documentation?

The entry point documents docker build -t docs . followed by docker run -p 3000:3000 docs, using the current directory as the build context. The repository root as listed does not include a Dockerfile, so the image definition has to be supplied before that command can succeed.

### Why did the InkChain docs project not move to the App Router?

The project states that due to compatibility limitations it has not yet upgraded to the App Router, and relies on the Pages Router for navigation and routing because that is what Nextra supports in this setup.

### What does the InkChain docs CI pipeline check on a pull request?

Four checks: js-lint using ESLint for JavaScript code formatting, md-lint using Remark for Markdown code formatting, format using Prettier for consistent code style, and spell-check using CSpell on the documentation. Unique terms are whitelisted through the ./cspell/project-words.txt file.

### How do I add a new word to the InkChain docs spell checker?

Add it to the ./cspell/project-words.txt file, which the pipeline documentation names as the whitelist for unique terms such as InkChain. The checking command is cspell lint "**/*.mdx", and the fixing command only prints the unknown words for you to commit yourself.

## Sources

- [Official documentation](https://docs.inkonchain.com)
- [Official README](https://github.com/inkonchain/docs#readme)
- [Project repository](https://github.com/inkonchain/docs)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/inkonchain-docs
