feat: first pass at oper guide requirements
This commit is contained in:
parent
efd0e7cf53
commit
8f7d0d372e
27 changed files with 1615 additions and 611 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -20,3 +20,4 @@ yarn-debug.log*
|
|||
yarn-error.log*
|
||||
|
||||
./idea
|
||||
/.idea
|
||||
|
|
|
|||
|
|
@ -1,47 +1,7 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Overview
|
||||
---
|
||||
|
||||
# Tutorial Intro
|
||||
# Documentation Overview
|
||||
|
||||
Let's discover **Docusaurus in less than 5 minutes**.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Get started by **creating a new site**.
|
||||
|
||||
Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**.
|
||||
|
||||
### What you'll need
|
||||
|
||||
- [Node.js](https://nodejs.org/en/download/) version 20.0 or above:
|
||||
- When installing Node.js, you are recommended to check all checkboxes related to dependencies.
|
||||
|
||||
## Generate a new site
|
||||
|
||||
Generate a new Docusaurus site using the **classic template**.
|
||||
|
||||
The classic template will automatically be added to your project after you run the command:
|
||||
|
||||
```bash
|
||||
npm init docusaurus@latest my-website classic
|
||||
```
|
||||
|
||||
You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor.
|
||||
|
||||
The command also installs all necessary dependencies you need to run Docusaurus.
|
||||
|
||||
## Start your site
|
||||
|
||||
Run the development server:
|
||||
|
||||
```bash
|
||||
cd my-website
|
||||
npm run start
|
||||
```
|
||||
|
||||
The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there.
|
||||
|
||||
The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/.
|
||||
|
||||
Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes.
|
||||
|
|
|
|||
4
docs/operator/_category_.yml
Normal file
4
docs/operator/_category_.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
label: Operator Guide
|
||||
link:
|
||||
type: "generated-index"
|
||||
80
docs/operator/architecture.md
Normal file
80
docs/operator/architecture.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
We begin the guide with a high-level overview of the architecture of the CDR Link deployment framework.
|
||||
|
||||
## Introduction
|
||||
|
||||
We deploy each CDR Link instance on a single
|
||||
[Red Had Enterprise Linux](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux)
|
||||
9 (or compatible) host using
|
||||
[rootless Podman](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md).
|
||||
Each component of Link is a container instance with the containers managed via systemd using
|
||||
[Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
|
||||
Components communicate via isolated networks that are also configured via Quadlet, and make use of the
|
||||
[slirp4netns](https://github.com/rootless-containers/slirp4netns) user-mode networking for unprivileged
|
||||
network namespaces.
|
||||
|
||||
Both
|
||||
[discretionary access controls](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_basic_system_settings/managing-file-system-permissions_configuring-basic-system-settings)
|
||||
and SELinux are used to prevent lateral movement between containers should a container be compromised, with particular
|
||||
attention given to the messaging channels WhatsApp and Signal.
|
||||
No container runs its application as the inside "root" user, which is an unprivileged user on the host.
|
||||
|
||||
The `/home` mount point on the host is encrypted using
|
||||
[LUKS](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/managing_storage_devices/encrypting-block-devices-using-luks_managing-storage-devices)
|
||||
with a per instance key to protect all user data at rest.
|
||||
Further, we use separate partitions for critical audit logging to ensure that a resource exhaustion attack cannot
|
||||
prevent later investigation, and automatically shut down instances where there is no space available for audit logging.
|
||||
|
||||
## Components
|
||||
|
||||
The following diagram shows the dependency relationships between the components of CDR Link.
|
||||
If you use our [Ansible role](./deploy) for deployment then these will be automatically configured.
|
||||
The Link stack containers are
|
||||
[OCI](https://opencontainers.org/) compliant containers and you can run these with alternatives
|
||||
such as [Docker Compose](https://docs.docker.com/compose/) however we would not be able to provide support for this
|
||||
setup.
|
||||
Our former Docker Compose deployment framework has been deprecated and we intend to migrate all partners to our new
|
||||
rootless Podman setup for the improved reliability, performance, and security.
|
||||
|
||||
:::info
|
||||
While the following diagram refers to `.service` units, these are the units generated by Podman Quadlet.
|
||||
The service definitions are in `.container` units within the Quadlet directory at `$HOME/.config/containers/systemd`.
|
||||
:::
|
||||
```mermaid
|
||||
flowchart TD
|
||||
bridge-worker.service --> bridge-postgresql.service
|
||||
bridge-worker.service --> bridge-whatsapp.service
|
||||
bridge-worker.service --> signal-cli-rest-api.service
|
||||
|
||||
link.service --> bridge-postgresql.service
|
||||
link.service --> bridge-worker.service
|
||||
|
||||
opensearch-dashboards.service --> zammad-opensearch.service
|
||||
|
||||
zammad-nginx.service --> zammad-railsserver.service
|
||||
zammad-nginx.service --> link.service
|
||||
|
||||
zammad-storage.target{zammad-storage.target}
|
||||
zammad-storage.target --> zammad-postgresql.service
|
||||
zammad-storage.target --> zammad-redis.service
|
||||
zammad-storage.target --> zammad-memcached.service
|
||||
zammad-storage.target --> zammad-opensearch.service
|
||||
|
||||
zammad-railsserver.service -.-> zammad-init.service
|
||||
|
||||
zammad-init.service --> zammad-storage.target
|
||||
zammad-railsserver.service --> zammad-storage.target
|
||||
zammad-scheduler.service --> zammad-storage.target
|
||||
zammad-websocket.service --> zammad-storage.target
|
||||
|
||||
link.target{link.target}
|
||||
link.target --> opensearch-dashboards.service
|
||||
link.target --> zammad-nginx.service
|
||||
link.target --> zammad-scheduler.service
|
||||
link.target --> zammad-websocket.service
|
||||
```
|
||||
105
docs/operator/requirements.md
Normal file
105
docs/operator/requirements.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
sidebar_position: 20
|
||||
---
|
||||
|
||||
# Requirements
|
||||
|
||||
If you are looking to self-host CDR Link, this page details what is required to run a secure and reliable instance.
|
||||
|
||||
The following requirements assume that your deployment framework will be the same as ours.
|
||||
You may need to adjust the requirements if your framework differs materially, and while we can offer limited support for
|
||||
this we would not be able to assist with in-depth troubleshooting.
|
||||
|
||||
## Deployment Host
|
||||
|
||||
:::danger
|
||||
A compromise of this host effectively compromises the entire stack.
|
||||
:::
|
||||
|
||||
* Appropriately hardened and vendor supported Linux operating system with the latest security updates applied
|
||||
* SSH key backed by hardware security module and requiring unlock (e.g. [YubiKey](https://www.yubico.com/)) to be used
|
||||
for login to the instance host
|
||||
* Python 3.11+ (the `venv` module is included in Python since v3.3 so this is not a separate requirement)
|
||||
* Git
|
||||
* Ansible-compatible secrets management (e.g.
|
||||
[sops](https://getsops.io/) or
|
||||
[Bitwarden Secrets Manager](https://bitwarden.com/products/secrets-manager/))
|
||||
|
||||
## CDR Link Instance Host
|
||||
|
||||
It is **strongly recommended** that this host is dedicated to running the CDR Link software only.
|
||||
|
||||
* A [Red Hat Enterprise Linux](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux)
|
||||
9 (or compatible) host with the latest security updates and appropriate hardening applied
|
||||
* At least 4 (v)CPUs, 15GB RAM, and 75GB disk space
|
||||
* Separate partitions for `/var`, `/var/log`, `/var/log/audit`, and `/home`
|
||||
* `/home` must use the
|
||||
[XFS](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/managing_file_systems/getting-started-with-xfs_managing-file-systems)
|
||||
file system (to apply quotas)
|
||||
* A global scope IP address assigned to one of the network interfaces
|
||||
* FirewallD is installed and enabled with only the `ssh` service enabled
|
||||
* Our deployment script will add the `http` and `https` services
|
||||
* An unprivileged user created with 65536
|
||||
[subuids and subgids](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/building_running_and_managing_containers/assembly_starting-with-containers_building-running-and-managing-containers#proc_setting-up-rootless-containers_assembly_starting-with-containers)
|
||||
assigned that will be used to run the Link stack
|
||||
* An unprivileged user with sudo permission, and the SSH public key from the deployment host installed as an authorised
|
||||
key
|
||||
|
||||
In our deployments, we would perform the hardening configuration using our
|
||||
[baseline Ansible role](https://guardianproject.dev/sr2/ansible-collection-core/src/branch/main/roles/baseline),
|
||||
however this role is not intended for general use and so may not fit your requirements.
|
||||
We manage our users, groups, and subordinate IDs using
|
||||
[Identity Management](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/installing_identity_management/index)
|
||||
but a locally created user can also be used.
|
||||
|
||||
:::warning
|
||||
Depending on your configuration it is also possible to use an LDAP user with locally defined subuids and subgids however
|
||||
be aware that this may lead to conflicts between hosts, and complications if file system snapshots or backups are
|
||||
available across hosts.
|
||||
:::
|
||||
|
||||
## CDR Link Handset (Optional)
|
||||
|
||||
The handset is only required if you wish to use the Signal or WhatsApp channels with CDR Link.
|
||||
|
||||
It is **strongly recommended** that this handset is dedicated to running the CDR Link related apps only and is stored in
|
||||
a secure facility.
|
||||
Consider that the device will require to have its cellular connection available and so it would not be advised to store
|
||||
the handset, for example, in a metallic container.
|
||||
|
||||
:::tip
|
||||
Many of the handset related support requests we receive are due to partners using the handset directly rather than
|
||||
allowing CDR Link to manage the channels leading to the system losing synchronisation and then failing to recover.
|
||||
:::
|
||||
|
||||
The handset has the ability to send and receive messages via the helpdesk channels and so should not be frequently moved
|
||||
between locations to reduce the risk of theft or other loss.
|
||||
|
||||
Cheaper handsets often do not receive security updates for Android promptly after their release as there are multiple
|
||||
steps in the supply chain before an update can be distributed. Ensure that you purchase your handset from a reputable
|
||||
manufacturer that provides a guaranteed period of security updates and has a track record of timely distribution of
|
||||
those updates.
|
||||
|
||||
* At least Android 14, preferably at least 15 for new deployments, with latest system updates installed
|
||||
* Google Play Services are required for Signal and WhatsApp
|
||||
* Cellular plan that can receive SMS and with enough data to allow for system updates
|
||||
* SMS required to allow activation of the WhatsApp and Signal accounts
|
||||
* We have seen lower rates of accounts being blocked (automatically flagged as spam or fraud) when using cellular data
|
||||
plans as opposed to WiFi
|
||||
* At least 3GB RAM and 16GB storage
|
||||
* [Mobile Device Management](https://www.android.com/intl/en_uk/enterprise/management/) for configuration, automatic
|
||||
updates and remote wipe capability
|
||||
* Appropriate hardening, for example:
|
||||
* Ensure that a complex screen lock is used
|
||||
* Ensure that device encryption is enabled
|
||||
* Ensure that developer options are disabled
|
||||
* Ensure screen timeout is set
|
||||
* Ensure lock screen does not show notifications
|
||||
* Disable Bluetooth and WiFi
|
||||
* 7-day timer to manage charging to avoid failure of the internal battery
|
||||
|
||||
:::danger
|
||||
If you leave the phone permanently connected to the charger, the internal battery of the handset will fail and may pose
|
||||
a fire hazard.
|
||||
You should consider any charging of lithium-ion batteries in your local site risk assessments.
|
||||
:::
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"label": "Tutorial - Basics",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "5 minutes to learn the most important Docusaurus concepts."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
---
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Congratulations!
|
||||
|
||||
You have just learned the **basics of Docusaurus** and made some changes to the **initial template**.
|
||||
|
||||
Docusaurus has **much more to offer**!
|
||||
|
||||
Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**.
|
||||
|
||||
Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610)
|
||||
|
||||
## What's next?
|
||||
|
||||
- Read the [official documentation](https://docusaurus.io/)
|
||||
- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config)
|
||||
- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration)
|
||||
- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout)
|
||||
- Add a [search bar](https://docusaurus.io/docs/search)
|
||||
- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase)
|
||||
- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support)
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Create a Blog Post
|
||||
|
||||
Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed...
|
||||
|
||||
## Create your first Post
|
||||
|
||||
Create a file at `blog/2021-02-28-greetings.md`:
|
||||
|
||||
```md title="blog/2021-02-28-greetings.md"
|
||||
---
|
||||
slug: greetings
|
||||
title: Greetings!
|
||||
authors:
|
||||
- name: Joel Marcey
|
||||
title: Co-creator of Docusaurus 1
|
||||
url: https://github.com/JoelMarcey
|
||||
image_url: https://github.com/JoelMarcey.png
|
||||
- name: Sébastien Lorber
|
||||
title: Docusaurus maintainer
|
||||
url: https://sebastienlorber.com
|
||||
image_url: https://github.com/slorber.png
|
||||
tags: [greetings]
|
||||
---
|
||||
|
||||
Congratulations, you have made your first post!
|
||||
|
||||
Feel free to play around and edit this post as much as you like.
|
||||
```
|
||||
|
||||
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Create a Document
|
||||
|
||||
Documents are **groups of pages** connected through:
|
||||
|
||||
- a **sidebar**
|
||||
- **previous/next navigation**
|
||||
- **versioning**
|
||||
|
||||
## Create your first Doc
|
||||
|
||||
Create a Markdown file at `docs/hello.md`:
|
||||
|
||||
```md title="docs/hello.md"
|
||||
# Hello
|
||||
|
||||
This is my **first Docusaurus document**!
|
||||
```
|
||||
|
||||
A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello).
|
||||
|
||||
## Configure the Sidebar
|
||||
|
||||
Docusaurus automatically **creates a sidebar** from the `docs` folder.
|
||||
|
||||
Add metadata to customize the sidebar label and position:
|
||||
|
||||
```md title="docs/hello.md" {1-4}
|
||||
---
|
||||
sidebar_label: 'Hi!'
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Hello
|
||||
|
||||
This is my **first Docusaurus document**!
|
||||
```
|
||||
|
||||
It is also possible to create your sidebar explicitly in `sidebars.js`:
|
||||
|
||||
```js title="sidebars.js"
|
||||
export default {
|
||||
tutorialSidebar: [
|
||||
'intro',
|
||||
// highlight-next-line
|
||||
'hello',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorial',
|
||||
items: ['tutorial-basics/create-a-document'],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Create a Page
|
||||
|
||||
Add **Markdown or React** files to `src/pages` to create a **standalone page**:
|
||||
|
||||
- `src/pages/index.js` → `localhost:3000/`
|
||||
- `src/pages/foo.md` → `localhost:3000/foo`
|
||||
- `src/pages/foo/bar.js` → `localhost:3000/foo/bar`
|
||||
|
||||
## Create your first React Page
|
||||
|
||||
Create a file at `src/pages/my-react-page.js`:
|
||||
|
||||
```jsx title="src/pages/my-react-page.js"
|
||||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
|
||||
export default function MyReactPage() {
|
||||
return (
|
||||
<Layout>
|
||||
<h1>My React page</h1>
|
||||
<p>This is a React page</p>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page).
|
||||
|
||||
## Create your first Markdown Page
|
||||
|
||||
Create a file at `src/pages/my-markdown-page.md`:
|
||||
|
||||
```mdx title="src/pages/my-markdown-page.md"
|
||||
# My Markdown page
|
||||
|
||||
This is a Markdown page
|
||||
```
|
||||
|
||||
A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page).
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# Deploy your site
|
||||
|
||||
Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**).
|
||||
|
||||
It builds your site as simple **static HTML, JavaScript and CSS files**.
|
||||
|
||||
## Build your site
|
||||
|
||||
Build your site **for production**:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
The static files are generated in the `build` folder.
|
||||
|
||||
## Deploy your site
|
||||
|
||||
Test your production build locally:
|
||||
|
||||
```bash
|
||||
npm run serve
|
||||
```
|
||||
|
||||
The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/).
|
||||
|
||||
You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**).
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Markdown Features
|
||||
|
||||
Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**.
|
||||
|
||||
## Front Matter
|
||||
|
||||
Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
|
||||
|
||||
```text title="my-doc.md"
|
||||
// highlight-start
|
||||
---
|
||||
id: my-doc-id
|
||||
title: My document title
|
||||
description: My document description
|
||||
slug: /my-custom-url
|
||||
---
|
||||
// highlight-end
|
||||
|
||||
## Markdown heading
|
||||
|
||||
Markdown text with [links](./hello.md)
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
Regular Markdown links are supported, using url paths or relative file paths.
|
||||
|
||||
```md
|
||||
Let's see how to [Create a page](/create-a-page).
|
||||
```
|
||||
|
||||
```md
|
||||
Let's see how to [Create a page](./create-a-page.md).
|
||||
```
|
||||
|
||||
**Result:** Let's see how to [Create a page](./create-a-page.md).
|
||||
|
||||
## Images
|
||||
|
||||
Regular Markdown images are supported.
|
||||
|
||||
You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`):
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
## Code Blocks
|
||||
|
||||
Markdown code blocks are supported with Syntax highlighting.
|
||||
|
||||
````md
|
||||
```jsx title="src/components/HelloDocusaurus.js"
|
||||
function HelloDocusaurus() {
|
||||
return <h1>Hello, Docusaurus!</h1>;
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```jsx title="src/components/HelloDocusaurus.js"
|
||||
function HelloDocusaurus() {
|
||||
return <h1>Hello, Docusaurus!</h1>;
|
||||
}
|
||||
```
|
||||
|
||||
## Admonitions
|
||||
|
||||
Docusaurus has a special syntax to create admonitions and callouts:
|
||||
|
||||
```md
|
||||
:::tip My tip
|
||||
|
||||
Use this awesome feature option
|
||||
|
||||
:::
|
||||
|
||||
:::danger Take care
|
||||
|
||||
This action is dangerous
|
||||
|
||||
:::
|
||||
```
|
||||
|
||||
:::tip My tip
|
||||
|
||||
Use this awesome feature option
|
||||
|
||||
:::
|
||||
|
||||
:::danger Take care
|
||||
|
||||
This action is dangerous
|
||||
|
||||
:::
|
||||
|
||||
## MDX and React Components
|
||||
|
||||
[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**:
|
||||
|
||||
```jsx
|
||||
export const Highlight = ({children, color}) => (
|
||||
<span
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderRadius: '20px',
|
||||
color: '#fff',
|
||||
padding: '10px',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
alert(`You clicked the color ${color} with label ${children}`)
|
||||
}}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
|
||||
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
|
||||
|
||||
This is <Highlight color="#1877F2">Facebook blue</Highlight> !
|
||||
```
|
||||
|
||||
export const Highlight = ({children, color}) => (
|
||||
<span
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderRadius: '20px',
|
||||
color: '#fff',
|
||||
padding: '10px',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
alert(`You clicked the color ${color} with label ${children}`);
|
||||
}}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
|
||||
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
|
||||
|
||||
This is <Highlight color="#1877F2">Facebook blue</Highlight> !
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"label": "Tutorial - Extras",
|
||||
"position": 3,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
|
|
@ -1,55 +0,0 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Manage Docs Versions
|
||||
|
||||
Docusaurus can manage multiple versions of your docs.
|
||||
|
||||
## Create a docs version
|
||||
|
||||
Release a version 1.0 of your project:
|
||||
|
||||
```bash
|
||||
npm run docusaurus docs:version 1.0
|
||||
```
|
||||
|
||||
The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created.
|
||||
|
||||
Your docs now have 2 versions:
|
||||
|
||||
- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs
|
||||
- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs**
|
||||
|
||||
## Add a Version Dropdown
|
||||
|
||||
To navigate seamlessly across versions, add a version dropdown.
|
||||
|
||||
Modify the `docusaurus.config.js` file:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
items: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'docsVersionDropdown',
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
The docs version dropdown appears in your navbar:
|
||||
|
||||

|
||||
|
||||
## Update an existing version
|
||||
|
||||
It is possible to edit versioned docs in their respective folder:
|
||||
|
||||
- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`
|
||||
- `docs/hello.md` updates `http://localhost:3000/docs/next/hello`
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Translate your site
|
||||
|
||||
Let's translate `docs/intro.md` to French.
|
||||
|
||||
## Configure i18n
|
||||
|
||||
Modify `docusaurus.config.js` to add support for the `fr` locale:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'fr'],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Translate a doc
|
||||
|
||||
Copy the `docs/intro.md` file to the `i18n/fr` folder:
|
||||
|
||||
```bash
|
||||
mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/
|
||||
|
||||
cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md
|
||||
```
|
||||
|
||||
Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French.
|
||||
|
||||
## Start your localized site
|
||||
|
||||
Start your site on the French locale:
|
||||
|
||||
```bash
|
||||
npm run start -- --locale fr
|
||||
```
|
||||
|
||||
Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated.
|
||||
|
||||
:::caution
|
||||
|
||||
In development, you can only use one locale at a time.
|
||||
|
||||
:::
|
||||
|
||||
## Add a Locale Dropdown
|
||||
|
||||
To navigate seamlessly across languages, add a locale dropdown.
|
||||
|
||||
Modify the `docusaurus.config.js` file:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
items: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'localeDropdown',
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
The locale dropdown now appears in your navbar:
|
||||
|
||||

|
||||
|
||||
## Build your localized site
|
||||
|
||||
Build your site for a specific locale:
|
||||
|
||||
```bash
|
||||
npm run build -- --locale fr
|
||||
```
|
||||
|
||||
Or build your site to include all the locales at once:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
|
@ -10,8 +10,8 @@ import {themes as prismThemes} from 'prism-react-renderer';
|
|||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: 'My Site',
|
||||
tagline: 'Dinosaurs are cool',
|
||||
title: 'CDR Link',
|
||||
tagline: 'A guide for agents, admins, and operators',
|
||||
favicon: 'img/favicon.ico',
|
||||
|
||||
// Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future
|
||||
|
|
@ -20,15 +20,15 @@ const config = {
|
|||
},
|
||||
|
||||
// Set the production url of your site here
|
||||
url: 'https://your-docusaurus-site.example.com',
|
||||
url: 'https://docs.cdr.link',
|
||||
// Set the /<baseUrl>/ pathname under which your site is served
|
||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||
baseUrl: '/',
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: 'facebook', // Usually your GitHub org/user name.
|
||||
projectName: 'docusaurus', // Usually your repo name.
|
||||
// organizationName: 'facebook', // Usually your GitHub org/user name.
|
||||
// projectName: 'docusaurus', // Usually your repo name.
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
|
||||
|
|
@ -49,24 +49,24 @@ const config = {
|
|||
sidebarPath: './sidebars.js',
|
||||
// Please change this to your repo.
|
||||
// Remove this to remove the "edit this page" links.
|
||||
editUrl:
|
||||
'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
|
||||
},
|
||||
blog: {
|
||||
showReadingTime: true,
|
||||
feedOptions: {
|
||||
type: ['rss', 'atom'],
|
||||
xslt: true,
|
||||
},
|
||||
// Please change this to your repo.
|
||||
// Remove this to remove the "edit this page" links.
|
||||
editUrl:
|
||||
'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
|
||||
// Useful options to enforce blogging best practices
|
||||
onInlineTags: 'warn',
|
||||
onInlineAuthors: 'warn',
|
||||
onUntruncatedBlogPosts: 'warn',
|
||||
// editUrl:
|
||||
// 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
|
||||
},
|
||||
// blog: {
|
||||
// showReadingTime: true,
|
||||
// feedOptions: {
|
||||
// type: ['rss', 'atom'],
|
||||
// xslt: true,
|
||||
// },
|
||||
// // Please change this to your repo.
|
||||
// // Remove this to remove the "edit this page" links.
|
||||
// // editUrl:
|
||||
// // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
|
||||
// // Useful options to enforce blogging best practices
|
||||
// onInlineTags: 'warn',
|
||||
// onInlineAuthors: 'warn',
|
||||
// onUntruncatedBlogPosts: 'warn',
|
||||
// },
|
||||
theme: {
|
||||
customCss: './src/css/custom.css',
|
||||
},
|
||||
|
|
@ -83,24 +83,26 @@ const config = {
|
|||
respectPrefersColorScheme: true,
|
||||
},
|
||||
navbar: {
|
||||
title: 'My Site',
|
||||
title: 'CDR Link',
|
||||
logo: {
|
||||
alt: 'My Site Logo',
|
||||
src: 'img/logo.svg',
|
||||
alt: '',
|
||||
src: 'img/link-logo.png',
|
||||
// href: 'https://www.digiresilience.org/solutions/link/',
|
||||
// target: '_self',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'tutorialSidebar',
|
||||
sidebarId: 'docsSidebar',
|
||||
position: 'left',
|
||||
label: 'Tutorial',
|
||||
},
|
||||
{to: '/blog', label: 'Blog', position: 'left'},
|
||||
{
|
||||
href: 'https://github.com/facebook/docusaurus',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
label: 'Documentation',
|
||||
},
|
||||
// {to: '/blog', label: 'Blog', position: 'left'},
|
||||
// {
|
||||
// href: 'https://github.com/facebook/docusaurus',
|
||||
// label: 'GitHub',
|
||||
// position: 'right',
|
||||
// },
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
|
|
@ -110,25 +112,29 @@ const config = {
|
|||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Tutorial',
|
||||
to: '/docs/intro',
|
||||
label: 'Agent Guide',
|
||||
to: '/docs/category/agent-guide',
|
||||
},
|
||||
{
|
||||
label: 'Admin Guide',
|
||||
to: '/docs/category/admin-guide',
|
||||
},
|
||||
{
|
||||
label: 'Operator Guide',
|
||||
to: '/docs/category/operator-guide',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
title: 'Policy',
|
||||
items: [
|
||||
{
|
||||
label: 'Stack Overflow',
|
||||
href: 'https://stackoverflow.com/questions/tagged/docusaurus',
|
||||
label: 'Code of Practice',
|
||||
href: 'https://digiresilience.org/about/code-practice/',
|
||||
},
|
||||
{
|
||||
label: 'Discord',
|
||||
href: 'https://discordapp.com/invite/docusaurus',
|
||||
},
|
||||
{
|
||||
label: 'X',
|
||||
href: 'https://x.com/docusaurus',
|
||||
label: 'Code of Conduct',
|
||||
href: 'https://digiresilience.org/about/code-conduct/',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -136,23 +142,23 @@ const config = {
|
|||
title: 'More',
|
||||
items: [
|
||||
{
|
||||
label: 'Blog',
|
||||
to: '/blog',
|
||||
},
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/facebook/docusaurus',
|
||||
label: 'GitLab',
|
||||
href: 'https://gitlab.com/digiresilience/link/',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`,
|
||||
copyright: `Copyright © 2021-${new Date().getFullYear()}. This documentation is made available to you under the terms of the Creative Commons Attribution 4.0 International licence.`,
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
},
|
||||
}),
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
themes: ['@docusaurus/theme-mermaid'],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
1326
package-lock.json
generated
1326
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -17,6 +17,7 @@
|
|||
"dependencies": {
|
||||
"@docusaurus/core": "3.9.2",
|
||||
"@docusaurus/preset-classic": "3.9.2",
|
||||
"@docusaurus/theme-mermaid": "^3.9.2",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
const sidebars = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
docsSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
|
||||
// But you can create a sidebar manually
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -50,15 +50,15 @@ function Feature({Svg, title, description}) {
|
|||
}
|
||||
|
||||
export default function HomepageFeatures() {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
return ( <></>
|
||||
// <section className={styles.features}>
|
||||
// <div className="container">
|
||||
// <div className="row">
|
||||
// {FeatureList.map((props, idx) => (
|
||||
// <Feature key={idx} {...props} />
|
||||
// ))}
|
||||
// </div>
|
||||
// </div>
|
||||
// </section>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,6 @@ function HomepageHeader() {
|
|||
{siteConfig.title}
|
||||
</Heading>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className="button button--secondary button--lg"
|
||||
to="/docs/intro">
|
||||
Docusaurus Tutorial - 5min ⏱️
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
|
@ -32,8 +25,8 @@ export default function Home() {
|
|||
const {siteConfig} = useDocusaurusContext();
|
||||
return (
|
||||
<Layout
|
||||
title={`Hello from ${siteConfig.title}`}
|
||||
description="Description will go into a meta tag in <head />">
|
||||
title={`${siteConfig.title}`}
|
||||
description="A guide for agents, admins, and operators of the CDR Link secure helpdesk platform.">
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
<HomepageFeatures />
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-image: linear-gradient(270deg, rgb(255, 113, 21), rgb(250, 201, 66));
|
||||
}
|
||||
|
||||
@media screen and (max-width: 996px) {
|
||||
|
|
|
|||
25
static/img/cdr-logo.svg
Normal file
25
static/img/cdr-logo.svg
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<svg width="840" height="857" viewBox="0 0 840 857" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="41" y="41" width="758" height="775">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M79.6604 41.0193L798.203 78.6581L759.543 815.981L41.0001 778.342L79.6604 41.0193Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M257.577 179.457L247.85 411.222C247.844 411.412 247.788 411.599 247.694 411.765L117.322 637.207C116.619 638.415 114.772 637.612 115.179 636.276L255.282 179.066C255.685 177.745 257.633 178.08 257.577 179.457ZM611.39 284.61L712.43 561.445C712.877 562.67 711.297 563.603 710.441 562.62L329.394 124.082C328.523 123.082 329.712 121.636 330.86 122.294L608.648 281.356C609.917 282.086 610.888 283.234 611.39 284.61ZM272.819 430.195L698.005 613.883C699.063 614.342 698.9 615.888 697.776 616.112L97.5989 737.09C96.6075 737.286 95.845 736.222 96.3522 735.349L272.819 430.195ZM279.391 398.465L290.666 129.839C290.71 128.779 292.029 128.317 292.728 129.121L673.189 566.981C674.009 567.924 672.985 569.324 671.84 568.83L280.1 399.588C279.657 399.398 279.374 398.949 279.391 398.465ZM633.872 260.097L269.832 51.6458C266.383 49.6734 261.996 51.4057 260.831 55.2071L41.603 770.65C40.2278 775.135 44.1502 779.467 48.7517 778.537L764.408 634.286C768.128 633.535 770.305 629.651 769.007 626.089L636.614 263.351C636.112 261.979 635.137 260.826 633.872 260.097Z" fill="url(#paint0_linear)"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="0.00927734" y="0.00976562" width="839.184" height="856.98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="20.5"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0471014 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear" x1="368.206" y1="875.676" x2="614.412" y2="219" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#ED633A"/>
|
||||
<stop offset="1" stop-color="#FEE128"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 15 KiB |
BIN
static/img/link-logo.png
Normal file
BIN
static/img/link-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Loading…
Add table
Add a link
Reference in a new issue