NextJS应用程序是使用Docker和NGINX部署的,因此我可以使用自定义基本路径

时间:2020-03-25 12:42:44

标签: docker nginx next.js

我创建了一个可以在本地完美运行的应用程序,现在我需要在具有自定义基本路径的服务器上进行部署。我的应用程序正在部署到一个Docker容器中,在那里我有第二个Docker容器,其中NGINX做反向代理。

我在网上看到了很多博客/查询/解决方案,而三周后,我仍然无法接近任何工作。我尝试使用“快速”包装我的应用程序,但是遇到阻塞问题

我正在使用以下博客中有关如何使用assetPrefix的信息:

我的项目结构

|- .next
|- client
     |- polyfills.js
|- components
     |- Link.tsx
     |- etc
|- node-modules
     |- ...
|- pages
     |- index.js
     |- page1.js
     |- page2.js
     |- etc
|- public
     |- appIcon.png
|- scripts
     |- utils.js
|- stylesheets
     |- main.css
|- next.config.js
|- package-lock.json
|- package.json

在我的应用中如何使用静态图像的示例

<img className="my-images" src="/appIcon.png" alt="App Icon"/>

如何使用样式表的示例

import "../stylesheets/main.css";

“ next.config.cs”

const withCSS = require("@zeit/next-css");
module.exports = withCSS();

module.exports = withCSS({
    assetPrefix: process.env.BASE_PATH || '',

    publicRuntimeConfig: {
        basePath: process.env.BASE_PATH || '',
    },

    webpack: function(cfg) {
        const originalEntry = cfg.entry
        cfg.entry = async () => {
            const entries = await originalEntry()
            if (entries['main.js'] &&
                !entries['main.js'].includes('./client/polyfills.js')
            ) {
                entries['main.js'].unshift('./client/polyfills.js')
            }
            return entries
        }
        return cfg
    },
});    

“ DockerFile”

...    
COPY package*.json ./
...
RUN --mount=type=ssh npm install
...
COPY .next .next/
COPY next.config.js  ./
...
ENV BASE_PATH=a/b 
CMD [ "./node_modules/.bin/next", "start", "-p", "8080"]

我的NGINX规则是

location = /a/b/ {
    set $upstream http://mysite:8080/;
    proxy_pass $upstream;
}
location /a/b/ {  
    set $upstream http://mysite:8080/;
    proxy_pass $upstream;
}

据我了解,这些规则意味着一个网址

Link.tsx:覆盖默认链接以将basePath作为前缀

import NextLink, { LinkProps } from 'next/link'
import { format } from 'url'
import getConfig from 'next/config'

const { publicRuntimeConfig } = getConfig()

const Link: React.FunctionComponent<LinkProps> = ({ children, ...props }) => (
    <NextLink
        {...props}
        as={`${publicRuntimeConfig.basePath || ''}${format(props.href)}`}
    >
        {children}
    </NextLink>
)

export default Link

我如何使用链接的示例

import Link from "./Link.tsx";
....
<Link href="/page1">  

问题1:资产似乎未加载

我可以使用以下命令访问我的应用:http://host/a/b/

但是没有加载任何静态文件,即找不到“ appIcon.png”,样式表“ main.css”也找不到

问题2:无法访问“索引”以外的页面

当我尝试使用URL访问任何其他页面均不起作用时,总是显示索引页面

例如

"http://host/a/b/page1" 

应显示page1,但不显示。显示索引页面。据我了解,NGINX规则只会删除/ a / b /部分,因此应调用

"http://host/page1" 

并显示第1页。

为什么这不起作用?

任何人都可以告诉我如何使这一切正常工作。

1 个答案:

答案 0 :(得分:0)

请参阅此帖子中的答案,其中对该解决方案进行了详细说明:https://stackoverflow.com/a/60952373/2663916

摘要如下。

对于问题1:公开图片

我使用了“ next-images”包,以便在我的组件中可以导入图像并引用导入的图像。

next.config.js

const withCSS = require("@zeit/next-css");
const withImages = require('next-images');

module.exports = withCSS(withImages({
   ....
}));

在我的组件中导入图像

import img1 from '../public/image_name1.png'
import img2 from '../public/image_name2.png'

在src属性中引用导入的对象

<img src={img1} alt="image_name1"/>

对于问题1:样式表

当我在“ next.config.js”中正确设置assetPrefix并在构建和运行应用程序时在环境中设置了值,并使用此路径使用了反向代理时,便可以正确拾取样式表。 / p>

查看链接的stackoverflow答案

对于问题2

这似乎是NGINX配置。

在该位置使用变量时,必须确保在路径上传递 例如

location ~ /a/b/(.*)$ {  
    set $upstream http://myhost:8080/$1;
    proxy_pass $upstream;
}

或者根本不使用变量

location /a/b/ {
    proxy_pass http://myhost:8080/;
}