Skip to content

Added new installation guide #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions docs/how-to-install/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.image {
border: 1px solid #E0E0E0;
}

.menu_item:before {
content: '';
width: 22px;
height: 22px;
margin: auto 8px auto 0;
background-color: var(--ifm-color-content);
}

.menu_item_desktop:before {
background: url("/icon/remote-desktop.svg");
}

.menu_item_commandline:before {
background: url("/icon/console.svg");
}

.menu_item_demoversion:before {
background: url("/icon/openremote.svg");
}

.menu_item_productionready:before {
-webkit-mask-image: url("/icon/package-variant-closed.svg");
mask-image: url("/icon/package-variant-closed.svg");
}

.menu_item_customproject:before {
-webkit-mask-image: url("/icon/tools.svg");
mask-image: url("/icon/tools.svg");
}

.bottom_navigation_container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}

.bottom_navigation_container > * {
flex: 1;
}

/*
.theme-code-block {
background: blue;
}*/
9 changes: 9 additions & 0 deletions docs/how-to-install/using-aws-marketplace.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
sidebar_position: 4
sidebar_label: Using AWS Marketplace
unlisted: true
---

# Install using AWS Marketplace

WIP
190 changes: 190 additions & 0 deletions docs/how-to-install/using-docker.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
sidebar_position: 1
sidebar_label: Using Docker
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import OpenRemoteDemo from '@site/static/img/install-demo.png';
import InsightsDashboard from '@site/static/img/insights-dashboard.png';
import OpenRemoteIcon from '@site/static/icon/openremote.svg';
import DockerIcon from '@site/static/icon/docker-mark-blue.svg';
import OpenInTabIcon from '@site/static/icon/open-in-new.svg';
import DownloadIcon from '@site/static/icon/download.svg';
import ChevronRight from '@site/static/icon/chevron-right.svg';
import styles from './styles.module.css';
import Admonition from '@theme/Admonition';
import {CardElement} from "../util/card-element";

# Install using Docker

