add installation using docker

This commit is contained in:
Azwan b. Amit 2026-01-06 17:42:13 +08:00
parent 386b9313ab
commit d0c28fe0b6

View File

@ -1,61 +1,223 @@
# 🛠️ Installation Guide # 🛠️ 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 ## Table of Contents
- [Prerequisites](#prerequisites) - [Host Requirements](#host-requirements)
- [Host Requirements](#host-requirements) - [Install using Docker](#install-using-docker)
- [Software Requirements](#software-requirements) - [Software Requirements](#software-requirements-docker)
- [Host Setup](#host-setup) - [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) - [Prepare host environment](#prepare-host-environment)
- [Install CLI tools](#install-cli-tools) - [Install CLI tools](#install-cli-tools)
- [Install k3s](#install-k3s) - [Install k3s](#install-k3s)
- [Install ArgoCD](#install-argocd) - [Install ArgoCD](#install-argocd)
- [Git Repo Access](#git-repo-access) - [Git Repo Access](#git-repo-access)
- [Deploy App](#deploy-app) - [Deploy App](#deploy-app)
- [App config values](#app-config-values) - [App config values](#app-config-values)
- [deployment.yaml](#deploymentyaml) - [deployment.yaml](#deploymentyaml)
- [Apply deployment](#apply-deployment) - [Apply deployment](#apply-deployment)
- [Deploy Secrets](#deploy-secrets) - [Deploy Secrets](#deploy-secrets)
- [Secret generation tools](#secret-generation-tools) - [Secret generation tools](#secret-generation-tools)
- [Secret config values](#secret-config-values) - [Secret config values](#secret-config-values)
- [secrets.yaml](#secretsyaml) - [secrets.yaml](#secretsyaml)
- [Apply secrets](#apply-secrets) - [Apply secrets](#apply-secrets)
- [Admin Account](#admin-account) - [Admin Account](#admin-account)
- [Add admin account](#add-admin-account) - [Add admin account](#add-admin-account)
- [Verification](#verification) - [Verification](#verification)
--- ---
## Prerequisites ## Host Requirements
### Host Requirements
| Component | Minimum Requirement | | Component | Minimum Requirement |
| --- | --- | | --------- | --------------------------------------------- |
| OS | Centos Stream 9 / Almalinux 9 / Rocky Linux 9 | | OS | Centos Stream 9 / Almalinux 9 / Rocky Linux 9 |
| CPU | 4 cores | | CPU | 8 cores |
| Memory | 8 GB | | Memory | 16 GB |
| Storage | 50 GB | | Storage | 100 GB |
| Network | Public IP or DNS-resolvable hostname | | Network | Public IP or DNS-resolvable hostname |
### Software Requirements ---
# Install using Docker
## Software Requirements (Docker)
| Software | Version | | Software | Version |
| --- | --- | | -------- | ------- |
| 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 | | k3s | ≥ 1.33 |
| ArgoCD | ≥ 3.1 | | ArgoCD | ≥ 3.1 |
| Helm | ≥ 3.19 | | Helm | ≥ 3.19 |
| kubeseal | ≥ 0.33 | | kubeseal | ≥ 0.33 |
---
## Host Setup ## Host Setup
### Prepare host environment: ### Prepare host environment:
```bash ```bash
# Install dependencies # Install dependencies
dnf install tar -y dnf install tar -y
@ -74,6 +236,7 @@ firewall-cmd --reload
``` ```
### Install CLI tools: ### Install CLI tools:
```bash ```bash
# Install helm # Install helm
mkdir -p /tmp/helm mkdir -p /tmp/helm
@ -92,11 +255,13 @@ rm -fr kubeseal*
``` ```
### Install k3s: ### Install k3s:
```bash ```bash
curl -sfL https://get.k3s.io | sh -s - curl -sfL https://get.k3s.io | sh -s -
``` ```
### Install ArgoCD: ### Install ArgoCD:
```bash ```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 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,6 +273,7 @@ helm --kubeconfig=/etc/rancher/k3s/k3s.yaml install -n argocd --create-namespace
Configure ArgoCD to access to this Git repository. Configure ArgoCD to access to this Git repository.
1. Generate SSH key pairs. 1. Generate SSH key pairs.
```bash ```bash
ssh-keygen -t rsa -b 4096 -C "root@hostname" ssh-keygen -t rsa -b 4096 -C "root@hostname"
``` ```
@ -119,22 +285,26 @@ ssh-keygen -t rsa -b 4096 -C "root@hostname"
3. Click Add Key: 3. Click Add Key:
- Key Name: `hostname` - Key Name: `hostname`
- Content: *(paste content from ~/.ssh/id_rsa.pub)* - Content: _(paste content from ~/.ssh/id_rsa.pub)_
3. Add Gitea as a known host in ArgoCD. 3. Add Gitea as a known host in ArgoCD.
1. Run this command: 1. Run this command:
```bash ```bash
ssh-keyscan -p 30025 gitssh.abyres.net ssh-keyscan -p 30025 gitssh.abyres.net
``` ```
2. Copy the output, for example: 2. Copy the output, for example:
``` ```
[gitssh.abyres.net]:30025 ssh-rsa … [gitssh.abyres.net]:30025 ssh-rsa …
``` ```
3. Login to ArgoCD in the k3s cluster. 3. Login to ArgoCD in the k3s cluster.
4. Go to Settings > Repository certificates and known hosts > Add SSH Known Hosts 4. Go to Settings > Repository certificates and known hosts > Add SSH Known Hosts
- SSH Known Host Data: *(paste ssh-keyscan output)* - SSH Known Host Data: _(paste ssh-keyscan output)_
--- ---
@ -143,8 +313,7 @@ ssh-keygen -t rsa -b 4096 -C "root@hostname"
### App config values ### App config values
- IMAGE_TAG = `1.1.0-build.1866.768ef2c8` - 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 ### deployment.yaml
@ -160,12 +329,11 @@ spec:
sourceRepos: sourceRepos:
- ssh://git@gitssh.abyres.net:30025/elixier/manager.git - ssh://git@gitssh.abyres.net:30025/elixier/manager.git
destinations: destinations:
- namespace: '*' - namespace: "*"
name: '*' name: "*"
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
@ -182,7 +350,6 @@ stringData:
<SSH_PRIVATE_KEY> <SSH_PRIVATE_KEY>
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
@ -199,7 +366,6 @@ stringData:
<SSH_PRIVATE_KEY> <SSH_PRIVATE_KEY>
--- ---
apiVersion: argoproj.io/v1alpha1 apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet kind: ApplicationSet
metadata: metadata:
@ -312,11 +478,11 @@ k3s kubectl apply -f deployment.yaml
### Secret config values ### Secret config values
- NODE_IP = 192.168.0.10 (*assumption) - NODE_IP = 192.168.0.10 (\*assumption)
- FERNET_KEY = *(generated using tool above)* - FERNET*KEY = *(generated using tool above)\_
- JWT_SECRET_KEY = *(generated using tool above)* - JWT*SECRET_KEY = *(generated using tool above)\_
- PRIVATE_PEM = *(generated using tool above)* - PRIVATE*PEM = *(generated using tool above)\_
- PUBLIC_PEM = *(generated using tool above)* - PUBLIC*PEM = *(generated using tool above)\_
### secrets.yaml ### secrets.yaml
@ -337,7 +503,6 @@ stringData:
JWT_SECRET_KEY: <JWT_SECRET_KEY> JWT_SECRET_KEY: <JWT_SECRET_KEY>
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
@ -372,12 +537,14 @@ You are required to create an initial global admin account in order to login to
### Add admin account ### Add admin account
1. Get one of the running backend pods name using this command: 1. Get one of the running backend pods name using this command:
```bash ```bash
k3s kubectl get pods -n emgr -l app=backend k3s kubectl get pods -n emgr -l app=backend
# Example pod name = backend-784d796dd9-647pw # Example pod name = backend-784d796dd9-647pw
``` ```
2. Create the initial global admin: 2. Create the initial global admin:
```bash ```bash
k3s kubectl exec -it backend-784d796dd9-647pw -n emgr -- uv run cli.py create-admin --email=admin@example.com --password=adminpass123 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: Assuming the NODE_IP = 192.168.0.10, the management tool components can be accessed at the following addresses:
- frontend: - frontend:
``` ```
http://192.168.0.10:30430 http://192.168.0.10:30430
``` ```
- backend: - backend:
``` ```
http://192.168.0.10:30480 http://192.168.0.10:30480
``` ```