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
问题分析与解决方案
核心原因
- 静态模式不支持serverMiddleware:你的Nuxt配置
target: 'static',但同时依赖serverMiddleware提供API服务,静态构建模式下Nuxt不会启动Node服务器,API路由无法生效,请求会被SPA fallback捕获返回HTML。 - 浏览器端地址解析错误: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
相关产品推荐
相关产品推荐