The most common installation method for OpenRemote is using [Docker](https://www.docker.com).<br />
It is the most popular tool for providing containerization, which runs our software in its own isolated environment.<br />

We provide easy-to-install configurations using [Docker Compose](https://docs.docker.com/compose/) profiles.<br />
All of our distributions, for both ARM64 and AMD64, are available on [Docker Hub](https://hub.docker.com/u/openremote).<br />

## Prerequisites

<CardElement prefix={DockerIcon} suffix={OpenInTabIcon} url="https://www.docker.com">
<span>Install Docker Engine</span>
<span>Version 18 or higher</span>
</CardElement>
<br />
You'll need access to the Docker CLI during the setup, to start containers using [Docker Compose](https://docs.docker.com/compose/).<br />

{/*<Tabs queryString="prerequisites">
<TabItem value="desktop" label="Using desktop environment" default attributes={{className: [styles.menu_item, styles.menu_item_desktop]}}>
- **Install Docker Desktop**<br />
You can install Docker Desktop on [Windows](https://docs.docker.com/desktop/setup/install/windows-install/), [Mac](https://docs.docker.com/desktop/setup/install/mac-install/) or [Linux](https://docs.docker.com/desktop/setup/install/linux/).<br />
It provides a straightforward GUI (Graphical User Interface) that lets you manage your containers, applications,<br />
and images directly from your machine. All necessary tools for installing OpenRemote come preinstalled.
</TabItem>
<TabItem value="command-line" label="Using command line" attributes={{className: [styles.menu_item, styles.menu_item_commandline]}}>
- **Install Docker Engine for Linux**<br />
Users can install [Docker Engine](https://docs.docker.com/engine/install/) on any Linux distribution for running OpenRemote.<br />
It includes all necessary CLI tools (like Docker Compose) for a smooth installation process.<br />
Other platforms will have to use the [desktop environment](./using-docker?prerequisites=desktop) instead.
</TabItem>
</Tabs>*/}

## Installing OpenRemote

Depending on your project, and the amount of customization you need, we provide steps below.

<Tabs queryString="install">
<TabItem value="demo" label="Demo version" default attributes={{className: [styles.menu_item, styles.menu_item_demoversion]}}>
<img src={OpenRemoteDemo} alt="OpenRemote Demo" className={styles.image} />
*Figure 1. Screenshot of the Manager UI Map page filled with the assets of this setup.*

We distribute a demo version of OpenRemote that includes several assets with simulated data.<br />
It includes automation rules, dashboards, and full administrator control of the software.<br />
The easy setup allows users to discover platform features, without needing additional setup.<br />
<br />

### 1. Download the `docker-compose.yml` file
<CardElement prefix={DockerIcon} suffix={DownloadIcon} url="https://github.com/openremote/openremote/blob/1.3.0/docker-compose.yml">
<span>docker-compose.yml</span>
</CardElement>
<br />
By default, we expose port `80` (HTTP), `443` (HTTPS) and `8883` (MQTT) to the local network.<br />
Make sure the correct firewall routing is set up for public access on these ports.<br />
Alternatively, you can adjust port mapping within the `docker-compose.yml` file; see [here](https://docs.docker.com/compose/how-tos/networking/).<br />
<br />

### 2. Start the OpenRemote stack
Open a terminal in the folder you downloaded the `docker-compose.yml` file in, and run the following command;
```bash
docker-compose -p openremote up -d
```
<br />

### Complete!
You can now visit the Manager UI on **https://localhost**, and log in with username `admin`, and password `secret`.<br />

<Admonition type="note" title="Did an 'Your connection is not private' error appear?">
It is referring to an self-signed SSL certificate that needs to be accepted, as we're running a local demo version.<br />
You can bypass this error, see more information on this [here](https://www.guidingtech.com/top-ways-to-fix-your-connection-is-not-private-in-chrome/).

For a production deployment, with an SSL certificate, check the [production guide](./using-docker?install=production)
</Admonition>
<br />

</TabItem>
<TabItem value="production" label="Production ready" attributes={{className: [styles.menu_item, styles.menu_item_productionready]}}>
<img src={InsightsDashboard} alt="OpenRemote Production demo" className={styles.image} />
*Figure 2. Screenshot of the Manager UI Insights page filled with simulated data.*

This guide will help you setting up a production-ready OpenRemote instance, together with an included proxy service.<br />
It comes without any pre-installed assets or realms, and includes minor tweaks to optimize for production use.<br />
<br />

### 1. Download the `docker-compose.yml` file
<CardElement prefix={DockerIcon} suffix={DownloadIcon} url="https://github.com/openremote/openremote/blob/1.3.0/docker-compose.yml">
<span>docker-compose.yml</span>
</CardElement>
<br />
By default, we expose port `80` (HTTP), `443` (HTTPS) and `8883` (MQTT) to the local network.<br />
Make sure the correct firewall routing is set up for public access on these ports.<br />
Alternatively, you can adjust port mapping within the `docker-compose.yml` file; see [here](https://docs.docker.com/compose/how-tos/networking/).<br />
<br />

### 2. Create an `.env` file in the same folder
You can configure the OpenRemote instance using environment variables.<br />
We create an `.env` file, where we add variables in `ENV_VARIABLE=VALUE` format. See this example here;
```env
OR_HOSTNAME=demo.openremote.app
OR_ADMIN_PASSWORD=secret
```
The most common environment variables are:
- `OR_HOSTNAME` - Configures the accessible hostname URL for all services.
- `OR_ADMIN_PASSWORD` - Sets the initial password for the `admin` username.
- `OR_EMAIL_***` - Configures the mail server to send emails from; full list [here](https://github.com/openremote/openremote/blob/1.3.0/profile/deploy.yml#L172).
- `OR_ADDITIONAL_HOSTNAMES` - Allow additional hostname URLs on top of `OR_HOSTNAME`.

A full list of variables can be viewed [here](https://github.com/openremote/openremote/blob/1.3.0/profile/deploy.yml).<br />
<br />

### 3. Optional steps
<details>
<summary>Configure a wildcard SSL certificate for your custom domain</summary>

By default, we ship a self-signed SSL certificate based on the `OR_HOSTNAME` environment variable.<br />
You can bring your own by including the full certificate chain in a `.pem` file.<br />

Place your `.pem` file in the same folder as your `docker-compose.yml` is located.<br />

After that, you need to modify the `docker-compose.yml` file, to include the following line;
```yml
services:
proxy:
image: openremote/proxy:${PROXY_VERSION:-latest}
// ...
volumes:
- proxy-data:/deployment
- ./cert.pem:/etc/haproxy/certs/00-custom
```
</details>
<br />

### 4. Start the OpenRemote stack
Open a terminal in the same folder, and run the following command;
```bash
docker-compose -p openremote up -d
```
<br />

### Complete!
You can now visit the Manager UI on **https://[yourhostname].com**, and log in with username `admin`, and your password.<br />
<br />

</TabItem>
<TabItem value="custom-project" label="Using a Custom Project" attributes={{className: [styles.menu_item, styles.menu_item_customproject]}}>
Work in progress
</TabItem>
</Tabs>

## Frequently asked questions
<details>
<summary>**Error:** "We are sorry... Invalid parameter: redirect_uri"</summary>

This is a common error when using an unexpected URL to access the Manager.<br />
By default, only `localhost` is accepted, and other hostnames are rejected from access.<br />

You can use the `OR_HOSTNAME` and `OR_ADDITIONAL_HOSTNAMES` environment variables for this.<br />
Check Step 2 of the [Production ready guide](./using-docker?install=production#2-create-an-env-file-in-the-same-folder) for more details on setting these up.
</details>

If your question is not listed, feel free to ask on our [community forum](https://forum.openremote.io)!

## Up next

<div className={styles.bottom_navigation_container}>
<CardElement wide prefix={OpenRemoteIcon} suffix={ChevronRight} url="../user-guide/manager-ui">
<span>Manager UI Guide</span>
<span>Learn more about the User Interface</span>
</CardElement>
<CardElement wide prefix={OpenRemoteIcon} suffix={ChevronRight} url="../user-guide/deploying/custom-deployment">
<span>Custom Deployment</span>
<span>Style the Manager UI to your brand</span>
</CardElement>
</div>
9 changes: 9 additions & 0 deletions docs/how-to-install/using-kubernetes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
sidebar_position: 2
sidebar_label: Using Kubernetes
unlisted: true
---

# Install using Kubernetes

WIP
9 changes: 9 additions & 0 deletions docs/how-to-install/using-openremote-cli.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
sidebar_position: 3
sidebar_label: Using the OpenRemote CLI
unlisted: true
---

# Install using OpenRemote CLI

WIP
18 changes: 18 additions & 0 deletions docs/util/card-element.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import styles from './util.module.css';

export const CardElement = ({prefix: PrefixIcon, suffix: SuffixIcon, children, url, wide}) => (
<a href={url} className={styles.card_container} style={{ width: wide ? '100%' : 'fit-content' }}>
{PrefixIcon && <PrefixIcon className={styles.card_icon_prefix} />}
<div className={styles.card_content}>
<div className={styles.card_title}>
{children?.length ? children[0] : children}
</div>
{children?.length &&
Comment on lines +8 to +10
Copy link
Preview

Copilot AI Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional check 'children?.length' returns true for string values, causing children[0] to extract only the first character instead of the entire string. Consider using Array.isArray(children) to differentiate between an array of elements and a single string.

Suggested change
{children?.length ? children[0] : children}
</div>
{children?.length &&
{Array.isArray(children) ? children[0] : children}
</div>
{Array.isArray(children) &&

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was using children?.length intentionally here.
This condition statement covers both undefined objects and an empty array.
However, I'm not sure whether this is the best solution.
Is this code OK for you?

Comment on lines +8 to +10
Copy link
Preview

Copilot AI Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using children?.length to decide whether to index into children may lead to unintended behavior if children is a string (since strings have a length property). Consider using Array.isArray(children) to ensure children is an array before accessing its elements.

Suggested change
{children?.length ? children[0] : children}
</div>
{children?.length &&
{Array.isArray(children) && children.length > 0 ? children[0] : children}
</div>
{Array.isArray(children) && children.length > 1 &&

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

<div className={styles.card_subtitle}>
{children[1]}
</div>
}
</div>
{SuffixIcon && <SuffixIcon className={styles.card_icon_suffix} />}
</a>
);
57 changes: 57 additions & 0 deletions docs/util/util.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
html[data-theme='dark'] .card_container {
background-color: var(--ifm-color-secondary);
}

.card_container {
display: flex;
align-items: center;
gap: 12px;
background-color: var(--ifm-color-secondary-lightest);
transition: background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default);
padding: 16px 24px;
border-left: 4px solid var(--ifm-color-primary);
border-radius: 2px;
cursor: pointer;
text-decoration: none;
}

html[data-theme='dark'] .card_container:hover {
background-color: var(--ifm-color-secondary-light);
}

.card_container:hover {
background-color: var(--ifm-color-secondary-dark);
text-decoration: none;
}

.card_container > .card_icon_prefix {
color: var(--ifm-color-content);
height: 24px;
}

.card_container > .card_icon_suffix {
color: var(--ifm-color-content);
margin-left: 48px;
height: 24px;
}

.card_container > .card_content {
flex: 1;
}

.card_content {
display: flex;
flex-direction: column;
}

.card_content > .card_title {
font-size: 20px;
font-weight: bold;
color: var(--ifm-color-content);
}

.card_content > .card_subtitle {
font-size: 14px;
font-weight: 400;
color: var(--ifm-color-content);
}
5 changes: 4 additions & 1 deletion docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {Config} from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
import type * as Plugin from "@docusaurus/types/src/plugin";
import type * as OpenApiPlugin from "docusaurus-plugin-openapi-docs";
import {themes as prismThemes} from 'prism-react-renderer';

const config: Config = {
title: 'OpenRemote Documentation',
Expand Down Expand Up @@ -47,7 +48,7 @@ const config: Config = {
theme: {
customCss: [
'./src/css/styles.css',
'./src/css/openapi-docs.css',
'./src/css/openapi-docs.css'
]
},
gtag: {
Expand Down Expand Up @@ -240,6 +241,8 @@ const config: Config = {
],
prism: {
additionalLanguages: ['bash', 'cpp', 'csharp', 'docker', 'groovy', 'java', 'javascript', 'json', 'python', 'ruby'],
theme: prismThemes.github,
darkTheme: prismThemes.dracula
},
algolia: {
apiKey: '18c8ff9992cf5a0b37acb9b008fa7cd9',
Expand Down
13 changes: 13 additions & 0 deletions sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ const sidebars: SidebarsConfig = {
docsSidebar: [
'introduction',
'quick-start',
{
type: "category",
label: "How to install",
link: {
type: "generated-index",
},
items: [
{
type: 'autogenerated',
dirName: 'how-to-install',
},
]
},
{
type: "category",
label: "User Guide",
Expand Down
Loading