Home Explore Blog CI



docker

2nd chunk of `content/guides/angular/containerize.md`
4b8a3fb9a154c4e2c1233c8d0d62e49ab21e419fd1ec016c0000000100000fe7
| Which package manager do you want to use?                  | npm             |
| Do you want to run "npm run build" before starting server? | yes             |
| What directory is your build output to?                    | dist            |
| What command do you want to use to start the app?          | npm run start   |
| What port does your server listen on?                      | 8080            |

After completion, your project directory will contain the following new files:

```text
├── docker-angular-sample/
│ ├── Dockerfile
│ ├── .dockerignore
│ ├── compose.yaml
│ └── README.Docker.md
```

---

## Build the Docker image

The default Dockerfile generated by `docker init` serves as a solid starting point for general Node.js applications. However, Angular is a front-end framework that compiles into static assets, so we need to tailor the Dockerfile to optimize for how Angular applications are built and served in a production environment.

### Step 1: Improve the generated Dockerfile and configuration

In this step, you’ll improve the Dockerfile and configuration files by following best practices:

- Use multi-stage builds to keep the final image clean and small  
- Serve the app using NGINX, a fast and secure web server  
- Improve performance and security by only including what’s needed  

These updates help ensure your app is easy to deploy, fast to load, and production-ready.

> [!NOTE]
> 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.  
> For full details, see the [Dockerfile reference](/reference/dockerfile/).


### Step 2: Configure the Dockerfile

Copy and replace the contents of your existing `Dockerfile` with the configuration below:

```dockerfile
# =========================================
# Stage 1: Build the Angular Application
# =========================================
# =========================================
# Stage 1: Build the Angular Application
# =========================================
ARG NODE_VERSION=22.14.0-alpine
ARG NGINX_VERSION=alpine3.21

# Use a lightweight Node.js image for building (customizable via ARG)
FROM node:${NODE_VERSION} AS builder

# Set the working directory inside the container
WORKDIR /app

# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json package-lock.json ./

# Install project dependencies using npm ci (ensures a clean, reproducible install)
RUN --mount=type=cache,target=/root/.npm npm ci

# Copy the rest of the application source code into the container
COPY . .

# Build the Angular application
RUN npm run build 

# =========================================
# Stage 2: Prepare Nginx to Serve Static Files
# =========================================

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

# Use a built-in non-root user for security best practices
USER nginx

# Copy custom Nginx config
COPY nginx.conf /etc/nginx/nginx.conf

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

# Expose port 8080 to allow HTTP traffic
# Note: The default NGINX container now listens on port 8080 instead of 80 
EXPOSE 8080

# Start Nginx directly with custom config
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
CMD ["-g", "daemon off;"]

```

> [!NOTE]
> We are using nginx-unprivileged instead of the standard NGINX image to follow security best practices.
> Running as a non-root user in the final image:
>- Reduces the attack surface
>- Aligns with Docker’s recommendations for container hardening
>- Helps comply with stricter security policies in production environments

### Step 3: Configure the .dockerignore file

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

> [!NOTE]
>This helps:
>- Reduce image size  
>- Speed up the build process  

Title: Building and Configuring the Docker Image for an Angular Application
Summary
This section details the process of building a Docker image for an Angular application, starting with tailoring the Dockerfile generated by `docker init`. It emphasizes using multi-stage builds for a smaller, cleaner image and serving the app with Nginx for performance and security. The steps include replacing the default Dockerfile content with a configuration that leverages a Node.js image for building and Nginx for serving static files. The configuration uses a non-root user for enhanced security. Additionally, the section describes configuring the `.dockerignore` file to exclude unnecessary files from the image, reducing its size and build time.