How to deploy a Docusaurus website to K8s
Tags: kubernetes, devops, documentation
Published: 2021-08-04 13:18:03

---
canonical_url: https://www.albertosadde.com/blog/how-to-deploy-a-docusaurus-website-to-k8s
---

First, let me give you a bit of background.  

At my company we're looking for a way to create and share internal documentation with a git and Markdown-based documentation service.  

The reasons behind these choices are that (1) Markdown is simple to use and all the developers know how to use it; and (2) a git-based service will help us track documentation changes and agree on improvements by using pull requests and "doc reviews" before merging any changes.  

After some searching around we decided to go with [Docusaurus]() a static documentation site generator created by Facebook.  

We really enjoy it since it is based in React Native and once things are set up it is very easy to submit a new doc page or make changes.  

But when we first started using it we found ourselves with a deployment issue. We wanted to keep the documentation private and didn't want to use any of the services that the docusuarus team propose (Netlify, GitHub Pages, etc.). Instead, we decided to host it on our own "dev" Kubernetes cluster so that we could access it via our proxy and VPN.  

I didn't find any information on how to do this online, so here are the steps I followed in case you find yourself with the same issue:  

## Deployment Steps  
  - I'll assume that you already have a docusuarus website that you can run locally using `yarn, yarn build, yarn serve` (or their `npm` equivalents).  
  - With that out of the way you'll just need to build a docker image:  

```javascript
FROM node:12.19.0-alpine

WORKDIR /app

COPY . /app

RUN yarn

RUN yarn build

ENTRYPOINT ["yarn", "run", "serve"]
```  
- Push the new image to your preferred docker registry  
- And finally apply a k8s deployment to your cluster. Save and adjust the below `yaml` and then simply run `kubectl apply -f deployment.yaml`  

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ms-docs
spec:
  selector:
    matchLabels:
      app: ms-docs
  template:
    metadata:
      labels:
        app: ms-docs
    spec:
      containers:
      - name: ms-docs
        envFrom:
        - configMapRef:
            name: ms-docs
        image: my-registry/ms-docs:stable
        imagePullPolicy: Always
        livenessProbe:
          failureThreshold: 15
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 20
          periodSeconds: 15
          timeoutSeconds: 5
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 15
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 20
          periodSeconds: 15
          timeoutSeconds: 5
        resources:
          limits:
            cpu: "500m"
            memory: 384Mi
          requests:
            cpu: "500m"
            memory: 384Mi
---
apiVersion: v1
kind: Service
metadata:
  name: ms-docs
spec:
  ports:
  - name: http
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: ms-docs
  type: ClusterIP
```