├── .eslintrc.json ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .node-version ├── LICENSE ├── README.md ├── next-env.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── public ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── public-rsa.key └── public.key ├── src ├── components │ ├── current-year │ │ └── index.tsx │ ├── home │ │ ├── index.module.css │ │ └── index.tsx │ ├── navbar │ │ ├── link.module.css │ │ ├── link.tsx │ │ ├── title.module.css │ │ └── title.tsx │ └── secondary-text │ │ ├── index.module.css │ │ └── index.tsx └── pages │ ├── _app.tsx │ ├── _meta.json │ ├── changelog.md │ ├── contact.md │ ├── index.mdx │ ├── install.mdx │ ├── intro.md │ └── mirrors.md ├── theme.config.tsx └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "root": true, 4 | "extends": [ 5 | "next/core-web-vitals" 6 | ], 7 | "overrides": [ 8 | { 9 | "files": [ 10 | "**/*.mdx" 11 | ], 12 | "extends": [ 13 | "plugin:mdx/recommended" 14 | ], 15 | "settings": { 16 | "mdx/code-blocks": true 17 | }, 18 | "rules": {}, 19 | "parserOptions": { 20 | "sourceType": "module", 21 | "extraFileExtensions": [ 22 | ".mdx" 23 | ] 24 | } 25 | }, 26 | { 27 | "files": [ 28 | "*.d.ts", 29 | "**/*.ts", 30 | "**/*.tsx" 31 | ], 32 | "parserOptions": { 33 | "project": "./tsconfig.json", 34 | "sourceType": "module" 35 | }, 36 | "extends": [ 37 | "sukka/react", 38 | "sukka/typescript" 39 | ], 40 | "rules": { 41 | "@typescript-eslint/no-explicit-any": "off", 42 | "@typescript-eslint/no-non-null-assertion": "off" 43 | }, 44 | "settings": {} 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build Site 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | 15 | - name: Use Node.js 18 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: 18 19 | 20 | - name: node_modules CI Cache 21 | uses: actions/cache@v3 22 | with: 23 | path: ${{ github.workspace }}/node_modules 24 | key: ${{ runner.os }}-node_modules-${{ hashFiles('**/package-lock.json') }} 25 | 26 | - name: Next.js CI Cache 27 | uses: actions/cache@v3 28 | with: 29 | path: ${{ github.workspace }}/.next/cache 30 | # Generate a new cache whenever packages or source files change. 31 | key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('src/**', 'contents/**') }} 32 | # If source files changed but packages didn't, rebuild from a prior cache. 33 | restore-keys: | 34 | ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- 35 | - name: Install Dependencies 36 | run: npm clean-install 37 | 38 | - name: Build Site 39 | run: npm run build && npm run export 40 | 41 | - name: Upload Build Output to Artifacts 42 | uses: actions/upload-artifact@v4 43 | with: 44 | name: dist 45 | path: ${{ github.workspace }}/out/ 46 | if-no-files-found: error 47 | 48 | deploy: 49 | runs-on: ubuntu-latest 50 | needs: [build] 51 | strategy: 52 | matrix: 53 | include: 54 | - host_id: REMOTE_HOST_SJC 55 | fail-fast: false 56 | env: 57 | REMOTE_HOST: ${{ secrets[matrix.host_id] }} 58 | steps: 59 | - uses: actions/download-artifact@v4 60 | with: 61 | name: dist 62 | path: ${{ github.workspace }}/out/ 63 | - run: ls -R ${{ github.workspace }}/out/ 64 | - uses: easingthemes/ssh-deploy@v4.0.5 65 | env: 66 | SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} 67 | ARGS: '-avz --delete' 68 | REMOTE_HOST: ${{ env.REMOTE_HOST }} 69 | REMOTE_USER: ${{ secrets.REMOTE_USER }} 70 | SOURCE: out/* 71 | TARGET: /home/github/n.wtf/ 72 | EXCLUDE: .git,.github,.gitlab-ci.yml,.nojekyll 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .temp 3 | .cache 4 | .yarn 5 | .DS_Store 6 | .next 7 | out 8 | dist 9 | *.log 10 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2022] [U.SB] 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A nginx Debian / Ubuntu repository 2 | 3 | ## Domain Change 4 | 5 | Due to some reasons, we changed our domain and project name from `nginx.io` and `nginx.u.sb` to `n.wtf`. 6 | 7 | ## License and Trademark 8 | 9 | We distribute this software under the MIT license. 10 | 11 | [nginx](http://nginx.org/en/) is a opensource HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server distributed under the 2-clause BSD-like license. 12 | 13 | NGINX is a trademark of F5 NETWORKS, INC. 14 | 15 | We are not affiliated with NGINX Inc. and/or F5 NETWORKS, INC. 16 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const withNextra = require('nextra'); 2 | 3 | module.exports = withNextra({ 4 | theme: 'nextra-theme-docs', 5 | themeConfig: './theme.config.tsx' 6 | })({ 7 | reactStrictMode: true, 8 | trailingSlash: true, 9 | images: { 10 | unoptimized: true 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nginx-docs", 3 | "version": "2.0.0", 4 | "private": true, 5 | "description": "A nginx Debian / Ubuntu repository", 6 | "main": "index.js", 7 | "repository": "https://github.com/u-sb/nginx-docs", 8 | "author": "U.SB", 9 | "license": "MIT", 10 | "scripts": { 11 | "dev": "next dev", 12 | "build": "next build", 13 | "start": "next start", 14 | "export": "next export" 15 | }, 16 | "dependencies": { 17 | "clsx": "^1.2.1", 18 | "next": "^13.1.2", 19 | "nextra": "^2.2.1", 20 | "nextra-theme-docs": "^2.2.1", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0" 23 | }, 24 | "devDependencies": { 25 | "@types/node": "18.11.18", 26 | "@types/react": "^18.0.26", 27 | "@typescript-eslint/eslint-plugin": "^5.48.1", 28 | "@typescript-eslint/parser": "^5.48.1", 29 | "eslint-config-next": "^13.1.2", 30 | "eslint-config-sukka": "1.6", 31 | "eslint-plugin-mdx": "^2.0.5", 32 | "eslint-plugin-react": "^7.32.0", 33 | "typescript": "^4.9.4" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/u-sb/nginx-docs/9078fcd6c839917ad896381cc34975b02ad9eaed/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/u-sb/nginx-docs/9078fcd6c839917ad896381cc34975b02ad9eaed/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/u-sb/nginx-docs/9078fcd6c839917ad896381cc34975b02ad9eaed/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/u-sb/nginx-docs/9078fcd6c839917ad896381cc34975b02ad9eaed/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/u-sb/nginx-docs/9078fcd6c839917ad896381cc34975b02ad9eaed/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/u-sb/nginx-docs/9078fcd6c839917ad896381cc34975b02ad9eaed/public/favicon.ico -------------------------------------------------------------------------------- /public/public-rsa.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mQEOBFv+Ma8BCADSta4JnXK4WmnKrX+aXwIUEL3A0DcmFFVN4HBacPUjFeNo2NlC 4 | +89oH54aCPS8tuFgwF7a1FIwegNjsAp6dfhtRoLvgB+Hmp4SYyzWKvAdzhARM52D 5 | NrHV5MUkmh5w64C2U9D9tVWXZslAt2GS0ErXzL/mkzs30ja+SS0ZFRz509Ea6qbi 6 | gXRP5iq3f78hGbRD7QAMWrWAYu7lK3foFZLrWom4NYlmnPexGMMgaYU00iJcPKfS 7 | MePZmx5Kowzql7i4t/c0z9BsEpCmDpnU/V4icrsqA2xp0r1jRaHErzAm/WbuwTsP 8 | 4FK2goQjkuvXdpP9yBSHxiZx7CoItvA6sd7JACD2smuHtCNTQiBQcm9mZXNzaW9u 9 | YWwgU2VydmljZXMgPHNiQHNiLnNiPokBTgQTAQgAOBYhBEVEHxNLlqFi4TMzlts7 10 | 3jdbWyAYBQJb/jIPAhsvBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJENs73jdb 11 | WyAYjWIIAICTppgHFX8a+GWTQavl5sakwy5TnA9bEz9C1BhIwJpekPNan+UupEyS 12 | H4Cat8mQ8j/nK09wPD4E3fTdY7uonwawONpUdNVewzJ4W/I0NitNne/nsra9rv2h 13 | TcU1G5oNRZ6Gl3PFgCv0HO5BxOPXnuj0eyssrZzZVww/iDdrCh5PwU5ODQkBHit3 14 | czeIVm1Kn86+4XdVbRkKNssYgXgOmaD7TkWKNXmksDpNMdvqvrc+eW6BJTioCJQI 15 | RbH5cxYXqGHp2giTH9X+iwj1sPLEkZ6BhWjwF0shHC/RrDCk4RPTpZ13Sw/fokAz 16 | LBpeubDAZ9xplTIsKzUxxnZr9Bu270u5AQ0EW/40ggEIALtYoLdeNEkHAAW7pnyQ 17 | 820iGuPuwcfZrCSMMl0iahN2H8o43pCxvH/Bz9MQ8uemiRV/QuBcQybIDuMCZVub 18 | OFo72fT4xL8YHinux/nYlgaBAnUI5ojfHN/A7C/HxdXNiPnBSh3cPH+VkY8EyNzQ 19 | hZJRly/Y03BZQVcx1r2oNRG7SZN6eVEhG5WiorXvm9ce9j7JYGSwsyhGuIVKdg4B 20 | Mk3BjjafbgxKBBLwZCLkmhLjuKhbQqBOzgVcaMxTlPUC81NX9X/ghyGCsTYm9ihu 21 | wOJSCBHDUFokRL0BijL51HnxGzMorp67sRAYVeTiE/yaPyrNtzMB5hHhBLehmiDZ 22 | QGUAEQEAAYkBNgQYAQgAIBYhBEVEHxNLlqFi4TMzlts73jdbWyAYBQJb/jSCAhsM 23 | AAoJENs73jdbWyAYrOoH/iZqEmduhbXELjuevxk0lIaIDyr8wAd6TjiSTV7iUHYh 24 | 3McBzDCOcFeVlQwFKv53iNoWexotyt058elB5Qbf8HKfdPOae5iSjclsQCu7XZtl 25 | wLNGTNaSEITmpgaab2IP7/iHhFkKpOu/hDhz7FbSKHiaZl9/ZFqO1HUyZkjZRwhh 26 | cdLKcpJGSLSXUE7WrBqQPT2whUOQzhI45Od23gX5uMXwcYrKu5uTH1PKi21CGIJj 27 | pdGPf3a5lgldbhVpKgHO1S211AkfHEuQdHJTnnpj7l0cs64mFKuSCJs0IfYUga37 28 | lEuGdSu1Oisz5pyE6G3qn7w/nB6k6b4+tM7ChJ+jveg= 29 | =1BWA 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | -------------------------------------------------------------------------------- /public/public.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mDMEW+ed9RYJKwYBBAHaRw8BAQdANcXWdtpkFkk8nmqYhpQ1yny+muJgxZV/Fp2y 4 | siaaGdW0I1NCIFByb2Zlc3Npb25hbCBTZXJ2aWNlcyA8c2JAc2Iuc2I+iJAEExYI 5 | ADgWIQQWBGFLSmwrc2VLuLbFIVyvAFVSLwUCW+ed9QIbIwULCQgHAgYVCgkICwIE 6 | FgIDAQIeAQIXgAAKCRDFIVyvAFVSL6leAQDDKWldReejgp3rcS4WWxXoDZNBEGej 7 | TMg/4+a1xpm4hwD/QxjN9JubyaNexHLEBD4HnQQ3NIFpxlYPjQ/Urr8Jygm4OARb 8 | 5531EgorBgEEAZdVAQUBAQdAhklzAaoLgtgH2MByBlJ5kc2Bj+5p9hq+nsccADyk 9 | DUIDAQgHiHgEGBYIACAWIQQWBGFLSmwrc2VLuLbFIVyvAFVSLwUCW+ed9QIbDAAK 10 | CRDFIVyvAFVSL0O9AQDRVtWevQICh7hquGi9WvnUISZfC6YeZcBryaVeWmqPxAEA 11 | qTBT2gUyytqI6g8cWVInDUucg7fDCfIX8kZhCy3eUwI= 12 | =LJQx 13 | -----END PGP PUBLIC KEY BLOCK----- 14 | 15 | -------------------------------------------------------------------------------- /src/components/current-year/index.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | export const CurrentYear = (props: { defaultYear: number }) => { 4 | const [year, setYear] = useState(props.defaultYear); 5 | useEffect(() => { 6 | setYear(new Date().getFullYear()); 7 | }, []); 8 | return {year}; 9 | }; 10 | -------------------------------------------------------------------------------- /src/components/home/index.module.css: -------------------------------------------------------------------------------- 1 | .hero { 2 | text-align: center; 3 | padding-top: 32px; 4 | padding-bottom: 32px; 5 | } 6 | 7 | .logo { 8 | max-width: 100%; 9 | max-height: 100px; 10 | width: auto; 11 | margin-left: auto; 12 | margin-right: auto; 13 | } 14 | 15 | .title { 16 | font-size: 32px; 17 | font-weight: 600; 18 | margin-top: 16px; 19 | margin-bottom: 16px; 20 | } 21 | 22 | .description { 23 | font-size: 20px; 24 | font-weight: 400; 25 | margin-top: 16px; 26 | margin-bottom: 16px; 27 | opacity: 50%; 28 | } 29 | 30 | .actions { 31 | margin: 16px auto; 32 | display: flex; 33 | flex-wrap: wrap; 34 | justify-content: center; 35 | } 36 | 37 | .button { 38 | border-radius: 16px; 39 | font-size: 20px; 40 | color: #ff55ff; 41 | padding: 8px 22px; 42 | margin: 8px; 43 | font-weight: 500; 44 | transition-property: background-color, border-color; 45 | transition-duration: 300ms; 46 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 47 | } 48 | 49 | .button_primary { 50 | background-color: #ff55ff; 51 | color: white; 52 | } 53 | 54 | .button_primary:hover { 55 | background-color: #ee00ee; 56 | } 57 | 58 | .button_secondary { 59 | background-color: #f1f1f1; 60 | } 61 | 62 | .button_secondary:hover { 63 | background-color: #e5e5e5; 64 | } 65 | 66 | html[class~=dark] .button_secondary { 67 | background-color: #2f2f2f; 68 | } 69 | 70 | html[class~=dark] .button_secondary:hover { 71 | background-color: #3a3a3a; 72 | } 73 | 74 | .features { 75 | border-top: 2px solid; 76 | border-color: #eee; 77 | padding-top: 32px; 78 | padding-bottom: 32px; 79 | display: grid; 80 | gap: 16px; 81 | grid-template-columns: repeat(1, 1fr); 82 | } 83 | 84 | @media screen and (min-width: 768px) { 85 | .features { 86 | grid-template-columns: repeat(3, 1fr); 87 | } 88 | } 89 | 90 | .feature { 91 | padding-top: 16px; 92 | padding-bottom: 16px; 93 | } 94 | 95 | .feature h2 { 96 | font-size: 24px; 97 | font-weight: 600; 98 | margin-bottom: 16px; 99 | } 100 | 101 | :global(.light) .features { 102 | border-color: #eee; 103 | } 104 | 105 | :global(.dark) .features { 106 | border-color: #333; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /src/components/home/index.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image'; 2 | import nwtfLogo from '../../../public/android-chrome-512x512.png'; 3 | 4 | import styles from './index.module.css'; 5 | import Link from 'next/link'; 6 | import { clsx } from 'clsx'; 7 | 8 | const features = [ 9 | { 10 | name: 'Up-to-date', 11 | text: 'We release latest mainline branch from nginx official source code.' 12 | }, 13 | { 14 | name: 'TLS 1.3', 15 | text: 'We packed OpenSSL 3.5.x into our nginx as standard.' 16 | }, 17 | { 18 | name: 'Modules', 19 | text: 'Brotli compression, QUIC, HTTP/3, GeoIP2 and more.' 20 | } 21 | ]; 22 | 23 | export default function HomePage() { 24 | return ( 25 | <> 26 |
27 | Logo 33 |

N.WTF

34 |

35 | Open-source nginx Debian / Ubuntu repository 36 |

37 |
38 | 39 | Getting Started 40 | 41 | 42 | Install 43 | 44 |
45 |
46 |
47 | {features.map(feature => ( 48 |
49 |

{feature.name}

50 |

{feature.text}

51 |
52 | ))} 53 |
54 | 55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /src/components/navbar/link.module.css: -------------------------------------------------------------------------------- 1 | .link { 2 | display: flex; 3 | flex-wrap: wrap; 4 | align-items: center; 5 | font-weight: 500; 6 | color: rgba(75, 85, 99) 7 | } 8 | 9 | .link:hover { 10 | color: rgba(31, 41, 55) 11 | } 12 | 13 | html[class~=dark] .link { 14 | color: rgba(156, 163, 175); 15 | } 16 | 17 | html[class~=dark] .link:hover { 18 | color: rgba(229, 231, 235); 19 | } 20 | 21 | .icon { 22 | width: 12px; 23 | height: 12px; 24 | margin-left: 6px; 25 | } 26 | -------------------------------------------------------------------------------- /src/components/navbar/link.tsx: -------------------------------------------------------------------------------- 1 | import styles from './link.module.css'; 2 | 3 | export default function SBBlogLink() { 4 | return ( 5 | 11 | m.ac 12 | 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/components/navbar/title.module.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-weight: 800; 3 | } 4 | 5 | .second { 6 | color: rgba(75, 85, 99); 7 | font-weight: 400; 8 | display: none; 9 | margin-left: 0.5rem; 10 | } 11 | 12 | @media screen and (min-width: 768px) { 13 | .second { 14 | display: inline; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/components/navbar/title.tsx: -------------------------------------------------------------------------------- 1 | import styles from './title.module.css'; 2 | 3 | export default function NavbarTitle() { 4 | return ( 5 | <> 6 | N.WTF 7 | nginx with latest features 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /src/components/secondary-text/index.module.css: -------------------------------------------------------------------------------- 1 | .secondary { 2 | font-size: 14px; 3 | color: gray; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/secondary-text/index.tsx: -------------------------------------------------------------------------------- 1 | import styles from './index.module.css'; 2 | 3 | export default function SecondaryText({ children }: { children: string }) { 4 | return {children}; 5 | } 6 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import Script from 'next/script'; 2 | import type { AppProps } from 'next/app'; 3 | 4 | function MyApp({ Component, pageProps }: AppProps) { 5 | if ('statusCode' in pageProps && pageProps.statusCode === 404) { 6 | return ( 7 | 8 | ); 9 | } 10 | return ( 11 | <> 12 | 13 | {process.env.NODE_ENV === 'production' && ( 14 |