Connect Axios to Unix Domain Sockets in Node.js
Communicating over Unix domain sockets instead of standard TCP/IP ports offers significant performance and security benefits for local inter-process communication in Node.js. This article explains how to configure the Axios HTTP client to send requests through Unix domain sockets using native configuration parameters and custom HTTP agents, illustrated with practical code examples such as interacting with the Docker daemon.
Understanding Unix Domain Sockets in Axios
A Unix domain socket (UDS) allows bidirectional data exchange between
processes running on the same host operating system without the overhead
of network routing. Node.js's underlying http and
https modules natively support Unix domain sockets via the
socketPath option. Because Axios relies on these standard
Node.js modules for transport, you can pass socket paths directly
through Axios request configs.
Method 1:
Using the Native socketPath Configuration
The most straightforward way to route requests through a socket is by
defining the socketPath property in the Axios configuration
object.
const axios = require('axios');
async function querySocket() {
try {
const response = await axios.get('http://localhost/info', {
socketPath: '/var/run/my-service.sock'
});
console.log(response.data);
} catch (error) {
console.error('Request failed:', error.message);
}
}
querySocket();When socketPath is provided:
- The hostname in the URL (e.g.,
http://localhostorhttp://unix) acts as a placeholder to satisfy URL parsing requirements and to populate theHostheader. - The request path (e.g.,
/info) is appended directly to the HTTP request sent through the socket.
Practical Example: Interacting with the Docker Engine API
A common use case for Unix sockets in Node.js is communicating
directly with the Docker daemon located at
/var/run/docker.sock.
const axios = require('axios');
const dockerClient = axios.create({
socketPath: '/var/run/docker.sock',
baseURL: 'http://localhost/v1.41'
});
async function listContainers() {
try {
const response = await dockerClient.get('/containers/json');
console.log('Running containers:', response.data);
} catch (error) {
console.error('Error fetching containers:', error.message);
}
}
listContainers();Method 2: Using a Custom
http.Agent
For advanced connection pooling, timeouts, or specific keep-alive
configurations, you can instantiate a custom Node.js
http.Agent with the socketPath option and
assign it to the Axios httpAgent property.
const axios = require('axios');
const http = require('http');
const agent = new http.Agent({
socketPath: '/tmp/custom-app.sock',
keepAlive: true,
maxSockets: 10
});
const client = axios.create({
httpAgent: agent,
baseURL: 'http://unix'
});
async function sendPostRequest() {
try {
const response = await client.post('/api/data', {
payload: 'sample data'
});
console.log('Response:', response.data);
} catch (error) {
console.error('Agent request failed:', error.message);
}
}
sendPostRequest();Key Considerations
- File Permissions: Ensure the Node.js process has
read and write permissions for the specified
.sockfile path. - Platform Differences: Unix domain sockets are
native to POSIX systems (Linux, macOS). On Windows, named pipes (e.g.,
\\\\.\\pipe\\docker_engine) are used similarly through thesocketPathparameter. - URL Schemes: Always specify
http://as the protocol in your URL. Even though communication travels over a local socket, the data payload remains standard HTTP.