Package Tutorial Web UI#
Setup for Static Output#
By default, the Next.js* framework creates a server-side rendered application. For the Tutorial Web UI you want the output to be static files that can be served by a web server. You will use NGINX* web server for this.
To do this, you need to set the output option in the next.config.ts file to export.
const nextConfig = {
output: 'export',
}
This will allow us to use the npx next build command to create the production ready static files in the Dockerfile.
Create a Dockerfile#
Similar to the Tutorial Server, the Tutorial Web UI application needs to be packaged in a Container image.
You want it to serve the static files from the Next.js application, but want the Node.js* server available to minify these files in the first place. You do not need to have the Node.js server running in the final image, so use a multi-stage build to create the final image.
The first stage will build the application and the second stage will copy the results into a minimal NGINX image.
Note
The NGINX image is much smaller than the Node.js image, and so the final image will be smaller. You should only take base images from reputable sources.
Add the following to a Dockerfile in the tutorial-web-ui directory.
# Stage 1: Build the application
FROM node:22 AS build
WORKDIR /app
COPY package.json package-lock.json next-env.d.ts postcss.config.mjs tsconfig.json next.config.ts ./
RUN npm install
COPY app app
COPY public public
RUN npx next build
# Stage 2: Serve the application
FROM nginxinc/nginx-unprivileged:alpine-perl
EXPOSE 8080
USER nginx
COPY --from=build /app/out /usr/share/nginx/html
Build the Container Image#
Build the Container image using the Dockerfile.
docker build --platform=linux/amd64 -t tutorial-web-ui-image .
Examining the Container image shows it is 1/10th the size of the Tutorial Server image, because you used a multi-stage build.
~ $ docker images | grep "tutorial.*image"
tutorial-web-ui-image latest 979019e086eb 47 minutes ago 87.2MB
tutorial-server-image latest 16bc7692277d 50 minutes ago 563MB
Test the Container Image#
docker run -p 8080:8080 tutorial-web-ui-image
Open your web browser to http://localhost:8080 to see the default page.
The Tutorial Web UI application is now running in a Container image, but is not yet connected to the Tutorial Server.
In the development stage, you had a special mapping that pointed to the API at http://localhost:8000. This is not available in the final image, and are in production mode, so it expects to access the API at the same URL from which the HTML, CSS, and JavaScript* files are served.
You will see how to set this up in the next section.
Note
This is a security feature of modern browsers to prevent cross-site scripting.
Understand the Container Image#
Similar to the Tutorial Server, you can jump into this container image to inspect it.
docker run -it --platform=linux/amd64 --entrypoint /bin/sh tutorial-web-ui-image
Running commands in this shows that the base container is based on the Alpine Linux* distribution.
~ $ cat /etc/issue
Welcome to Alpine Linux 3.21
Kernel \r on an \m (\l)
~ $ uname -a
"Linux 2337e849911f 6.10.14-linuxkit #1 SMP Fri Nov 29 17:22:03 UTC 2024 x86_64 Linux"
~ $ ls /usr/share/nginx/html
404.html 50x.html _next favicon.ico file.svg globe.svg index.html index.txt next.svg vercel.svg window.svg
~ $ ls /etc/nginx/conf.d/default.conf
/etc/nginx/conf.d/default.conf
~ $ nginx -V
nginx version: nginx/1.27.4
built by gcc 14.2.0 (Alpine 14.2.0)
built with OpenSSL 3.3.2 3 Sep 2024 (running with OpenSSL 3.3.3 11 Feb 2025)
TLS SNI support enabled
...
~ $ whoami
nginx
~ $