In a SvelteKit server action (+page.server.js
), I am attempting to use SvelteKit's fetch
implementation to call an API endpoint.
This is hosted within a Docker container on port 8000
, trying to call a GraphQL service served from another container on port 8002
.
import { fail } from '@sveltejs/kit'
export const actions = {
default: async ({ request, cookies, fetch }) => {
const form = await request.formData()
const username = form.get('username')
const password = form.get('password')
if (!username || !password) return fail(400, { username })
const result = await fetch('http://localhost:8002/sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
// Omitted because it doesn't appear to be the cause of this issue.
body: JSON.stringify({}),
})
console.log({result})
}
}
The call to fetch
throws this error:
TypeError: fetch failed
at node:internal/deps/undici/undici:13484:13
at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
[cause]: Error: connect ECONNREFUSED 127.0.0.1:8002
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1615:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 8002
}
}
I've seen advice elsewhere to reference 127.0.0.1
instead of localhost
, but that still doesn't resolve the issue for me.
Using Postman to call the same endpoint with the same info works fine, so this all seems to be an issue with SvelteKit/Node connecting to the API service.
Because I'm using Docker on macOS, I need to reference other local containers with host.docker.internal
instead of localhost
or 127.0.0.1
:
const result = await fetch('http://host.docker.internal:8002/sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
})
I read that this also applies if you're running Docker on Windows.