Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting vue devServer proxy to work with different local ports in docker

Going a little crazy here trying to get this set up properly. I have Vue running with devServer in docker, and then a separate volume running json-server, for serving up fake api data. For starters, I'd be happy to get this simple example working, but I keep getting proxy errors. Here is my current configs.

docker-compose:

version: "3.7"

services:
  front:
    container_name: front
    build: .
    volumes:
      - .:/app
      - ./node_modules:/app/node_modules
    ports:
      - '8080:8080'

  api:
    image: vimagick/json-server
    command: -H 0.0.0.0 -p 3000 -w db.json
    ports:
      - "3000:3000"
    volumes:
      - ./server/data:/data

Dockerfile:


FROM node:lts-alpine as front

# install simple http server for serving static content
RUN npm install -g @vue/cli

# make the 'app' folder the current working directory
WORKDIR /app

# Add necessary files to app
ENV PATH ./:/app/:./node_modules/.bin:$PATH
ENV NODE_ENV=development

# copy both 'package.json' and 'package-lock.json' (if available)
COPY package.json /app/package.json
COPY package-lock.json /app/package.lock.json

# install project dependencies
RUN npm install --silent

# copy project files and folders to the current working directory (i.e. 'app' folder)

COPY ./ .

EXPOSE 8080
CMD ["npm", "run", "serve"]

All of the above works fine. Everything above builds, and they are both running on their respective ports.

I can navigate to http://localhost:3000/posts, and I see the fake json I'm expecting. And I can do hot module reloading, dev, etc. on http://localhost:8080/. Now here's the rub. I want to use data from the json server in the vue app, and I want to proxy my requests from http://localhost:8080/api/* to http://localhost:3000/$1. Here is my Vue.Config file:

module.exports={
  devServer: {
      proxy: {
        "^/api/": {
          target: "http://localhost:3000/",
          secure: false,
          pathRewrite: {
            "/api/*": "/"
          }
        }
      }
    }
  };

Then within the app, I make requests like axios.get('/api/posts/'). I've tried about 100 different subtle variations of the code above in all three files, but every time I get this error:

Proxy error: Could not proxy request /posts from localhost:8080 to http://localhost:3000/ (ECONNREFUSED).

I'm thinking that I have a fundamental misunderstanding of how this is supposed to work, because I've followed every instruction and copied and pasted from Vue's instructions. Any insight that anyone can offer would be greatly appreciated

like image 681
dgo Avatar asked Jan 26 '23 01:01

dgo


1 Answers

The issue here that proxy to localhost is incorrect. It should work if you change your vue config to the following:

module.exports={
  devServer: {
      proxy: {
        "^/api/": {
          target: "http://api:3000",
          secure: false,
          pathRewrite: {
            "/api/*": "/"
          }
        }
      }
    }
  };

Basically, the change is replacing host from localhost to api. Reason for that is that docker-compose resolves host by service names. And since your service name is api, host should also be api.

To clarify a little more, the host here is not from your machine's prospective but from the vue.js container prospective. And from the vue.js container prospective, api is a separate host (not a localhost anymore). Hope this makes sense - if more clarification is needed, lmk.

like image 114
taleodor Avatar answered Jan 31 '23 08:01

taleodor