繁体   English   中英

使用 Docker 和 NGINX 部署 NextJS 应用程序,以便我可以拥有自定义基本路径

[英]NextJS app deploying using Docker and NGINX so I can have a custom base path

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

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

我正在使用以下博客中有关如何使用 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
    },
});    

“码头档案”

...    
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;
}

我的理解是这些规则意味着一个 url

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 页。

为什么这不起作用?

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

请参阅这篇文章中的答案,其中对解决方案进行了全面的解释: https : //stackoverflow.com/a/60952373/2663916

总结如下。

对于问题 1:公共图像

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

下一个.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 并在我构建和运行我的应用程序时在环境中设置了该值,并使用此路径使用反向代理时,样式表将被正确选取。

查看链接的stackoverflow答案

对于问题 2

这似乎是 NGINX 配置。

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

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

或者根本不使用变量

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM