You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt3中调用useFetch()在Docker容器触发Vue Router错误

Nuxt 3 + Docker:容器内useFetch请求触发Vue Router错误,且出现套接字占用问题

环境版本

  • Nuxt 3.10.2
  • Docker 25.0.3
  • Node.js 20.9

问题描述

本地执行npm run dev时应用运行正常,但Docker容器中启动后出现两个核心问题:

  1. Vue Router匹配错误:所有useFetch请求触发No match found for location with path "/api/v1/xxx"警告,API请求无法正确发送到后端,应用无法响应请求。
  2. 套接字地址占用:容器启动后页面无法打开,抛出listen EADDRINUSE: address already in use /tmp/nitro/worker-xx-x.sock错误。

容器启动日志(Vue Router错误阶段)

> docker-compose -f docker-compose.local.yml up
[+] Running 1/2
 ✔ Network frontend    Created                                                                                     0.1s
 - Container frontend  Created                                                                                     0.2s
Attaching to frontend
frontend  |
frontend  | > dev
frontend  | > nuxt dev
frontend  |
frontend  | Nuxt 3.10.2 with Nitro 2.8.1
frontend  |
frontend  | [QR code]
frontend  |
frontend  |   ➜ Local:    http://0.0.0.0:/
frontend  |   ➜ Network:  http://172.19.0.4:/ [QR code]
frontend  |   ➜ Network:  http://172.20.0.2:/
frontend  |
frontend  | [nuxt:tailwindcss] ℹ Using default Tailwind CSS file
frontend  | ℹ Compiled types/plugins.d.ts in 774.5ms
frontend  | ℹ Compiled plugins/server.mjs in 769.24ms
frontend  | ℹ Compiled plugins/client.mjs in 798.45ms
frontend  | ℹ Vite server warmed up in 76990ms
frontend  | ℹ Vite client warmed up in 82499ms
frontend  | [nitro] ✔ Nitro built in 4538 ms
frontend  | [Vue Router warn]: No match found for location with path "/api/v1/user/profile"
frontend  | [Vue Router warn]: No match found for location with path "/api/v1/user/profile"
...(省略重复警告)

后续套接字占用错误日志

frontend  |   ➜ Local:    http://0.0.0.0:/
frontend  |   ➜ Network:  http://172.21.0.2:/ [QR code]
frontend  |
frontend  | [nuxt:tailwindcss] ℹ Using default Tailwind CSS file
frontend  | ℹ Vite server warmed up in 43668ms
frontend  | ℹ Vite client warmed up in 52475ms
frontend  | [nitro] ✔ Nitro built in 2394 ms
frontend  | [nitro] [uncaughtException] Error: listen EADDRINUSE: address already in use /tmp/nitro/worker-30-1.sock
frontend  |     at Server.setupListenHandle [as _listen2] (node:net:1880:21)
frontend  |     at listenInCluster (node:net:1945:12)
frontend  |     at Server.listen (node:net:2054:5)
frontend  |     at <anonymous> (/src/node_modules/nitropack/dist/runtime/entries/nitro-dev.mjs:26:25)
frontend  |     at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
frontend  |     at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
frontend  |     at async loadESM (node:internal/process/esm_loader:28:7)
frontend  |     at async handleMainPromise (node:internal/run_main:113:12) {
frontend  |   code: 'EADDRINUSE',
frontend  |   errno: -98,
frontend  |   syscall: 'listen',
frontend  |   address: '/tmp/nitro/worker-30-1.sock',
frontend  |   port: -1
frontend  | }

相关代码

插件文件:./plugins/loadCity.ts

import {useCityStore} from "~/store/useCityStore";

export default defineNuxtPlugin(async (nuxtApp) => {
    const location = useCityStore();

    if(!location.currentCity){
        await location.fetchCity(); // 触发错误: No match found for location with path "/api/v1/city/get"
    }
});

Pinia Store:/store/useCityStore.ts

import { defineStore } from "pinia";

export const useCityStore = defineStore('location', () => {
    async function fetchCity() {
        const {data} = await useApiFetch(`/api/v1/city/get`);

        // 其他逻辑
    }
    return { fetchCity }
});

自定义Fetch钩子:useApiFetch.ts

