How to Dockerize a Docusaurus v2 application
Tags: docker, documentation, opensource
Published: 2022-03-08 14:46:31

Let's get started with the most basic [Docusaurus](https://docusaurus.io/docs) application.

## Getting started with Docusaurus
1. Create a new Docusaurus site
```
npx create-docusaurus@latest my-website classic
```

Your directory structure should look like this:

![Directory structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzsk43jvyqbgbu0ozbeh.png)

2. Start the site:
```
cd my-website
npx docusaurus start
```

3. Open `http://localhost:3000`. Once you see that your website is running locally you can close the server then proceed to the next section.

## Adding the Dockerfile

1. Add the `host` flag to the `start` and `serve` scripts in the `package.json` file

```diff
  "scripts": {
    "docusaurus": "docusaurus",
--  "start": "docusaurus start",
++  "start": "docusaurus start --host 0.0.0.0",
    "build": "docusaurus build",
    "swizzle": "docusaurus swizzle",
    "deploy": "docusaurus deploy",
    "clear": "docusaurus clear",
--  "serve": "docusaurus serve",
++  "serve": "docusaurus serve --host 0.0.0.0",
    "write-translations": "docusaurus write-translations",
    "write-heading-ids": "docusaurus write-heading-ids"
  },
```

2. Create a new file called `Dockerfile` in the root of the project

```docker
## Base ########################################################################
# Use a larger node image to do the build for native deps (e.g., gcc, python)
FROM node:lts as base

# Reduce npm log spam and colour during install within Docker
ENV NPM_CONFIG_LOGLEVEL=warn
ENV NPM_CONFIG_COLOR=false

# We'll run the app as the `node` user, so put it in their home directory
WORKDIR /home/node/app
# Copy the source code over
COPY --chown=node:node . /home/node/app/

## Development #################################################################
# Define a development target that installs devDeps and runs in dev mode
FROM base as development
WORKDIR /home/node/app
# Install (not ci) with dependencies, and for Linux vs. Linux Musl (which we use for -alpine)
RUN npm install
# Switch to the node user vs. root
USER node
# Expose port 3000
EXPOSE 3000
# Start the app in debug mode so we can attach the debugger
CMD ["npm", "start"]

## Production ##################################################################
# Also define a production target which doesn't use devDeps
FROM base as production
WORKDIR /home/node/app
COPY --chown=node:node --from=development /home/node/app/node_modules /home/node/app/node_modules
# Build the Docusaurus app
RUN npm run build

## Deploy ######################################################################
# Use a stable nginx image
FROM nginx:stable-alpine as deploy
WORKDIR /home/node/app
# Copy what we've installed/built from production
COPY --chown=node:node --from=production /home/node/app/build /usr/share/nginx/html/
```

### Working with Docker container in development

3. To build the Docker container for development, run

```
docker build --target development -t docs:dev .
```

4. To run the Docker container in development, run

```
docker run -p 3000:3000 docs:dev
```

Note: Remember to stop the container before proceeding to the next step

### Working with Docker container in production
5. To build the Docker container for production, run

```
docker build -t docusaurus:latest .
```

6. To run the Docker container in production, run

```
docker run --rm -p 3000:80 docusaurus:latest
```