├── .github └── workflows │ └── buildx.yml ├── Dockerfile ├── LICENSE ├── README.md ├── config ├── auto_update_crontab.txt ├── auto_update_job.sh ├── init.sh ├── run.sh └── supervisord.conf └── docs └── docusaurus2_homepage.png /.github/workflows/buildx.yml: -------------------------------------------------------------------------------- 1 | name: buildx 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | buildx: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | - name: Set up QEMU 13 | uses: docker/setup-qemu-action@v1 14 | with: 15 | platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 16 | - name: Set up Docker Buildx 17 | uses: docker/setup-buildx-action@v1 18 | - name: Login to Docker Hub 19 | uses: docker/login-action@v1 20 | with: 21 | username: ${{ secrets.DOCKERHUB_USERNAME }} 22 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 23 | - name: Build and push 24 | uses: docker/build-push-action@v2 25 | with: 26 | context: . 27 | file: ./Dockerfile 28 | platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 29 | tags: ${{ secrets.DOCKERHUB_USERNAME }}/docusaurus:latest 30 | push: true 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20-alpine3.17 2 | LABEL maintainer="Deokgyu Yang " \ 3 | description="Lightweight Docusaurus container with Node.js based on Alpine Linux" 4 | 5 | RUN apk add --no-cache \ 6 | bash bash-completion supervisor \ 7 | autoconf automake build-base libtool nasm 8 | 9 | # Environments 10 | ENV TARGET_UID=1000 11 | ENV TARGET_GID=1000 12 | ENV AUTO_UPDATE='true' 13 | ENV WEBSITE_NAME='MyWebsite' 14 | ENV TEMPLATE='classic' 15 | ENV RUN_MODE='development' 16 | 17 | # Create Docusaurus directory and change working directory to that 18 | RUN mkdir /docusaurus 19 | WORKDIR /docusaurus 20 | 21 | # Copy configuration files 22 | ADD config/init.sh / 23 | ADD config/auto_update_crontab.txt / 24 | ADD config/auto_update_job.sh / 25 | ADD config/run.sh / 26 | COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf 27 | 28 | # Set files permission 29 | RUN chmod a+x /init.sh /auto_update_job.sh /run.sh 30 | 31 | EXPOSE 80 32 | VOLUME [ "/docusaurus" ] 33 | ENTRYPOINT [ "/init.sh" ] 34 | 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2021 Deokgyu Yang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | MIT License 24 | 25 | Copyright (c) Facebook, Inc. and its affiliates. 26 | 27 | Permission is hereby granted, free of charge, to any person obtaining a copy 28 | of this software and associated documentation files (the "Software"), to deal 29 | in the Software without restriction, including without limitation the rights 30 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 31 | copies of the Software, and to permit persons to whom the Software is 32 | furnished to do so, subject to the following conditions: 33 | 34 | The above copyright notice and this permission notice shall be included in all 35 | copies or substantial portions of the Software. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 43 | SOFTWARE. 44 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-docusaurus 2 | 3 | ![](https://img.shields.io/badge/multiarch-amd64(x86__64)%2C%20arm64%2C%20armv7%2C%20armv6-lightgrey?style=flat-square) 4 | ![](https://img.shields.io/github/actions/workflow/status/awesometic/docker-docusaurus/buildx.yml?branch=master?style=flat-square) 5 | 6 | ![](https://img.shields.io/docker/image-size/awesometic/docusaurus/latest?style=flat-square) 7 | ![](https://img.shields.io/docker/pulls/awesometic/docusaurus?style=flat-square) 8 | ![](https://img.shields.io/docker/stars/awesometic/docusaurus?style=flat-square) 9 | 10 | ## What is Docusaurus 11 | 12 | I'd like to quote the [official website](https://docusaurus.io/). 13 | > Docusaurus makes it easy to maintain Open Source documentation websites. 14 | 15 | ## What this project provided for 16 | 17 | I hope this project would be useful for those who uses docker for building their server. 18 | 19 | ## Features 20 | 21 | ### Core packages 22 | 23 | I chose Alpine Linux for make it a **light-weight** service. 24 | And I did choose node-alpine as its base image for the sake of some tweaks of Node.js version. 25 | 26 | So this is composed of, 27 | 28 | * Alpine Linux 3.17 29 | * Node.js 20.2.0 30 | 31 | with, 32 | 33 | * The latest Docusaurus 2 beta comes with automatic updating 34 | 35 | ### Docusaurus 2 36 | 37 | This image runs Docusaurus 2 beta instead of stable Docusaurus 1. Docusaurus 2 is developing very actively currently, so I hope that will be released in the near future. 38 | 39 | ![homepage](docs/docusaurus2_homepage.png) 40 | 41 | I saw that there will be some migration jobs needed when a user upgrades their Docusarus 1 to the new Docusaurus 2. So, at this moment I think it is reasonable to use Docusaurus 2 for those who about to start constructing their own website. 42 | 43 | But, officially, as this is an beta version yet, I put a automatic update trigger into this image. This can be disabled by setting environment variable like `AUTO_UPDATE=false`. By default this is enabled. 44 | 45 | ### Keep backing-up your docs 46 | 47 | It is highly recommended that always do keeping backing-up your docs. For several reasons such as unexpected physical damage onto your harddrive or software corruptions under development and/or maintenance, you have to back-up your data into your other safe place. 48 | 49 | ### Supports multiple architectures 50 | 51 | It builds from Github Actions for supporting multiple architectures such as AMD64(x86_64) and ARM64, ARMv7, ARMv6. 52 | 53 | So that you can use this on most computers supporting Docker. 54 | 55 | ## How can I use this 56 | 57 | Pull the image from Docker Hub. 58 | 59 | ```bash 60 | docker pull awesometic/docusaurus 61 | ``` 62 | 63 | ### Basic usage 64 | 65 | You can just do dry-run this with the following command. The '--rm' option removes container when you terminate the interactive session. 66 | 67 | ```bash 68 | docker run -it --rm \ 69 | -p 80:80 \ 70 | -v /config/dir:/docusaurus \ 71 | awesometic/docusaurus 72 | ``` 73 | 74 | This Docker image requires one mapped volume on host computer. 75 | 76 | * `/docusaurus`: Where the Docusaurus source files located in 77 | 78 | **In the first running**, it may takes several minutes to download/prepare the whole source code from the Internet. See the [When can I access my website](https://github.com/awesometic/docker-docusaurus#when-can-i-access-my-website) chapter below. 79 | 80 | Then you have made a basic Docusaurus website having the following characteristics. 81 | 82 | * Project sources are having UID 1000 and GID 1000 for non-root editing 83 | * Enabled auto update 84 | * Named "MyWebsite" 85 | * Styled with "classic" template 86 | 87 | If you want to run this image as a daemon with your parameters, try using the following command. 88 | 89 | ```bash 90 | docker run -d --name=docusaurus \ 91 | -p 80:80 \ 92 | -v /config/dir:/docusaurus \ 93 | -e TARGET_UID=1000 \ 94 | -e TARGET_GID=1000 \ 95 | -e AUTO_UPDATE=true \ 96 | -e WEBSITE_NAME="awesometic-docs" \ 97 | -e TEMPLATE=classic \ 98 | awesometic/docusaurus 99 | ``` 100 | 101 | When the container runs, just let your browser browses: 102 | 103 | ``` http 104 | http://localhost/ 105 | ``` 106 | 107 | ### Production mode 108 | 109 | This image runs in development mode by default so that you can see the changes right after you edit the documents. 110 | 111 | But you can build the source files by starting this image as production mode. You can do this by adding the `RUN_MODE` environment variable when you create a container. See the commands below. 112 | 113 | ```bash 114 | docker run -d --name=docusaurus \ 115 | -p 80:80 \ 116 | -v /config/dir:/docusaurus \ 117 | -e TARGET_UID=1000 \ 118 | -e TARGET_GID=1000 \ 119 | -e AUTO_UPDATE=true \ 120 | -e WEBSITE_NAME="awesometic-docs" \ 121 | -e TEMPLATE=classic \ 122 | -e RUN_MODE=production \ 123 | awesometic/docusaurus 124 | ``` 125 | 126 | Then the logs shows like the below. 127 | 128 | ```shell 129 | /* Will run this Node service as production mode... */ 130 | /* Build current sources... */ 131 | yarn run v1.22.15 132 | $ docusaurus serve --build --port 80 --host 0.0.0.0 133 | 2021-10-21 07:18:25,121 INFO success: docusaurus entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 134 | 135 | [en] Creating an optimized production build... 136 | ℹ Compiling Client 137 | ℹ Compiling Server 138 | ✔ Client: Compiled successfully in 12.17s 139 | ✔ Server: Compiled successfully in 14.75s 140 | Success! Generated static files in "build". 141 | 142 | Use `npm run serve` command to test your build locally. 143 | 144 | 145 | ┌────────────────────────────────────────────────────────┐ 146 | │ │ 147 | │ Serving "build" directory at "http://0.0.0.0:80/". │ 148 | │ │ 149 | └────────────────────────────────────────────────────────┘ 150 | 151 | 152 | ``` 153 | 154 | If the build is completed flawlessly, you can find the `build` directory under the directory you selected for the website sources of the Docusaurus service. 155 | 156 | The built-in web server serves built web sources but you also can serve that from the other web servers like Nginx or Apache. 157 | 158 | The built files will be updated to have the latest contents whenever you enter the `docker restart [container-id]` command. 159 | 160 | ### When can I access my website 161 | 162 | In the first running, so to speak, if it ran without configuration files that are created during the first run time before, the users cannot access the newly created Docusaurus website immediately. It will take more than 1 minutes because it downloads the latest Docusaurus source codes at the init process. 163 | 164 | See the logs showing when the Docusaurus container runs. 165 | 166 | ``` 167 | Variables: 168 | - UID=1000 169 | - GID=1000 170 | - AUTO_UPDATE=true 171 | - WEBSITE_NAME=awesometic-docs 172 | - TEMPLATE=classic 173 | - RUN_MODE=development 174 | /* Register a new cron job for auto updating... */ 175 | /* Successfully registered. */ 176 | /* Install docusaurus... */ 177 | npm WARN exec The following package was not found and will be installed: @docusaurus/init@latest 178 | 179 | Creating new Docusaurus project ... 180 | ... 181 | [4/4] Building fresh packages... 182 | ... 183 | Success! Created awesometic-docs 184 | ... 185 | /* Node modules already exist in /docusaurus/awesometic-docs/node_modules */ 186 | /* Start supervisord to start Docusaurus... */ 187 | 2021-02-22 03:14:43,572 INFO Set uid to user 0 succeeded 188 | 2021-02-22 03:14:43,584 INFO supervisord started with pid 95 189 | 2021-02-22 03:14:44,589 INFO spawned: 'docusaurus' with pid 97 190 | yarn run v1.22.5 191 | $ docusaurus start --port 80 --host 0.0.0.0 192 | 2021-02-22 03:14:46,406 INFO success: docusaurus entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 193 | Starting the development server... 194 | Docusaurus website is running at: http://localhost:80/ 195 | ℹ Compiling Client 196 | ℹ 「wds」: Project is running at http://0.0.0.0:80/ 197 | ℹ 「wds」: webpack output is served from / 198 | ℹ 「wds」: Content not from webpack is served from /docusaurus/awesometic-docs 199 | ℹ 「wds」: 404s will fallback to /index.html 200 | ✔ Client: Compiled successfully in 27.42s 201 | ℹ Compiling Client 202 | ✔ Client: Compiled successfully in 507.94ms 203 | ``` 204 | 205 | As we can see the logs, at the first, the init process is downloading the full source codes from the Internet. Then it builds the source codes, and finally it starts with the specified port number. At this moment the logs are, 206 | 207 | ``` 208 | $ docusaurus start --port 80 --host 0.0.0.0 209 | 2021-02-22 03:14:46,406 INFO success: docusaurus entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 210 | Starting the development server... 211 | Docusaurus website is running at: http://localhost:80/ 212 | ℹ Compiling Client 213 | ℹ 「wds」: Project is running at http://0.0.0.0:80/ 214 | ℹ 「wds」: webpack output is served from / 215 | ℹ 「wds」: Content not from webpack is served from /docusaurus/awesometic-docs 216 | ℹ 「wds」: 404s will fallback to /index.html 217 | ✔ Client: Compiled successfully in 27.42s 218 | ℹ Compiling Client 219 | ✔ Client: Compiled successfully in 507.94ms 220 | ``` 221 | 222 | So, even if you cannot access it after running this Docker image, the container itself maybe not broken. Wait 1 or 2 minutes, then you can see the website front. 223 | 224 | ## Remains 225 | 226 | * [x] Production mode - Currently, this image always runs Docusaurus as development mode. The development mode allows live-updated as the admin edits whose site but it is not that solid because the visitors also can see the 'being editing' contents. This is acceptable for now but the production mode will be added on the requests. 227 | * [ ] Support HTTPS - This image doesn't support SSL even if the generated cert files are preprared but you can apply SSL if you have external Let's Encrypt program and/or a reverse proxy server like "linuxserver/letsencrypt". 228 | 229 | ## License 230 | 231 | This project comes with MIT license. Please see the [license file](LICENSE). 232 | -------------------------------------------------------------------------------- /config/auto_update_crontab.txt: -------------------------------------------------------------------------------- 1 | 00 00 * * * /usr/bin/env bash /auto_update_job.sh 2 | -------------------------------------------------------------------------------- /config/auto_update_job.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | msg() { 4 | echo -E "/* $1 */" 5 | } 6 | 7 | WEB_SRC_PATH="/docusaurus/website" 8 | 9 | cd "$WEB_SRC_PATH" || (msg "Cannot enter $WEB_SRC_PATH. Won't run the yarn command to update." ; exit) 10 | 11 | msg "Current version" 12 | yarn docusaurus --version 13 | 14 | msg "Now updating to the latest version..." 15 | yarn install & 16 | [[ "$!" -gt 0 ]]; wait "$!" 17 | 18 | msg "Updated version" 19 | yarn docusaurus --version 20 | 21 | exit 0 22 | 23 | -------------------------------------------------------------------------------- /config/init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | msg() { 4 | echo -E "/* $1 */" 5 | } 6 | 7 | find_autoupdate_cron_jobs() { 8 | local auto_update_jobs=0 9 | 10 | while read -r line; do 11 | [[ $line == *"auto_update_job"* ]] && (( auto_update_jobs++ )) 12 | done 13 | 14 | echo $auto_update_jobs 15 | } 16 | 17 | DOCU_PATH="/docusaurus" 18 | WEB_SRC_PATH="$DOCU_PATH"/website 19 | AUTO_UPD_CRONTAB_PATH="/auto_update_crontab.txt" 20 | 21 | echo -e "Variables: 22 | \\t- UID=${TARGET_UID} 23 | \\t- GID=${TARGET_GID} 24 | \\t- AUTO_UPDATE=${AUTO_UPDATE} 25 | \\t- WEBSITE_NAME=${WEBSITE_NAME} 26 | \\t- TEMPLATE=${TEMPLATE} 27 | \\t- RUN_MODE=${RUN_MODE}" 28 | 29 | [[ -z "$WEBSITE_NAME" ]] && \ 30 | msg "You have to enter your website name. Program will be closed." && exit 31 | 32 | if [[ "$AUTO_UPDATE" == true ]]; then 33 | msg "Register a new cron job for auto updating..." 34 | cat "$AUTO_UPD_CRONTAB_PATH" >> /etc/crontabs/root 35 | if [[ $(find_autoupdate_cron_jobs < <(crontab -l)) -gt 0 ]]; then 36 | msg "Successfully registered." 37 | else 38 | msg "Register failed with unknown problem. Please issue this on my Github repository." 39 | fi 40 | fi 41 | 42 | if [[ ! -d "$DOCU_PATH"/"$WEBSITE_NAME" ]]; then 43 | msg "Install docusaurus..." 44 | npx @docusaurus/init@latest init "$WEBSITE_NAME" "$TEMPLATE" & 45 | [[ "$!" -gt 0 ]] && wait $! 46 | ln -s "$DOCU_PATH"/"$WEBSITE_NAME" "$WEB_SRC_PATH" 47 | chown -R "$TARGET_UID":"$TARGET_GID" "$DOCU_PATH" 48 | else 49 | msg "Docusaurus configuration already exists in the target directory $DOCU_PATH" 50 | fi 51 | 52 | if [[ ! -d "$DOCU_PATH"/"$WEBSITE_NAME"/node_modules ]]; then 53 | msg "Installing node modules..." 54 | cd "$DOCU_PATH"/"$WEBSITE_NAME" 55 | yarn install & 56 | [[ "$!" -gt 0 ]] && wait $! 57 | cd .. 58 | ln -sf "$DOCU_PATH"/"$WEBSITE_NAME" "$WEB_SRC_PATH" 59 | chown -R "$TARGET_UID":"$TARGET_GID" "$DOCU_PATH" 60 | else 61 | msg "Node modules already exist in $DOCU_PATH/$WEBSITE_NAME/node_modules" 62 | fi 63 | 64 | if [[ "$RUN_MODE" != "development" ]]; then 65 | msg "Other mode is not supported yet. It will run as a development mode." 66 | fi 67 | 68 | msg "Start supervisord to start Docusaurus..." 69 | supervisord -c /etc/supervisor/conf.d/supervisord.conf 70 | 71 | -------------------------------------------------------------------------------- /config/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | msg() { 3 | echo -E "/* $1 */" 4 | } 5 | 6 | msg "Will run this Node service as $RUN_MODE mode..." 7 | 8 | if [[ "$RUN_MODE" == "development" ]]; then 9 | yarn run start --port 80 --host 0.0.0.0 & 10 | elif [[ "$RUN_MODE" == "production" ]]; then 11 | msg "Build current sources..." 12 | yarn run serve --build --port 80 --host 0.0.0.0 & 13 | elif [[ "$RUN_MODE" != "production" ]] && [[ "$RUN_MODE" != "development" ]]; then 14 | msg "This "$RUN_MODE" mode is unknown as a default Node.js service mode. You should do know what you do." 15 | yarn run "$RUN_MODE" & 16 | fi 17 | [[ "$!" -gt 0 ]] && wait $! 18 | -------------------------------------------------------------------------------- /config/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | 5 | [program:docusaurus] 6 | directory=/docusaurus/website 7 | command=/run.sh 8 | stdout_logfile=/dev/stdout 9 | stdout_logfile_maxbytes=0 10 | stderr_logfile=/dev/stderr 11 | stderr_logfile_maxbytes=0 12 | autorestart=false 13 | startretries=0 14 | -------------------------------------------------------------------------------- /docs/docusaurus2_homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesometic/docker-docusaurus/5e175c32c5c73579ed02b302201a088cee590575/docs/docusaurus2_homepage.png --------------------------------------------------------------------------------