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

2020-03-25 docker nginx next.js

I have created an application that is working perfectly locally and now I need to deploy on a server with a custom base path. My app is being deployed to a Docker Container where I have a second Docker Container with NGINX doing reverse proxy.

I have seen lots of blogs/queries/solutions online and after 3 weeks i am still no closer in getting anything to work. I have tried using "Express" wrapping my app but I encountered blocking issues

I am using the information in the following blog as to how to use assetPrefix :

My project structure

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

Example of how static images are being used in my app

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

Example of how style sheet is being used

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


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'] &&
            ) {
            return entries
        return cfg


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

my NGINX rule is

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

It is my understanding that these rules means that a url

Link.tsx : overwriting default links to have the basePath as the prefix

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 }) => (
        as={`${publicRuntimeConfig.basePath || ''}${format(props.href)}`}

export default Link

Example of how i am using the link

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

ISSUE 1 : assets do not appear to be loading

I can access my app with the following : http://host/a/b/

However NONE of the static files are loaded, i.e. "appIcon.png" is not found neither is the stylesheet "main.css"

ISSUE 2 : pages other than "index" are not accessible

When I try and access any other page using the URL it does not work, the index page is always shown

For example


should show page1, but it does not. The index page is shown. It is my understanding that the NGINX rules would remove ONLY the /a/b/ part therefore it should call through to


and show the page1.

Why is this not working?

Can anyone please advise me how to get this all working.


See the answer in this post which has a comprehensive explanation of the solution:

A summary is below.

For Issue 1 : public images

I used "next-images" package so that in my components i could import the image and reference the imported image.


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

module.exports = withCSS(withImages({

In my component import the images

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

reference the imported object in the src attribute

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

For Issue 1 : stylesheets

When i set the assetPrefix in "next.config.js" correctly and had the value set in the environment when i built and run my application, and have the reverse proxy using this path then the stylesheets are picked up correctly.

See the linked stackoverflow answer

For Issue 2

This appears to be an NGINX configuration.

When using a variable in the location you have to make sure you pass on the paths for example

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

or don't use a variable at all

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