我正在构建一个 Web 应用程序,它应该在不同的 docker 容器上运行:
version: "3.8"
services:
backend:
build: ./backend
container_name: app-be
ports:
- 8000:8000
volumes:
- ./backend:/app
frontend:
build: ./frontend
container_name: app-fe
ports:
- 5173:5173
volumes:
- ./frontend:/app
test:
build: ./test
container_name: app-e2e
command: npx cypress run -b firefox
environment:
- CYPRESS_baseUrl=http://frontend:5173
tty: true
volumes:
- ./test:/app
前端是一个vuejs应用程序,我尝试通过axios访问后端;当启动一切时,该应用程序也会经过 cypress 的测试。但我也想在本地看到我的改变;这造成了我的问题:
为了从主机访问后端,axios 需要使用 http://localhost:8000 作为后端地址,但这样 Cypress 测试当然会失败;对于这些 axios 需要访问 http://backend:8000 ,这对于主机来说也是未知的。不过我希望两种情况都涵盖。
export default {
data() {
return { msg: '' };
},
methods: {
getMessage() {
axios.get('http://backend:8000/') // <-- change to localhost when running in browser
.then((res) => { this.msg = res.data; })
.catch((error) => { console.error(error);});
},
},
created() {
this.getMessage();
},
};
来自后端开发,我通常会使用根据环境获取的不同环境文件来解决类似的问题 - 但在这种情况下 axios 在客户端上作为 JavaScript 运行,所以这不能在服务器端解决,因为它是使用相同的服务器。当然,我们可以改变这一点 - 运行两个前端实例 - 一个用于 cypress 测试,另一个用于本地开发,并使用不同的环境变量启动它们,但这感觉有点脏。
另一个解决方法是将行
127.0.0.1 backend
添加到系统 /etc/hosts
,但我对这个解决方案也感觉不好;对我来说,使用 docker 的一个主要好处是让其他人只需下载项目并运行它,而无需在本地计算机上安装任何内容。需要 root 权限来更改基本的系统配置在某种程度上违背了这个想法。
所以我的问题: 有没有更好的方法来解决我没有看到的这个问题?或者这真的是唯一可用的两个选择吗?
所以我找到了一个我满意的更好的解决方案,感谢David Maze的评论,但它涉及更多的工作。
添加 nginx 代理后如所解释的,即
proxy:
build: ./proxy
container_name: app-prx
ports:
- 80:80
./proxy/
中引入新的 Dockerfile:
./proxy/default.conf
中引入新的nginx配置文件:
http://proxy/
并将前端对后端的调用从
http://backend:8000/
修复为
/api/
,项目实际上会在本地浏览器中显示正确的结果。然而,我的柏树测试失败并出现一条奇怪的消息:
指定了无效或非法的字符串事实证明,当在本地查看控制台时,您会收到一条更有用的消息:
Firefox 无法与位于 ws://localhost/ 的服务器建立连接。 未捕获(承诺中)DOMException:指定了无效或非法字符串 setupWebSocet client.ts:77 后备 client.ts: 42 (...) 我不知道为什么会发生这种情况,但是由于某种原因,在添加nginx时,vite需要在
vite.config.js
中指定一个websocket:
export default defineConfig({
plugins: [
vue(),
],
(...)
server: {
hmr: {
port: 5173
host: "localhost",
protocol: "ws",
},
},
})
NB:添加所有三个组件非常重要 - 我首先遗漏了端口,这导致了与之前相同的错误(因此我花了更长的时间才弄清楚这一点)。根据您启动前端的方式,这可能会导致新的错误:
端口 5173 正在使用中,请尝试另一个端口。 启动开发服务器时出错: 错误 [ERR_SERVER_ALREADY_LISTEN]:Listen 方法已被多次调用而未关闭。 在这种情况下,请确保您使用指定的端口显式启动前端。就我而言,我在前端的Dockerfile
末尾执行此操作:CMD [“npm”,“运行”,“dev”,“--”,“--主机”,“0.0.0.0”,“--端口”,“5173”] 对我来说,与我上面介绍的其他两种设置相比,这是一个更加优越的设置,原因有 4 个:
baseURL: 'http://backend:8000'
并将其导出到我的所有组件之前 - 不再需要了)。