Full error message: connect ECONNREFUSED 127.0.0.1:30561 at TCPConnectWrap.afterConnect
The axios request is running in a Node.js environment (Next.js), which is where the error occurs, strangely the axios request works perfectly fine when it is being run in the browser.
My component (running in Node.js) that calls axios:
import axios from 'axios'
import Router from 'next/router'
import React, { Component } from 'react'
import { initializeStore } from '~/reducers'
import { authenticate } from '~/actions/auth'
import { getCookieByName } from '~/helpers/cookie'
const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'
function getOrCreateStore(initialState) {
// Always make a new store if server, otherwise state is shared between requests
if (isServer) {
return initializeStore(initialState)
}
// Create store if unavailable on the client and set it on the window object
if (!window[__NEXT_REDUX_STORE__]) {
window[__NEXT_REDUX_STORE__] = initializeStore(initialState)
}
return window[__NEXT_REDUX_STORE__]
}
export default App => {
return class AppWithRedux extends Component {
static async getInitialProps(appContext) {
const reduxStore = getOrCreateStore()
appContext.ctx.reduxStore = reduxStore
let appProps = {}
if (typeof App.getInitialProps === 'function') {
appProps = await App.getInitialProps(appContext)
}
const JWT = (isServer ? getCookieByName('JWT', appContext.ctx.req.headers.cookie) : getCookieByName('JWT', document.cookie))
const pathname = appContext.ctx.pathname
//set axios baseURL
axios.defaults.baseURL = (isServer ? `${appContext.ctx.req.headers['x-forwarded-proto']}://${appContext.ctx.req.headers.host}` : window.location.origin)
//if user has a JWT
if(JWT){
axios.defaults.headers.common['Authorization'] = `Bearer ${JWT}`
//get user from API layer
reduxStore.dispatch(authenticate())
}
return {
...appProps,
initialReduxState: reduxStore.getState()
}
}
constructor(props) {
super(props)
this.reduxStore = getOrCreateStore(props.initialReduxState)
}
render() {
return <App {...this.props} reduxStore={this.reduxStore} />
}
}
}
Specifically reduxStore.dispatch(authenticate())
And my actual axios call (using redux thunk), looking at the authenticate
method:
import axios from 'axios'
import { setCookieByName } from '~/helpers/cookie'
const BASE_URL = '/api/auth'
export const TYPE_REGISTER = 'TYPE_REGISTER'
export const TYPE_AUTHENTICATE = 'TYPE_AUTHENTICATE'
export const register = values => (dispatch) => {
return axios.post(`${BASE_URL}/register`, values)
.then(function({data: {token, user}}){
setCookieByName('JWT', token, 365)
dispatch({
type: TYPE_REGISTER,
payload: user
})
})
}
export const authenticate = () => (dispatch) => {
return axios.post(`${BASE_URL}/me`)
.then(function({data: {user}}){
dispatch({
type: TYPE_AUTHENTICATE,
payload: user
})
})
.catch(function(err){
console.log(err)
dispatch({
type: TYPE_AUTHENTICATE,
payload: {}
})
})
}
I'm running my local Kubernetes cluster using Docker for Mac, and my Ingress controller is being accessed on http://kludge.info:30561
. My domain is mapped from 127.0.0.1 kludge.info
locally to allow the Ingress controller to hit the container. My theory is that when I send a request to http://kludge.info:30561/api/auth/me
for example, the docker container running the Node.js app thinks it is a request to localhost (inside the container), and results in a connection error. Please note that the Node.js app inside the container is running on http://localhost:8080
. Basically I'm running localhost on my machine, and localhost inside the Node instance. How could I send a request outside to http://kludge.info:30561/
where the Ingress controller is running.
I've also configured the baseURL
in axios, but it does not solve the problem. My ingress controller has a path /api
that will point to a PHP instance, so I need my Node.js axios call to hit that inside it's container. Any help would be much appreciated.
When I ran my K8 cluster on Minikube I did not have this problem, however minikube does provide you with the IP of the VM, while Docker for Desktop uses localhost
directly on your machine.