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

Docker容器中next/image组件加载不稳定问题求助

NextJS图片优化+Docker跨容器图片访问问题解决方案

给你几个不用host网络、又能保留Next图片优化的可行方案:

方案一:容器间直接通信+Next远程域名白名单

  • 先确保你的Strapi(api容器)和NextJS(frontend容器)在同一个Docker网络里(默认bridge网络或者自定义网络都行),这样容器名可以直接当域名用。
  • 修改NextJS的next.config.js,把Strapi容器的地址加入图片远程访问白名单,同时把图片基础URL改成容器间可访问的地址(比如你的Strapi容器名叫strapi-api,就用http://strapi-api:1337/uploads/):
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      images: {
        remotePatterns: [
          {
            protocol: 'http',
            hostname: 'strapi-api',
            port: '1337',
            pathname: '/uploads/**',
          },
        ],
      },
    };
    
    module.exports = nextConfig;
    
  • 原理:Next服务端(frontend容器)直接从Strapi容器拉取原图做优化,客户端只会请求Next生成的优化后图片地址,完全不会碰host.docker.internal,从根源避免客户端访问失败的问题。

方案二:自定义图片代理接口

  • 在NextJS里写一个代理接口,所有图片请求先经过这个接口转发到Strapi,确保全部走Next的优化流程:
    1. 如果用Pages Router,新建pages/api/proxy-image.js:
      import axios from 'axios';
      import { pipeline } from 'stream/promises';
      
      export default async function handler(req, res) {
        const { filename } = req.query;
        if (!filename) return res.status(400).send('缺少文件名');
      
        try {
          const strapiRes = await axios.get(`http://strapi-api:1337/uploads/${filename}`, {
            responseType: 'stream',
          });
      
          res.setHeader('Content-Type', strapiRes.headers['content-type']);
          await pipeline(strapiRes.data, res);
        } catch (err) {
          res.status(404).send('图片不存在');
        }
      }
      
    2. 如果用App Router,新建app/api/proxy-image/route.js:
      import axios from 'axios';
      import { NextResponse } from 'next/server';
      import { pipeline } from 'stream/promises';
      
      export async function GET(request) {
        const { searchParams } = new URL(request.url);
        const filename = searchParams.get('filename');
        if (!filename) return NextResponse.json({ error: '缺少文件名' }, { status: 400 });
      
        try {
          const strapiRes = await axios.get(`http://strapi-api:1337/uploads/${filename}`, {
            responseType: 'stream',
          });
      
          const response = new NextResponse(strapiRes.data);
          response.headers.set('Content-Type', strapiRes.headers['content-type']);
          return response;
        } catch (err) {
          return NextResponse.json({ error: '图片不存在' }, { status: 404 });
        }
      }
      
    3. 把图片的基础URL改成/api/proxy-image?filename=,所有图片都会通过这个代理走Next的优化流程,客户端只和NextJS通信。

方案三:NextJS路径重写+反向代理

  • 用NextJS的rewrite功能,把前端的/uploads路径直接转发到Strapi容器,这样图片URL可以直接写/uploads/xxx.ext,完全不用关心跨容器的问题:
    1. 先安装http-proxy-middleware依赖:npm install http-proxy-middleware
    2. 修改next.config.js:
      const nextConfig = {
        images: {
          domains: ['localhost'], // 填你的前端访问域名,比如localhost:3000
        },
        async rewrites() {
          return [
            {
              source: '/uploads/:path*',
              destination: 'http://strapi-api:1337/uploads/:path*',
            },
          ];
        },
      };
      
      module.exports = nextConfig;
      
  • 原理:NextJS会自动把/uploads开头的请求转发到Strapi获取原图,然后进行优化,客户端看到的始终是Next处理后的图片地址,不会直接请求Strapi容器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:52:25