export function useApiFetch<T> (path: string|(() => string)|ComputedRef<string>, options: UseFetchOptions<T> = {}) {
    const config = useRuntimeConfig()

    const xsrfToken = useCookie('XSRF-TOKEN');

    let headers: any = {
        accept: 'application/json',
        referer: config.public.api.referer,
        ...options?.headers,
    }

    if (xsrfToken && xsrfToken.value !== null) {
        headers['X-XSRF-TOKEN'] = xsrfToken.value as string;
    }

    if (process.server) {
        headers = {
            ...headers,
            ...useRequestHeaders(['cookie']),
        }
    }

    return useFetch(path, {
        baseURL: config.public.api.url,
        watch: false,
        credentials: 'include',
        ...options,
        headers,
    })
}

Docker配置

Dockerfile.dev

# syntax = docker/dockerfile:1

ARG NODE_VERSION=20.9

FROM node:${NODE_VERSION}-slim as base

ENV NODE_ENV=development

WORKDIR /src

# Build
FROM base as build

COPY --link package.json package-lock.json ./

RUN npm install

# Run
FROM base

COPY --from=build /src/node_modules /src/node_modules

CMD [ "npm", "run", "dev" ]

docker-compose.yml

version: '3.7'
services:
  frontend:
    container_name: frontend
    build:
      context: .
      dockerfile: ./Dockerfile.dev
    restart: always
    volumes:
      - ./:/src
      - node_modules:/src/node_modules
    working_dir: /src
    expose:
      - 80
      - 24678
    ports:
      - "24678:24678"
    environment:
      NODE_OPTIONS: '--max_old_space_size=4096'
      VIRTUAL_HOST: $FRONTEND_DOMAIN
      LETSENCRYPT_HOST: $FRONTEND_DOMAIN
      LETSENCRYPT_EMAIL: "le@bybuy.kz"
      HTTPS_METHOD: noredirect
      VIRTUAL_PORT: 80
      NITRO_PORT: 80
      NITRO_HOST: 0.0.0.0
      PORT: 80
      NUXT_SITE_URL: $NUXT_SITE_URL
      NUXT_API_URL: $NUXT_API_URL
      NUXT_API_REFERRER: $NUXT_API_REFERRER
      NUXT_SEARCH_API_KEY: $NUXT_SEARCH_API_KEY
      NUXT_SEARCH_HOST: $NUXT_SEARCH_HOST
      NUXT_SEARCH_PORT: $NUXT_SEARCH_PORT
      NUXT_SEARCH_PROTOCOL: $NUXT_SEARCH_PROTOCOL
    networks:
      - frontend
      - reverse-proxy

networks:
  reverse-proxy:
    name: reverse-proxy
    external: true
  frontend:
    name: frontend
    driver: bridge

volumes:
  node_modules:

已尝试的排查

  • 排除代理问题:直接启动容器不使用反向代理,发送HTTP请求仍复现Vue Router错误。

排查与解决方案

针对Vue Router匹配错误

  1. 验证环境变量正确性

    • 确认容器内NUXT_API_URL已正确注入,且值为容器可访问的后端地址(避免使用localhost,容器内localhost指向自身,需改用宿主机IP或Docker服务名)。
    • 在useApiFetch中添加调试日志,打印config.public.api.url,确认baseURL是否正确:
      console.log('API Base URL:', config.public.api.url);
      
  2. 检查Nuxt运行时配置

    • 确保nuxt.config.ts中已正确暴露api.url和api.referer到客户端:
      export default defineNuxtConfig({
        runtimeConfig: {
          public: {
            api: {
              url: process.env.NUXT_API_URL,
              referer: process.env.NUXT_API_REFERRER
            }
          }
        }
      })
      
  3. 确认网络连通性

    • 进入容器内部,执行curl <NUXT_API_URL>/api/v1/city/get,验证是否能正常访问后端API:
      docker exec -it frontend bash
      curl $NUXT_API_URL/api/v1/city/get
      

针对套接字地址占用错误

  1. 清理残留套接字文件

    • 修改Dockerfile的CMD,启动前清理Nitro临时套接字:
      CMD ["sh", "-c", "rm -rf /tmp/nitro/ && npm run dev"]
      
  2. 强制清理容器资源

    • 停止并删除容器及相关卷,避免残留进程或文件:
      docker-compose down -v
      docker-compose up --build
      
  3. 指定Nitro使用端口而非套接字

    • 在环境变量中添加NITRO_PRESET=node-server,强制Nitro使用端口监听而非Unix套接字:
      # docker-compose.yml中frontend的environment添加
      NITRO_PRESET: node-server
      
  4. 检查容器重启策略

    • 暂时将restart: always改为restart: no,避免容器频繁重启导致资源泄漏,排查问题根源。

内容的提问来源于stack exchange,提问作者Olexin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:58:11