Skip to content

Commit 7fa67e6

Browse files
[feat] update angular sample guide to add dhi example
1 parent 8a5b59f commit 7fa67e6

File tree

1 file changed

+71
-8
lines changed

1 file changed

+71
-8
lines changed

content/guides/angular/containerize.md

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ For consistency, please use the same responses shown in the example below when p
7777
| Question | Answer |
7878
|------------------------------------------------------------|-----------------|
7979
| What application platform does your project use? | Node |
80-
| What version of Node do you want to use? | 23.11.0-alpine |
80+
| What version of Node do you want to use? | 24.11.1-alpine |
8181
| Which package manager do you want to use? | npm |
8282
| Do you want to run "npm run build" before starting server? | yes |
8383
| What directory is your build output to? | dist |
@@ -114,19 +114,80 @@ These updates help ensure your app is easy to deploy, fast to load, and producti
114114
> A `Dockerfile` is a plain text file that contains step-by-step instructions to build a Docker image. It automates packaging your application along with its dependencies and runtime environment.
115115
> For full details, see the [Dockerfile reference](/reference/dockerfile/).
116116
117-
118117
### Step 2: Configure the Dockerfile
119118

120-
Copy and replace the contents of your existing `Dockerfile` with the configuration below:
119+
Before creating a Dockerfile, you need to choose a base image. You can either use the [Node.js Official Image](https://hub.docker.com/_/node) or a Docker Hardened Image (DHI) from the [Hardened Image catalog](https://hub.docker.com/hardened-images/catalog).
120+
121+
Choosing DHI offers the advantage of a production-ready image that is lightweight and secure. For more information, see [Docker Hardened Images](https://docs.docker.com/dhi/).
122+
123+
> [!IMPORTANT]
124+
> This guide uses a stable Node.js LTS image tag that is considered secure when the guide is written. Because new releases and security patches are published regularly, the tag shown here may no longer be the safest option when you follow the guide. Always review the latest available image tags and select a secure, up-to-date version before building or deploying your application.
125+
>
126+
> Official Node.js Docker Images: https://hub.docker.com/_/node
127+
128+
{{< tabs >}}
129+
{{< tab name="Using Docker Hardened Images" >}}
130+
Docker Hardened Images (DHIs) are available for Node.js on [Docker Hub](https://hub.docker.com/hardened-images/catalog/dhi/node). Unlike using the Docker Official Image, you must first mirror the Node.js image into your organization and then use it as your base image. Follow the instructions in the [DHI quickstart](/dhi/get-started/) to create a mirrored repository for Node.js.
131+
132+
Mirrored repositories must start with `dhi-`, for example: `FROM <your-namespace>/dhi-node:<tag>`. In the following Dockerfile, the `FROM` instruction uses `<your-namespace>/dhi-node:24-alpine3.22-dev` as the base image.
121133

122134
```dockerfile
123135
# =========================================
124136
# Stage 1: Build the Angular Application
125137
# =========================================
138+
139+
# Use a lightweight Node.js image for building (customizable via ARG)
140+
FROM <your-namespace>/dhi-node:24-alpine3.22-dev AS builder
141+
142+
# Set the working directory inside the container
143+
WORKDIR /app
144+
145+
# Copy package-related files first to leverage Docker's caching mechanism
146+
COPY package.json package-lock.json ./
147+
148+
# Install project dependencies using npm ci (ensures a clean, reproducible install)
149+
RUN --mount=type=cache,target=/root/.npm npm ci
150+
151+
# Copy the rest of the application source code into the container
152+
COPY . .
153+
154+
# Build the Angular application
155+
RUN npm run build
156+
157+
# =========================================
158+
# Stage 2: Prepare Nginx to Serve Static Files
159+
# =========================================
160+
161+
FROM <your-namespace>/dhi-nginx:1.28.0-alpine3.21-dev AS runner
162+
163+
# Copy custom Nginx config
164+
COPY nginx.conf /etc/nginx/nginx.conf
165+
166+
# Copy the static build output from the build stage to Nginx's default HTML serving directory
167+
COPY --chown=nginx:nginx --from=builder /app/dist/*/browser /usr/share/nginx/html
168+
169+
# Use a non-root user for security best practices
170+
USER nginx
171+
172+
# Expose port 8080 to allow HTTP traffic
173+
# Note: The default NGINX container now listens on port 8080 instead of 80
174+
EXPOSE 8080
175+
176+
# Start Nginx directly with custom config
177+
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
178+
CMD ["-g", "daemon off;"]
179+
```
180+
181+
{{< /tab >}}
182+
{{< tab name="Using the Docker Official Image" >}}
183+
184+
Now you need to create a production-ready multi-stage Dockerfile. Replace the generated Dockerfile with the following optimized configuration:
185+
186+
```dockerfile
126187
# =========================================
127188
# Stage 1: Build the Angular Application
128189
# =========================================
129-
ARG NODE_VERSION=24.7.0-alpine
190+
ARG NODE_VERSION=24.11.1-alpine
130191
ARG NGINX_VERSION=alpine3.22
131192

132193
# Use a lightweight Node.js image for building (customizable via ARG)
@@ -153,23 +214,22 @@ RUN npm run build
153214

154215
FROM nginxinc/nginx-unprivileged:${NGINX_VERSION} AS runner
155216

156-
# Use a built-in non-root user for security best practices
157-
USER nginx
158-
159217
# Copy custom Nginx config
160218
COPY nginx.conf /etc/nginx/nginx.conf
161219

162220
# Copy the static build output from the build stage to Nginx's default HTML serving directory
163221
COPY --chown=nginx:nginx --from=builder /app/dist/*/browser /usr/share/nginx/html
164222

223+
# Use a built-in non-root user for security best practices
224+
USER nginx
225+
165226
# Expose port 8080 to allow HTTP traffic
166227
# Note: The default NGINX container now listens on port 8080 instead of 80
167228
EXPOSE 8080
168229

169230
# Start Nginx directly with custom config
170231
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
171232
CMD ["-g", "daemon off;"]
172-
173233
```
174234

175235
> [!NOTE]
@@ -179,6 +239,9 @@ CMD ["-g", "daemon off;"]
179239
>- Aligns with Docker’s recommendations for container hardening
180240
>- Helps comply with stricter security policies in production environments
181241
242+
{{< /tab >}}
243+
{{< /tabs >}}
244+
182245
### Step 3: Configure the .dockerignore file
183246

184247
The `.dockerignore` file tells Docker which files and folders to exclude when building the image.

0 commit comments

Comments
 (0)