add installation using docker
This commit is contained in:
parent
386b9313ab
commit
d0c28fe0b6
@ -1,61 +1,223 @@
|
||||
# 🛠️ Installation Guide
|
||||
|
||||
This document describes how to deploy the management tool web app to a Kubernetes environment.
|
||||
This document describes how to run the management tool web app using Docker and Kubernetes.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Host Requirements](#host-requirements)
|
||||
- [Software Requirements](#software-requirements)
|
||||
- [Host Setup](#host-setup)
|
||||
- [Prepare host environment](#prepare-host-environment)
|
||||
- [Install CLI tools](#install-cli-tools)
|
||||
- [Install k3s](#install-k3s)
|
||||
- [Install ArgoCD](#install-argocd)
|
||||
- [Git Repo Access](#git-repo-access)
|
||||
- [Deploy App](#deploy-app)
|
||||
- [App config values](#app-config-values)
|
||||
- [deployment.yaml](#deploymentyaml)
|
||||
- [Apply deployment](#apply-deployment)
|
||||
- [Deploy Secrets](#deploy-secrets)
|
||||
- [Secret generation tools](#secret-generation-tools)
|
||||
- [Secret config values](#secret-config-values)
|
||||
- [secrets.yaml](#secretsyaml)
|
||||
- [Apply secrets](#apply-secrets)
|
||||
- [Admin Account](#admin-account)
|
||||
- [Add admin account](#add-admin-account)
|
||||
- [Verification](#verification)
|
||||
- [Host Requirements](#host-requirements)
|
||||
- [Install using Docker](#install-using-docker)
|
||||
- [Software Requirements](#software-requirements-docker)
|
||||
- [Docker compose](#docker-compose)
|
||||
- [Install to Kubernetes](#install-to-kubernetes)
|
||||
- [Software Requirements](#software-requirements-kubernetes)
|
||||
- [Host Setup](#host-setup)
|
||||
- [Prepare host environment](#prepare-host-environment)
|
||||
- [Install CLI tools](#install-cli-tools)
|
||||
- [Install k3s](#install-k3s)
|
||||
- [Install ArgoCD](#install-argocd)
|
||||
- [Git Repo Access](#git-repo-access)
|
||||
- [Deploy App](#deploy-app)
|
||||
- [App config values](#app-config-values)
|
||||
- [deployment.yaml](#deploymentyaml)
|
||||
- [Apply deployment](#apply-deployment)
|
||||
- [Deploy Secrets](#deploy-secrets)
|
||||
- [Secret generation tools](#secret-generation-tools)
|
||||
- [Secret config values](#secret-config-values)
|
||||
- [secrets.yaml](#secretsyaml)
|
||||
- [Apply secrets](#apply-secrets)
|
||||
- [Admin Account](#admin-account)
|
||||
- [Add admin account](#add-admin-account)
|
||||
- [Verification](#verification)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
## Host Requirements
|
||||
|
||||
### Host Requirements
|
||||
| Component | Minimum Requirement |
|
||||
| --------- | --------------------------------------------- |
|
||||
| OS | Centos Stream 9 / Almalinux 9 / Rocky Linux 9 |
|
||||
| CPU | 8 cores |
|
||||
| Memory | 16 GB |
|
||||
| Storage | 100 GB |
|
||||
| Network | Public IP or DNS-resolvable hostname |
|
||||
|
||||
| Component | Minimum Requirement |
|
||||
| --- | --- |
|
||||
| OS | Centos Stream 9 / Almalinux 9 / Rocky Linux 9 |
|
||||
| CPU | 4 cores |
|
||||
| Memory | 8 GB |
|
||||
| Storage | 50 GB |
|
||||
| Network | Public IP or DNS-resolvable hostname |
|
||||
---
|
||||
|
||||
### Software Requirements
|
||||
# Install using Docker
|
||||
|
||||
## Software Requirements (Docker)
|
||||
|
||||
| Software | Version |
|
||||
| --- | --- |
|
||||
| k3s | ≥ 1.33 |
|
||||
| ArgoCD | ≥ 3.1 |
|
||||
| Helm | ≥ 3.19 |
|
||||
| kubeseal | ≥ 0.33 |
|
||||
| -------- | ------- |
|
||||
| Docker | ≥ 28.5 |
|
||||
|
||||
## Docker compose
|
||||
|
||||
Example of docker-compose.yml file:
|
||||
|
||||
```yaml
|
||||
x-db-env: &db-env
|
||||
POSTGRES_DB: em_db
|
||||
POSTGRES_USER: em_db_user
|
||||
POSTGRES_PASSWORD: postgres-secret
|
||||
|
||||
x-opensearch-env: &opensearch-env
|
||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD: opensearch-secret
|
||||
|
||||
x-app-env: &app-env
|
||||
EMGR_ADMIN_EMAIL: admin@example.com
|
||||
EMGR_ADMIN_PASSWORD: secret
|
||||
APP_ENV: prod
|
||||
APP_URL: http://emgr.office.lan:6400
|
||||
BACKEND_URL: http://emgr.office.lan:6500
|
||||
DATABASE_HOST: db
|
||||
OPENSEARCH_HOST: opensearch
|
||||
VALKEY_HOST: valkey
|
||||
UV_CACHE_DIR: /workspace/.uv-cache
|
||||
|
||||
x-app-config: &app-config
|
||||
image: git.abyres.net/elixier/manager:latest
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
init:
|
||||
condition: service_completed_successfully
|
||||
|
||||
services:
|
||||
frontend:
|
||||
<<: *app-config
|
||||
container_name: emgr-frontend
|
||||
environment:
|
||||
<<: [*db-env, *opensearch-env, *app-env]
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
export DATABASE_NAME=$$POSTGRES_DB
|
||||
export DATABASE_USER=$$POSTGRES_USER
|
||||
export DATABASE_PASSWORD=$$POSTGRES_PASSWORD
|
||||
export OPENSEARCH_ADMIN_PASSWORD=$$OPENSEARCH_INITIAL_ADMIN_PASSWORD
|
||||
uv run reflex run --env prod --frontend-only
|
||||
ports:
|
||||
- "6400:3000"
|
||||
|
||||
backend:
|
||||
<<: *app-config
|
||||
container_name: emgr-backend
|
||||
environment:
|
||||
<<: [*db-env, *opensearch-env, *app-env]
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
export DATABASE_NAME=$$POSTGRES_DB
|
||||
export DATABASE_USER=$$POSTGRES_USER
|
||||
export DATABASE_PASSWORD=$$POSTGRES_PASSWORD
|
||||
export OPENSEARCH_ADMIN_PASSWORD=$$OPENSEARCH_INITIAL_ADMIN_PASSWORD
|
||||
uv run reflex run --env prod --backend-only
|
||||
ports:
|
||||
- "6500:8000"
|
||||
|
||||
init:
|
||||
<<: *app-config
|
||||
container_name: emgr-init
|
||||
environment:
|
||||
<<: [*db-env, *opensearch-env, *app-env]
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
export DATABASE_NAME=$$POSTGRES_DB
|
||||
export DATABASE_USER=$$POSTGRES_USER
|
||||
export DATABASE_PASSWORD=$$POSTGRES_PASSWORD
|
||||
export OPENSEARCH_ADMIN_PASSWORD=$$OPENSEARCH_INITIAL_ADMIN_PASSWORD
|
||||
uv run reflex db migrate
|
||||
uv run python cli.py init-opensearch
|
||||
uv run python cli.py create-admin --email=$$EMGR_ADMIN_EMAIL --password=$$EMGR_ADMIN_PASSWORD
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
opensearch:
|
||||
condition: service_healthy
|
||||
restart: "no"
|
||||
|
||||
db:
|
||||
image: docker.io/postgres:17.4
|
||||
container_name: emgr-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
<<: *db-env
|
||||
volumes:
|
||||
- emgr-db:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
valkey:
|
||||
image: docker.io/valkey/valkey:8.0.2
|
||||
container_name: emgr-valkey
|
||||
restart: unless-stopped
|
||||
|
||||
opensearch:
|
||||
image: docker.io/opensearchproject/opensearch:2.19.0
|
||||
container_name: emgr-opensearch
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
<<: *opensearch-env
|
||||
discovery.type: single-node
|
||||
OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m
|
||||
volumes:
|
||||
- emgr-opensearch:/usr/share/opensearch/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"curl -k https://localhost:9200/_cluster/health || exit 1",
|
||||
]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 30s
|
||||
|
||||
volumes:
|
||||
emgr-app:
|
||||
driver: local
|
||||
emgr-db:
|
||||
driver: local
|
||||
emgr-opensearch:
|
||||
driver: local
|
||||
```
|
||||
|
||||
- Change values in `x-db-env`, `x-opensearch-env` & `x-app-env` to actual, secure values.
|
||||
- Make sure to use strong password for `OPENSEARCH_INITIAL_ADMIN_PASSWORD`, refer https://docs.opensearch.org/latest/security/configuration/demo-configuration/
|
||||
- Get image tag at https://git.abyres.net/elixier/-/packages/container/manager/ and replace 'latest' with the actual value at `x-app-config.image`.
|
||||
- If you're changing the port number for frontend and backend at `APP_URL` and `BACKEND_URL`, make sure to also change at `services.frontend.ports` and `services.backend.ports`.
|
||||
|
||||
Run web app:
|
||||
|
||||
```bash
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
The management tool should be accessible at `APP_URL`.
|
||||
|
||||
---
|
||||
|
||||
# Install to Kubernetes
|
||||
|
||||
## Software Requirements (Kubernetes)
|
||||
|
||||
| Software | Version |
|
||||
| -------- | ------- |
|
||||
| k3s | ≥ 1.33 |
|
||||
| ArgoCD | ≥ 3.1 |
|
||||
| Helm | ≥ 3.19 |
|
||||
| kubeseal | ≥ 0.33 |
|
||||
|
||||
## Host Setup
|
||||
|
||||
### Prepare host environment:
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
dnf install tar -y
|
||||
@ -74,6 +236,7 @@ firewall-cmd --reload
|
||||
```
|
||||
|
||||
### Install CLI tools:
|
||||
|
||||
```bash
|
||||
# Install helm
|
||||
mkdir -p /tmp/helm
|
||||
@ -92,11 +255,13 @@ rm -fr kubeseal*
|
||||
```
|
||||
|
||||
### Install k3s:
|
||||
|
||||
```bash
|
||||
curl -sfL https://get.k3s.io | sh -s -
|
||||
```
|
||||
|
||||
### Install ArgoCD:
|
||||
|
||||
```bash
|
||||
helm --kubeconfig=/etc/rancher/k3s/k3s.yaml install -n argocd --create-namespace argocd --version 8.6.1 --set server.service.type=NodePort oci://ghcr.io/argoproj/argo-helm/argo-cd
|
||||
```
|
||||
@ -108,33 +273,38 @@ helm --kubeconfig=/etc/rancher/k3s/k3s.yaml install -n argocd --create-namespace
|
||||
Configure ArgoCD to access to this Git repository.
|
||||
|
||||
1. Generate SSH key pairs.
|
||||
|
||||
```bash
|
||||
ssh-keygen -t rsa -b 4096 -C "root@hostname"
|
||||
```
|
||||
|
||||
2. Add SSH key to Gitea.
|
||||
|
||||
1. Login to https://git.abyres.net.
|
||||
2. Go to the top right menu > Settings > SSH / GPG Keys.
|
||||
3. Click ‘Add Key’:
|
||||
1. Login to https://git.abyres.net.
|
||||
2. Go to the top right menu > Settings > SSH / GPG Keys.
|
||||
3. Click ‘Add Key’:
|
||||
|
||||
- Key Name: `hostname`
|
||||
- Content: *(paste content from ~/.ssh/id_rsa.pub)*
|
||||
- Key Name: `hostname`
|
||||
- Content: _(paste content from ~/.ssh/id_rsa.pub)_
|
||||
|
||||
3. Add Gitea as a known host in ArgoCD.
|
||||
|
||||
1. Run this command:
|
||||
```bash
|
||||
ssh-keyscan -p 30025 gitssh.abyres.net
|
||||
```
|
||||
2. Copy the output, for example:
|
||||
```
|
||||
[gitssh.abyres.net]:30025 ssh-rsa …
|
||||
```
|
||||
3. Login to ArgoCD in the k3s cluster.
|
||||
4. Go to Settings > Repository certificates and known hosts > Add SSH Known Hosts
|
||||
1. Run this command:
|
||||
|
||||
- SSH Known Host Data: *(paste ssh-keyscan output)*
|
||||
```bash
|
||||
ssh-keyscan -p 30025 gitssh.abyres.net
|
||||
```
|
||||
|
||||
2. Copy the output, for example:
|
||||
|
||||
```
|
||||
[gitssh.abyres.net]:30025 ssh-rsa …
|
||||
```
|
||||
|
||||
3. Login to ArgoCD in the k3s cluster.
|
||||
4. Go to Settings > Repository certificates and known hosts > Add SSH Known Hosts
|
||||
|
||||
- SSH Known Host Data: _(paste ssh-keyscan output)_
|
||||
|
||||
---
|
||||
|
||||
@ -143,8 +313,7 @@ ssh-keygen -t rsa -b 4096 -C "root@hostname"
|
||||
### App config values
|
||||
|
||||
- IMAGE_TAG = `1.1.0-build.1866.768ef2c8`
|
||||
- SSH_PRIVATE_KEY = *(paste content from ~/.ssh/id_rsa)*
|
||||
|
||||
- SSH*PRIVATE_KEY = *(paste content from ~/.ssh/id*rsa)*
|
||||
|
||||
### deployment.yaml
|
||||
|
||||
@ -160,12 +329,11 @@ spec:
|
||||
sourceRepos:
|
||||
- ssh://git@gitssh.abyres.net:30025/elixier/manager.git
|
||||
destinations:
|
||||
- namespace: '*'
|
||||
name: '*'
|
||||
- namespace: "*"
|
||||
name: "*"
|
||||
server: https://kubernetes.default.svc
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
@ -182,7 +350,6 @@ stringData:
|
||||
<SSH_PRIVATE_KEY>
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
@ -199,7 +366,6 @@ stringData:
|
||||
<SSH_PRIVATE_KEY>
|
||||
|
||||
---
|
||||
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
@ -207,9 +373,9 @@ metadata:
|
||||
namespace: argocd
|
||||
spec:
|
||||
generators:
|
||||
- list:
|
||||
elements:
|
||||
- tag: <IMAGE_TAG>
|
||||
- list:
|
||||
elements:
|
||||
- tag: <IMAGE_TAG>
|
||||
template:
|
||||
metadata:
|
||||
name: infrastructure
|
||||
@ -291,7 +457,7 @@ spec:
|
||||
automated:
|
||||
enabled: true
|
||||
syncOptions:
|
||||
- ServerSideApply=true
|
||||
- ServerSideApply=true
|
||||
```
|
||||
|
||||
### Apply deployment
|
||||
@ -312,11 +478,11 @@ k3s kubectl apply -f deployment.yaml
|
||||
|
||||
### Secret config values
|
||||
|
||||
- NODE_IP = 192.168.0.10 (*assumption)
|
||||
- FERNET_KEY = *(generated using tool above)*
|
||||
- JWT_SECRET_KEY = *(generated using tool above)*
|
||||
- PRIVATE_PEM = *(generated using tool above)*
|
||||
- PUBLIC_PEM = *(generated using tool above)*
|
||||
- NODE_IP = 192.168.0.10 (\*assumption)
|
||||
- FERNET*KEY = *(generated using tool above)\_
|
||||
- JWT*SECRET_KEY = *(generated using tool above)\_
|
||||
- PRIVATE*PEM = *(generated using tool above)\_
|
||||
- PUBLIC*PEM = *(generated using tool above)\_
|
||||
|
||||
### secrets.yaml
|
||||
|
||||
@ -337,7 +503,6 @@ stringData:
|
||||
JWT_SECRET_KEY: <JWT_SECRET_KEY>
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
@ -372,12 +537,14 @@ You are required to create an initial global admin account in order to login to
|
||||
### Add admin account
|
||||
|
||||
1. Get one of the running backend pods name using this command:
|
||||
|
||||
```bash
|
||||
k3s kubectl get pods -n emgr -l app=backend
|
||||
# Example pod name = backend-784d796dd9-647pw
|
||||
```
|
||||
|
||||
2. Create the initial global admin:
|
||||
|
||||
```bash
|
||||
k3s kubectl exec -it backend-784d796dd9-647pw -n emgr -- uv run cli.py create-admin --email=admin@example.com --password=adminpass123
|
||||
```
|
||||
@ -389,10 +556,13 @@ k3s kubectl exec -it backend-784d796dd9-647pw -n emgr -- uv run cli.py create-ad
|
||||
Assuming the NODE_IP = 192.168.0.10, the management tool components can be accessed at the following addresses:
|
||||
|
||||
- frontend:
|
||||
|
||||
```
|
||||
http://192.168.0.10:30430
|
||||
```
|
||||
|
||||
- backend:
|
||||
|
||||
```
|
||||
http://192.168.0.10:30480
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user