Dockerfile Language Server
The Dockerfile Language Server provides robust Language Server Protocol (LSP) support for Dockerfiles, enhancing developer experience across various code editors. Written in TypeScript and powered by Node.js, it offers features such as code completion, diagnostics, formatting, hover information, code actions, and semantic highlighting. Currently stable at version `0.15.0`, the project sees a consistent release cadence driven by updates to its core logic libraries. Unlike monolithic language servers, this package is designed specifically as the LSP server frontend, delegating the heavy lifting of Dockerfile parsing and language intelligence to the separate `dockerfile-ast`, `dockerfile-language-service`, and `dockerfile-utils` libraries. This architecture allows for a lean server implementation and flexible integration, as demonstrated by its adoption in popular extensions like VS Code Docker, Sublime Text LSP-dockerfile, and clients for Zed, Atom, Sourcegraph, Theia, and Emacs.
Common errors
-
SyntaxError: Unexpected token '.' at wrapSafe (internal/modules/cjs/loader.js:915:16)
cause This error often indicates that the Node.js version running the server is too old to support modern JavaScript syntax (e.g., optional chaining or nullish coalescing) used by the language server or its dependencies.fixUpgrade your Node.js runtime to a version that supports the required syntax. As of `0.15.0`, Node.js 16 or higher is recommended. -
Error: spawn docker-langserver ENOENT
cause The `docker-langserver` executable could not be found in the system's PATH, meaning either the package was not installed globally, or the PATH is not correctly configured.fixInstall the package globally using `npm install -g dockerfile-language-server-nodejs` and verify that the `docker-langserver` binary is accessible in your system's PATH. You may need to restart your terminal or shell. -
Language server cannot start right after installing the extension
cause This can occur in VS Code environments if multiple Docker-related extensions (e.g., Docker DX and Container Tools) are installed and activated in a specific order, leading to a race condition or conflict during server startup.fixOften, restarting the VS Code window (Developer: Reload Window) can resolve this. In some cases, adjusting extension activation order or disabling/re-enabling them may be necessary.
Warnings
- breaking Support for Node.js 14 was removed in version `0.10.0` and Node.js 12 in `0.9.0`. Running the server with these older Node.js versions will result in runtime errors due to incompatible JavaScript syntax (e.g., optional chaining).
- breaking The internal `dockerfile-language-service` library, which this server consumes, transitioned its build output from UMD to CJS in `0.15.0`. While this primarily affects direct consumers of `dockerfile-language-service`, it could lead to subtle module resolution issues if an environment is explicitly configured for UMD or has strict module resolution rules that do not correctly handle CJS.
- gotcha When installing the Dockerfile Language Server globally via `npm install -g dockerfile-language-server-nodejs`, ensure that the `docker-langserver` executable is correctly added to your system's PATH. If not, client applications (like editor extensions) may fail to launch the server, reporting 'command not found' errors.
Install
-
npm install dockerfile-language-server-nodejs -
yarn add dockerfile-language-server-nodejs -
pnpm add dockerfile-language-server-nodejs
Imports
- startServer
import { startServer } from 'dockerfile-language-server-nodejs/lib/server'; - DockerfileLanguageServerOptions
import type { DockerfileLanguageServerOptions } from 'dockerfile-language-server-nodejs/lib/server'; - docker-langserver binary (CLI)
import { main } from 'dockerfile-language-server-nodejs/lib/main';
Quickstart
import { spawn } from 'child_process';
import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';
import type { InitializeParams } from 'vscode-languageserver';
const serverProcess = spawn('docker-langserver', ['--stdio'], {
stdio: ['pipe', 'pipe', 'inherit'],
windowsHide: true
});
const connection = createConnection(ProposedFeatures.all, serverProcess.stdin, serverProcess.stdout);
connection.onInitialize(async (params: InitializeParams) => {
console.log('LSP Client: Received initialize request from server.');
return {
capabilities: {
textDocumentSync: 1, // Full
completionProvider: { resolveProvider: true, triggerCharacters: [' ', '.', '-', ':'] },
hoverProvider: true,
definitionProvider: true,
documentFormattingProvider: true,
diagnosticProvider: { interFileDependencies: false, workspaceDiagnostics: false }
},
serverInfo: { name: 'Test Dockerfile LSP Client', version: '1.0.0' }
};
});
connection.onInitialized(() => {
console.log('LSP Client: Initialized. Language Server is ready.');
});
connection.listen();
serverProcess.on('exit', (code, signal) => {
console.log(`LSP Server process exited with code ${code} and signal ${signal}`);
process.exit(code || 0);
});
serverProcess.on('error', (err) => {
console.error('Failed to start LSP server process:', err);
process.exit(1);
});
console.log('LSP Client: Connecting to Dockerfile Language Server...');
// In a real scenario, you'd send a didOpen notification here for a Dockerfile.
// For this quickstart, we just establish the connection.