Deploying Docusaurus with Docker
What is Docusaurus?
Docusaurus is an open-source static site generator built by Facebook. It is designed for documentation websites, blogs, and knowledge bases. Docusaurus uses Markdown for content creation and provides a React-based frontend.
Key Components of Docusaurus
Docusaurus consists of several components that make it easy to build and maintain a documentation site.
1. docs/
(Documentation Pages)
- Stores Markdown files for your documentation.
- Each
.md
file in this directory becomes a documentation page. - The navigation order is controlled by
sidebars.js
.
2. blog/
(Blog Posts)
- Contains Markdown blog posts (
YYYY-MM-DD-title.md
). - Docusaurus automatically generates a blog listing page.
3. static/
(Static Assets)
- Stores images, CSS, JavaScript, and other static files.
- These files are directly accessible via the
/
URL path.
4. src/
(Custom React Components)
- Used for adding custom React components to enhance documentation.
- Contains custom pages (
src/pages/
) and UI enhancements.
5. docusaurus.config.js
(Configuration File)
- The main configuration file for site settings, themes, and plugins.
- Defines the site title, URL, navbar, footer, and more.
6. sidebars.js
(Sidebar Navigation)
- Controls the navigation structure of the documentation.
- Organizes docs into categories and sections.
Docusaurus Build Process
To create a new Docusaurus project:
npx create-docusaurus@latest my-website classic
cd my-website
npm install
The process of containerizing and deploying your Docusaurus project to Google Compute Engine (GCE) involves the following steps:
Containerize the Docusaurus Project
- Create a Dockerfile.
- Build a Docker image.
- Test the container locally.
Push the Docker Image to Google Container Registry (GCR)
- Tag and push the image to Google Container Registry.
- Deploy the Container on Google Compute Engine (GCE)
Install Docker on the VM.
- Pull and run the container.
- Expose it via Nginx or a firewall rule.
Detailed Steps
Containerize the Docusaurus Project
Ensure your Docusaurus project is built
npm install
npm run build
Create a Dockerfile in your project root.
What is a Dockerfile?
A Dockerfile is a text file that contains a set of instructions to build a Docker image. It automates the process of creating a container by specifying:
- The base image (e.g., node:18-alpine for a Node.js-based app like Docusaurus)
- Dependencies to install
- Commands to run
- Ports to expose
- The application’s startup command
How to Create a Dockerfile To create a Dockerfile for your Docusaurus project, follow these steps:
-
Step 1: Navigate to Your Docusaurus Project Root
Open a terminal and change into your project directory:
cd /path/to/your/docusaurus-project
-
Step 2: Create the Dockerfile Run the following command:
touch Dockerfile
This creates an empty file named Dockerfile in your project directory.
-
Step 3: Open the Dockerfile and Add the Following Content Open the file in a text editor (nano, vim, or VS Code):
nano Dockerfile
Then, add the following lines:
# Use a lightweight Node.js image as the base
FROM node:18-alpine
# Set the working directory
WORKDIR /app
# Copy package.json and install dependencies
COPY package.json package-lock.json ./
RUN npm install --omit=dev
# Copy the rest of the Docusaurus files
COPY . .
# Build the Docusaurus static site
RUN npm run build
# Expose port 3000
EXPOSE 3000
# Start the Docusaurus server
CMD ["npm", "run", "serve"]
Understanding the Dockerfile
Line | Explanation |
---|---|
FROM node:18-alpine | Uses a lightweight Node.js image as the base. |
WORKDIR /app | Sets /app as the working directory inside the container. |
COPY package.json package-lock.json ./ | Copies package files to install dependencies. |
RUN npm install --omit=dev | Installs dependencies without modifying package-lock.json . |
COPY . . | Copies all Docusaurus project files into the container. |
RUN npm run build | Builds the static Docusaurus site. |
EXPOSE 3000 | Tells Docker that the app will run on port 3000. |
CMD ["npm", "run", "serve"] | Starts the Docusaurus web server inside the container. |
- Build the Docker Image
docker build -t docusaurus-site .
- Test Locally
docker run -p 3000:3000 docusaurus-site
1. Difference Between EXPOSE and -p 3000:3000
Command | Purpose |
---|---|
EXPOSE 3000 (in Dockerfile) | Documentation-only. Tells Docker that the container listens on port 3000 but does not automatically map it to the host machine. |
docker run -p 3000:3000 | Maps port 3000 in the container to port 3000 on the host machine, making it accessible from the browser. |
2. Why Do We Need to Specify the Port Twice?
The syntax:
docker run -p 3000:3000 docusaurus-site
Maps the container's internal port (3000) to an external port (3000) on the host.
- First 3000 (Host Port) → The port you use to access the app (e.g., http://localhost:3000).
- Second 3000 (Container Port) → The port exposed inside the container (where the app is running).
You can also map it to a different host port, for example:
docker run -p 8080:3000 docusaurus-site
Now, the app inside the container still runs on port 3000, but you can access it at http://localhost:8080
3. When is EXPOSE Useful?
- It’s helpful when using Docker networking (e.g., linking multiple containers).
- Some cloud services (like AWS ECS) detect EXPOSE ports for automatic mappings.
- But for local development, you must use -p to expose it to your machine.
Explaining npm start
or npm run start
When you run:
npm start
or
npm run start
Docusaurus does the following:
1. Looks for the start script inside package.json:
"scripts": {
"start": "docusaurus start"
}
This means npm start executes:
docusaurus start
2. Launches the Docusaurus Development Server:
- Starts a local development server using Express.js.
- Watches for Markdown and config file changes and hot-reloads them.
- Serves the website at http://localhost:3000/ (default port).
3. Keeps the Process Running:
- The server keeps running as long as the terminal is open.
- If you close the terminal, the server stops.
Difference Between npm start and npm run start
Command | Difference |
---|---|
npm start | A shortcut for npm run start, but it only works if "start" is defined in package.json. |
npm run start | The recommended way to run scripts. Always works, even for custom scripts. |
For example, if package.json contains:
"scripts": {
"dev": "docusaurus start"
}
- Running
npm start
will fail because start is not defined. - Running
npm run
dev will work.
Running Docker as a Background Process
When you run:
docker run -p 3000:3000 docusaurus-site
- The container runs in the foreground (attached to your terminal).
- If you close the terminal, the container stops.
Solution: Run Docker in the Background (-d mode)
docker run -d -p 3000:3000 docusaurus-site
- The -d flag (--detach) makes Docker run in the background.
- The container keeps running even if you close the terminal.
Check Running Containers To verify that the container is running:
docker ps
This lists all active containers.
Stopping the Container
To stop the running container, find its CONTAINER ID using docker ps, then run:
docker stop <CONTAINER_ID>
Restarting a Stopped Container Find the container ID using:
docker ps -a
Then restart it:
docker start <CONTAINER_ID>
Automatically Restart on System Reboot If you want the container to start automatically after a reboot:
docker run -d --restart unless-stopped -p 3000:3000 docusaurus-site
- --restart unless-stopped ensures it restarts unless manually stopped.
Breaking Down npm start
Execution
When you run:
npm start
or
npm run start
the process works in two steps:
Step 1: npm Executes the Script
npm
looks insidepackage.json
for a script named"start"
, like this:"scripts": {
"start": "docusaurus start"
}npm
then launches the command in the"start"
script, which in this case is:docusaurus start
- This means npm itself does NOT start the web server; it just acts as a task runner, executing whatever is defined in
package.json
.
Step 2: Docusaurus Takes Over
- Once
npm
starts thedocusaurus start
command, Docusaurus itself takes over and:- Launches an Express.js-based local development server.
- Watches for changes to Markdown files.
- Serves the website at
http://localhost:3000/
.
Analogy: npm as a Conductor, Docusaurus as the Orchestra
- npm is only responsible for finding and executing the script inside
package.json
. - Docusaurus is responsible for:
- Starting the web server
- Handling Markdown files
- Rendering the UI
So, while npm initiates the process, Docusaurus is the one actually running the web application.
Think of npm start
as a conductor starting an orchestra:
- npm = The conductor (tells the musicians what to play).
- Docusaurus = The orchestra (actually performs the music).
- Web Server = The sound you hear.
The conductor npm
does not make the music; it just starts the musicians Docusaurus
, who do the actual work.
Summary
npm start
**only triggers the script defined in package.json.docusaurus start
**is the command that actually runs the web server.- npm does not start the web server. Docusaurus does.