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

Docker部署NuxtJS+Express时@nuxtjs/auth-next登录报URIError

问题描述

使用@nuxtjs/auth-next模块调用$auth.loginWith()实现登录功能时,仅在Docker容器中运行Nuxt应用会触发URIError: URI malformed错误;直接通过yarn dev或yarn start启动应用则登录正常,请求可成功完成。

Chrome控制台显示Docker环境下请求已完成,但返回的是Nuxt的HTML页面,而非Express后端预期的JSON数据。

相关配置文件

nuxt.config.js

import colors from 'vuetify/es5/util/colors'

export default {
  target: 'static',
  srcDir: './',
  head: {
    titleTemplate: '%s - Dein digitaler Restauranthelfer',
    title: 'digimenu',
    htmlAttrs: {
      lang: 'de'
    },
    meta: [
      {charset: 'utf-8'},
      {name: 'viewport', content: 'width=device-width, initial-scale=1'},
      {hid: 'description', name: 'description', content: ''},
      {name: 'format-detection', content: 'telephone=no'}
    ],
    link: [
      {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}
    ]
  },
  css: [],
  plugins: [
    '~/plugins/vuex'
  ],
  components: true,
  buildModules: [
    '@nuxt/typescript-build',
    '@nuxtjs/vuetify'
  ],
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/auth-next',
/*    '@nuxtjs/proxy'*/
  ],
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    theme: {
      dark: true,
      themes: {
        dark: {
          primary: colors.orange.darken4,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    }
  },
  server: {
    host: process.env.HOST,
    port: 3000
  },
  serverMiddleware: [
    {path: '/api', handler: '~/api'},
    {path: '/api', handler: '~/middleware/session.js'}
  ],
  axios: {
    proxy: false
  },
  publicRuntimeConfig: {
    axios: {
      baseURL: process.env.BASE_URL,
      browserBaseURL: process.env.BROWSER_BASE_URL
    }
  },
  privateRuntimeConfig: {
    axios: {
      baseURL: process.env.BASE_URL,
      browserBaseURL: process.env.BROWSER_BASE_URL
    }
  },
/*  
proxy: {
    '/api/': { target: process.env.BASE_URL, pathRewrite: {'^/api/': ''}}
  },
*/
  router: {
    middleware: ['auth']
  },
  auth: {
    strategies: {
      local: {
        scheme: 'local',
        token: {
          property: 'token',
          global: true
        },
        user: {
          property: 'user'
        },
        endpoints: {
          login: { url: '/api/auth/login', method: 'post'},
          logout: { url: '/api/auth/logout', method: 'post'},
          user: {url:  '/api/auth/user', method: 'get'}
        }
      }
    },
    redirect: {
      login: '/login',
      logout: '/',
      home: '/admin'
    }
  },
  build: {
    transpile: [
      'defu'
    ]
  }
}

docker-compose.yml

version: "3.1"
services:
  nodeserver:
    image: node:14-alpine
    working_dir: /app
    ports:
      - 3000:3000
    volumes:
      - ./:/app
    command: [ "yarn", "start" ]
  db:
    image: mongo:latest
    restart: always
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${DB_USER:-digimenu}
      - MONGO_INITDB_ROOT_PASSWORD=${DB_PASSWORD:-digimenu}
    ports:
      - 27017:27017

.env

# 'nodeserver' if I run it with docker and 'localhost' if I run it with 'yarn dev'
HOST=nodeserver
BASE_URL=http://nodeserver:3000
BROWSER_BASE_URL=http://nodeserver:3000

已尝试的无效方案

  • 开启/关闭nuxt.config.js中的proxy配置
  • 重建Docker容器
  • 构建包含应用的镜像来创建容器(替代挂载卷+node:14镜像的方式)
  • 修改HOST、BASE_URL、BROWSER_BASE_URL为127.0.0.1、0.0.0.0、localhost、nodeserver
问题分析与解决方案

核心原因

  1. 静态模式不支持serverMiddleware:你的Nuxt配置target: 'static',但同时依赖serverMiddleware提供API服务,静态构建模式下Nuxt不会启动Node服务器,API路由无法生效,请求会被SPA fallback捕获返回HTML。
  2. 浏览器端地址解析错误:Docker内部的nodeserver主机名仅能在容器网络内识别,浏览器运行在宿主机环境无法解析该域名,导致请求异常。

修复步骤

1. 切换Nuxt运行模式

将nuxt.config.js中的target改为server,适配serverMiddleware的使用:

export default {
  target: 'server', // 替换原有的'static'
  // 其他配置保持不变
}

2. 修正环境变量配置

区分服务端和浏览器端的请求地址:

  • 服务端用Docker内部可识别的地址,浏览器端用宿主机可访问的地址
    修改.env文件:
HOST=0.0.0.0 # 让Nuxt监听所有网卡,容器内必须配置
BASE_URL=http://nodeserver:3000 # 服务端内部请求地址
BROWSER_BASE_URL=http://localhost:3000 # 浏览器端请求地址,对应宿主机端口映射

3. 调整serverMiddleware顺序

将session中间件放在API路由前面,确保请求先经过会话校验:

serverMiddleware: [
  {path: '/api', handler: '~/middleware/session.js'},
  {path: '/api', handler: '~/api'}
],

4. 重启Docker服务

执行命令重新启动容器:

docker-compose down
docker-compose up --build

验证

启动后访问http://localhost:3000尝试登录:

  • 查看Chrome网络请求,确认登录请求地址为http://localhost:3000/api/auth/login
  • 检查响应是否为JSON格式,而非HTML页面
  • 确认$auth.loginWith()能正常获取token并完成登录流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:25:43