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

Docker Compose部署应用时获取容器图片出现CORS错误原因咨询

容器化部署NextJS博客后出现CORS问题排查

我有一个NextJS前端博客应用,从独立的animations API获取图片和视频。本地运行(前端localhost:3000,API localhost:8001)时一切正常,图片可正常渲染,但使用Docker Compose容器化部署后出现CORS问题。

相关配置

docker-compose.yaml

version: '3.8'
services:
  blog-app:
    build:
      context: . # <-- ENSURES REBUILD EVERY TIME
      dockerfile: Dockerfile
    environment:
      - ANIMATION_URL=http://animation-app:5000 # <-- RELEVANT
      - MARKDOWN_URL=http://markdown-app:5000
      - AVATARS_URL=https://avatars.githubusercontent.com
  nginx:
    image: jdev9487/blog-proxy-server:latest
    depends_on:
      - blog-app
    ports:
      - '443:443'
      - '80:80'
    volumes:
      - ./.nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
  animation-app: # <-- RELEVANT
    image: jdev9487/math-blog-animations:latest
    ports:
      - '8001:5000'
  markdown-app:
    image: jdev9487/blog-markdown:latest
    ports:
      - '8000:5000'

前端fetch调用代码

"use client";

import Link from "next/link";
import Avatar from '@mui/material/Avatar';
import { PostMetadata } from "./postMetadata";
import ShareIcon from '@mui/icons-material/Share';
import { useEffect, useState } from "react";

export default function PostPreview(props: PostMetadata) {

    const [img, setImg] = useState('')
    useEffect(() => {
        const fetchData = async () => {
            const url = `${props.animationUrl}/thumbnails/${props.featuredAnimation}`;
// props.animationUrl gets populated from env variables in compose.yaml
            var res = await fetch(url);
            var blob = await res.blob();
            var blobUrl = URL.createObjectURL(blob);
            setImg(blobUrl);
        }
        fetchData();
    }, []);

    return (
        <div className="flex flex-row border border-background-secondary shadow min-h-80">
            <div className="flex basis-1/2">
                <img id="thumbnail" className="object-cover" src={img} />

Flask Animations API代码

from flask import Flask
from flask import send_file
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.get("/animations/<slug>")
def animation(slug):
    filename = f'output/{slug}.mp4'
    return send_file(filename, mimetype='image/mp4')

@app.get("/thumbnails/<slug>") # <-- this is the endpoint being called
def thumbnail(slug):
    filename = f'output/{slug}.png'
    return send_file(filename, mimetype='image/png')

if __name__ == "__main__":
    app.run()

浏览器报错信息

Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
http://animation-app:5000/thumbnails/completingTheSquare. (Reason:
CORS request did not succeed). Status code: (null)

问题原因

  1. 浏览器无法解析Docker内部服务名:前端代码在浏览器中执行,请求的http://animation-app:5000是Docker Compose内部的服务域名,浏览器无法识别这个地址,导致请求根本无法到达API服务器,CORS配置自然无法生效。报错中的"Status code: (null)"也验证了这一点——请求连连接都没建立。
  2. 本地与容器化环境的差异:本地运行时用localhost:8001作为API地址,浏览器能正常解析localhost并发起请求;容器化后错误地将前端的API地址配置为Docker内部服务地址,导致跨域问题(本质是请求无法到达)。

解决方案

方案1:通过Nginx反向代理转发API请求(推荐)

利用已有的Nginx作为反向代理,将前端的API请求转发到内部的animation-app服务,避免浏览器直接访问内部地址:

  • 修改Nginx配置文件(.nginx/default.conf),添加以下路由规则:
location /api/animations/ {
    proxy_pass http://animation-app:5000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}
  • 更新docker-compose.yaml中blog-app的环境变量:
ANIMATION_URL=/api/animations

这样前端请求会先发送到Nginx,再由Nginx转发到内部的animation-app,既避免了跨域问题,又不需要暴露API的端口。

方案2:将请求移到NextJS服务器端执行

NextJS支持服务器组件,可以把fetch图片的逻辑放到服务器组件中,服务器端可以直接访问Docker内部的服务地址,然后将图片数据传递给客户端渲染:

  • 将PostPreview改为服务器组件(去掉"use client"指令),在组件内部直接执行fetch逻辑,然后将图片转换为Base64格式或者直接传递Blob数据给客户端。

方案3:调整API地址并显式配置CORS

如果需要浏览器直接访问API,可以:

  • 将blog-app的环境变量ANIMATION_URL改为服务器的公网IP/域名加上映射的端口8001,比如http://your-server-ip:8001
  • 显式配置Flask的CORS允许你的博客域名:
CORS(app, origins=["https://your-blog-domain.com", "http://localhost:3000"])

这种方式需要暴露API端口,安全性不如代理方式,不推荐生产环境使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:33:17