簡體   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