FileGrant Infrastructure - Local Setup (OpenShift Local / CRC)
This guide walks you through running the entire FileGrant infrastructure locally on OpenShift Local (CRC) for development and testing purposes.
Overview
This setup runs all services locally without public DNS, SSL certificates, or external Routes. All services are accessed via oc port-forward.
Differences from Production
| Feature | Production | Localhost |
|---|---|---|
| DNS | Public domains | Not required |
| SSL/TLS | TLS edge via Route | Disabled |
| Routes | OpenShift Routes | Disabled (port-forward) |
| Resources | Full CPU/memory | Reduced for local machines |
| Logging stack | Loki + Alloy + Grafana (full resources) | Loki + Alloy + Grafana (reduced resources) |
| Persistence | Large volumes | Small volumes (2-5 Gi) |
Minimum System Requirements
- CPU: 4 cores (8 recommended for CRC)
- RAM: 12 GB (16 GB recommended)
- Disk: 35 GB of free space
Prerequisites
Installing OpenShift Local (CRC)
Download OpenShift Local (CRC)
Go to the Red Hat Console — OpenShift Local page (a free Red Hat account is required).
Download the installer for your operating system:
- Windows: Download the
.msiinstaller, run it, and follow the wizard. CRC will be added to yourPATHautomatically. - macOS: Download the
.pkginstaller and run it, or use Homebrew:brew install --cask crc - Linux (RHEL/Fedora/Ubuntu): Download the
.tar.xzarchive, extract it, and move the binary to yourPATH:tar -xvf crc-linux-amd64.tar.xz sudo cp crc-linux-*-amd64/crc /usr/local/bin/ crc version
On the same page, click Copy pull secret and save it — you will need it when starting CRC for the first time.
- Windows: Download the
Run initial setup and start the cluster
Initial setup (first time only)# Initial setup (first time only) crc setup # Start the cluster with sufficient resources crc start --cpus 6 --memory 14336 --disk-size 50 # When prompted, enter your pull secretConfigure your environment
Configure environmenteval $(crc oc-env) oc login -u kubeadmin -p $(crc console --credentials | grep kubeadmin | awk '{print $NF}') oc statusVerify the cluster
Verify clusteroc get nodes oc version
External Dependencies
MySQL 8.4.8
The application requires a MySQL database running outside the cluster. Start it with Docker:
docker run -d --name mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=rootpassword \
-e MYSQL_DATABASE=filegrant \
-e MYSQL_USER=filegrant \
-e MYSQL_PASSWORD=filegrantpassword \
-v mysql-data:/var/lib/mysql \
mysql:8.4.8Configure Azure Container Registry (ACR) Access
All service images are hosted on Azure Container Registry. Before installing the chart, create the imagePullSecret:
oc new-project filegrant-local
oc create secret docker-registry acr-secret \
--docker-server=cybergrantregistry-cuash9ckhse5gcha.azurecr.io \
--docker-username=<SERVICE_PRINCIPAL_ID> \
--docker-password=<SERVICE_PRINCIPAL_PASSWORD> \
-n filegrant-localInstallation (Three-Phase Deploy)
The installation requires 3 phases because the infrastructure has sequential dependencies:
- FileGrantAPI and RabbitMQ must start first (they are the core services)
- RabbitMQ must be configured (virtual host and first user) before other services can connect
- FGLicense must start to perform the initial EEVMS variable setup in storage (without these variables, EEVMS certificates cannot be authorized)
- Only after the initial setup can you generate certificates for CGSignalR and PDFProcessing and authorize the EEVMS keys
Phase 1: Bootstrap - FileGrantAPI + RabbitMQ + FGLicense
|
+-- Prepare values-secrets.yaml (without EEVMS certificates)
+-- helm install (only FileGrantAPI, RabbitMQ, FGLicense)
+-- Wait for pods to be Running
+-- Configure RabbitMQ (virtual host + first user)
+-- FGLicense: initial EEVMS variable setup in storage
|
Phase 2: Generate certificates and authorize EEVMS
|
+-- Generate PFX certificates for CGSignalR and PDFProcessing
+-- Update values-secrets.yaml with certificates
+-- Port-forward FileGrantAPI
+-- Authorize EEVMS keys
|
Phase 3: Enable all services
|
+-- helm upgrade (CGSignalR and PDFProcessing enabled)
+-- CGSignalR and PDFProcessing start and load secrets from EEVMS
+-- Final verificationStep 1: Create the Initial values-secrets.yaml
Create a values-secrets.yaml file with secrets for the bootstrap services. Do not commit this file to version control (it is already in .gitignore).
EEVMS Certificates
At this stage, EEVMS certificates for CGSignalR and PDFProcessing are not needed yet. They will be added in Phase 2.
cat > values-secrets.yaml << EOF
global:
editorApiKey: "<EDITOR_API_KEY>"
filegrantapi:
secrets:
masterCertificateBase64: "<MASTER_CERT_BASE64>"
masterCertificatePassword: "<MASTER_CERT_PASSWORD>"
secretsAzureConnectionString: "<AZURE_BLOB_CONNECTION_STRING>"
fglicense:
secrets:
monitoringApiKey: "<MONITORING_API_KEY>"
grafanaToken: "<GRAFANA_TOKEN>"
filegrantfe:
env:
pdfProcessingBaseUrl: "<TO_BE_DEFINED>"
officeExcelIconUrl: "<TO_BE_DEFINED>"
officeWordIconUrl: "<TO_BE_DEFINED>"
officeWopisourceUrl: "<TO_BE_DEFINED>"
officeWopitestUrl: "<TO_BE_DEFINED>"
officePowerpointUrl: "<TO_BE_DEFINED>"
officeExcelUrl: "<TO_BE_DEFINED>"
officeWordUrl: "<TO_BE_DEFINED>"
stripePublicKey: "<TO_BE_DEFINED>"
cryptoKey: "<TO_BE_DEFINED>"
remotegrantAgentBaseUrl: "<TO_BE_DEFINED>"
apiBaseUrl: "<TO_BE_DEFINED>"
azureResourcesContainer: "<TO_BE_DEFINED>"
wasmModuleBytes: "0,97,115,109,..."
websocketUrl: "<TO_BE_DEFINED>"
reactPdfLicenseKey: "<TO_BE_DEFINED>"
EOFReplace the placeholders with actual values:
| Placeholder | Value | Notes |
|---|---|---|
<EDITOR_API_KEY> | e.g. eevms-migrate-2026-temp-key | Shared between FileGrantAPI and FGLicense |
<MASTER_CERT_BASE64> | EEVMS master certificate | Base64 of the master PFX |
<MASTER_CERT_PASSWORD> | Master certificate password | |
<AZURE_BLOB_CONNECTION_STRING> | Azure Blob connection string | For EEVMS secrets storage |
<MONITORING_API_KEY> | e.g. Secret! | Shared API key for health checks between services |
<GRAFANA_TOKEN> | e.g. glsa_BQ9fRqh5Aq... | Grafana service account token |
<TO_BE_DEFINED> (frontend variables) | See Frontend Variables table below | Environment variables for the frontend |
Other FGLicense Variables
Other FGLicense variables (monitoring URLs, Grafana configuration) are already configured in values-localhost.yaml with internal cluster URLs (http://filegrantapi:8080, http://cgsignalr:8080, etc.).
Step 2: Phase 1 - Install Bootstrap Services
Install the chart with only FileGrantAPI, RabbitMQ, and FGLicense enabled. CGSignalR and PDFProcessing are disabled because the EEVMS variables do not exist yet:
helm install filegrant . \
--namespace filegrant-local \
--create-namespace \
-f values-localhost.yaml \
-f values-secrets.yaml \
--set cgsignalr.enabled=false \
--set filegrantpdfprocessing.enabled=falseStep 3: Wait for Pods to Be Running
oc get pods -n filegrant-local -wWait until filegrantapi, rabbitmq, and fglicense are in Running state with READY 1/1:
NAME READY STATUS RESTARTS AGE
rabbitmq-0 1/1 Running 0 2m
filegrantfe-xxx-yyy 1/1 Running 0 2m
filegrantapi-xxx-yyy 1/1 Running 0 2m
fglicense-xxx-yyy 1/1 Running 0 2m
loki-0 1/1 Running 0 2m
alloy-xxx-yyy 1/1 Running 0 2m
grafana-xxx-yyy 1/1 Running 0 2mPress Ctrl+C to exit the watch.
Step 4: Configure RabbitMQ
RabbitMQ requires virtual host and first application user configuration before other services can connect.
Open a separate terminal and start the port-forward for the management UI:
oc port-forward -n filegrant-local svc/rabbitmq 15672:15672Open http://localhost:15672 and log in with the credentials configured in values-localhost.yaml (default: admin-rmq / password from the values file).
- Create the Virtual Host: go to Admin > Virtual Hosts, create the vhost required for FileGrant (e.g.
/filegrant) - Create the application user: go to Admin > Users, create the user that services will use to connect to RabbitMQ
- Assign permissions: set the user permissions on the created virtual host (configure, write, read:
.*)
Step 5: FGLicense - Initial EEVMS Variable Setup
FGLicense must perform the initial setup to create all required variables in the EEVMS storage. Without this step, EEVMS certificates cannot be authorized because the variables do not exist yet.
Open a separate terminal and start the port-forward for FGLicense:
oc port-forward -n filegrant-local svc/fglicense 5003:8080Access http://localhost:5003 and complete the initial setup. FGLicense will:
- Create all required variables in the EEVMS storage
- Set initial configuration values (connection strings, JWT keys, etc.)
- Prepare the storage for EEVMS certificate authorization
Required Step
This step is mandatory. If skipped, the EEVMS authorization script (Step 8) will fail with not_found errors for all variables.
Step 6: Generate EEVMS Certificates
Now that the variables exist in storage, generate a PFX certificate for each service that uses EEVMS (CGSignalR and PDFProcessing). The certificates are used to authenticate with FileGrantAPI via RSA signature.
./scripts/generate-eevms-certs.shFor production, use --password to protect the PFX files:
./scripts/generate-eevms-certs.sh --password "A_SECURE_PASSWORD"Expected output:
=============================================
EEVMS Certificate Generation
=============================================
--- cgsignalr ---
Private key: certs/cgsignalr-key.pem
Certificate: certs/cgsignalr-cert.pem
PFX: certs/cgsignalr.pfx
PFX base64: certs/cgsignalr.b64
Public key: certs/cgsignalr-pubkey.pem
--- filegrantpdfprocessing ---
Private key: certs/filegrantpdfprocessing-key.pem
Certificate: certs/filegrantpdfprocessing-cert.pem
PFX: certs/filegrantpdfprocessing.pfx
PFX base64: certs/filegrantpdfprocessing.b64
Public key: certs/filegrantpdfprocessing-pubkey.pemStep 7: Update values-secrets.yaml with Certificates
Add the generated EEVMS certificates to the values-secrets.yaml file:
# Read the base64 values of the generated certificates
SIGNALR_CERT=$(cat certs/cgsignalr.b64)
PDFPROC_CERT=$(cat certs/filegrantpdfprocessing.b64)
# Append CGSignalR and PDFProcessing sections to the file
cat >> values-secrets.yaml << EOF
cgsignalr:
eevms:
apiSecret: "${SIGNALR_CERT}"
apiSecretPassword: ""
filegrantpdfprocessing:
eevms:
apiSecret: "${PDFPROC_CERT}"
apiSecretPassword: ""
EOFManual Alternative
Alternatively, you can manually edit values-secrets.yaml and add the cgsignalr and filegrantpdfprocessing sections.
Step 8: Port-Forward FileGrantAPI and Authorize EEVMS Keys
Open a separate terminal and start the port-forward for FileGrantAPI:
oc port-forward -n filegrant-local svc/filegrantapi 5001:8080Verify it is accessible:
curl -s http://localhost:5001/api/verRun the authorization script. This registers the public keys of the certificates generated in Step 6 in the EEVMS system, so that CGSignalR and PDFProcessing can read the secrets:
./scripts/authorize-eevms-keys.sh \
--api-url http://localhost:5001 \
--api-key "<EDITOR_API_KEY>"API Key
Use the same editorApiKey from your values-secrets.yaml.
Expected output:
=============================================
EEVMS Key Authorization
=============================================
--- cgsignalr (alias: cgsignalr) ---
Authorized: 11
Already authorized: 0
Not found: 0
[+] FILEGRANT-API-JWT-KEY -> authorized
[+] FILEGRANT-API-JWT-ISSUER -> authorized
...
--- filegrantpdfprocessing (alias: filegrantpdfprocessing) ---
Authorized: 10
Already authorized: 0
Not found: 0
[+] FILEGRANT-MASTER-ENCRYPTED-SYMMETRIC-KEY -> authorized
...Variables Not Found
If some variables show not_found, go back to Step 5 and verify that FGLicense has completed the initial setup. The variables must exist in the EEVMS storage before they can be authorized.
Step 9: Phase 3 - Enable All Services
Now that the keys are authorized and the certificates are in values-secrets.yaml, enable CGSignalR and PDFProcessing:
helm upgrade filegrant . \
--namespace filegrant-local \
-f values-localhost.yaml \
-f values-secrets.yamlAll Services Enabled
Without the --set *.enabled=false flags, all services are enabled by default.
This starts:
- CGSignalR -- connects to FileGrantAPI via EEVMS and loads 11 secrets
- PDFProcessing -- connects to FileGrantAPI via EEVMS and loads 10 secrets
Step 10: Verify the Deployment
# Check that all pods are Running
oc get pods -n filegrant-local
# Check CGSignalR logs (should show "EEVMS: Successfully loaded 11 secrets")
oc logs -n filegrant-local -l app=cgsignalr --tail=20
# Check PDFProcessing logs (should show "EEVMS: Successfully loaded 10 secrets")
oc logs -n filegrant-local -l app=filegrantpdfprocessing --tail=20
# Check FGLicense logs (should start without errors)
oc logs -n filegrant-local -l app=fglicense --tail=20Expected output:
NAME READY STATUS RESTARTS AGE
rabbitmq-0 1/1 Running 0 10m
filegrantfe-xxx-yyy 1/1 Running 0 10m
filegrantapi-xxx-yyy 1/1 Running 0 10m
fglicense-xxx-yyy 1/1 Running 0 10m
cgsignalr-xxx-yyy 1/1 Running 0 1m
filegrantpdfprocessing-xxx-yyy 1/1 Running 0 1m
loki-0 1/1 Running 0 10m
alloy-xxx-yyy 1/1 Running 0 10m
grafana-xxx-yyy 1/1 Running 0 10mFGLicense: Environment Variables
Secrets (in values-secrets.yaml)
| Variable | Helm Value | Description |
|---|---|---|
| MONITORING_API_KEY | fglicense.secrets.monitoringApiKey | Shared API key for health checks |
| GRAFANA_TOKEN | fglicense.secrets.grafanaToken | Grafana service account token |
| EDITOR_API_KEY | global.editorApiKey | EEVMS admin API key (shared with FileGrantAPI) |
Configuration (in values-localhost.yaml)
| Variable | Default Value | Description |
|---|---|---|
| FG_API | http://filegrantapi:8080 | FileGrant API URL |
| MONITORING_SIGNALR_URL | http://cgsignalr:8080 | CGSignalR health check |
| MONITORING_RABBITMQ_URL | http://rabbitmq:15672 | RabbitMQ health check |
| MONITORING_PDF_PROCESSING_URL | http://filegrantpdfprocessing:8080 | PDFProcessing health check |
| MONITORING_FILEGRANT_API_URL | http://filegrantapi:8080 | FileGrantAPI health check |
| MONITORING_LISTMONK_URL | https://listmonk-dev.cybergrant.io | Listmonk health check (external) |
| MONITORING_FILEGRANT_FE_URL | http://filegrantfe:8080 | Frontend health check |
| GRAFANA_URL | http://grafana:3000 | Grafana URL |
| GRAFANA_LOKI_DATASOURCE_ID | 1 | Loki datasource ID in Grafana |
| GRAFANA_LOKI_LABEL_KEY | container | Label key for Loki queries |
| GRAFANA_LOKI_SERVICE_NAMES | app-filegrant-1|... | Service names for Loki queries (pipe-separated) |
Override Monitoring URLs
To override a monitoring URL (e.g. point to an external service), use --set:
helm upgrade filegrant . \
-f values-localhost.yaml \
-f values-secrets.yaml \
--set fglicense.env.monitoringSignalrUrl="https://signalr-dev.cybergrant.io"Environment Variables by Service
FileGrantAPI (EEVMS Server)
| Variable | Type | Description |
|---|---|---|
| MASTER_CERTIFICATE_BASE64 | Secret | EEVMS master certificate (base64) |
| MASTER_CERTIFICATE_PASSWORD | Secret | Master certificate password |
| SECRETS_STORAGE_PROVIDER | Config | Storage provider (azureblob) |
| SECRETS_AZURE_CONNECTION_STRING | Secret | Azure Blob Storage connection string |
| SECRETS_AZURE_CONTAINER | Config | Azure container name |
| SECRETS_AZURE_BLOB_NAME | Config | Blob name for encrypted secrets |
| EDITOR_API_KEY | Secret | Admin API key for EEVMS management |
CGSignalR (EEVMS Client)
| Variable | Type | Description |
|---|---|---|
| FILEGRANT_API_URL | Config | FileGrant API URL |
| FILEGRANT_API_SECRET | Secret | PFX certificate (base64) for EEVMS authentication |
| FILEGRANT_API_SECRET_PASSWORD | Secret | PFX password (empty if unprotected) |
PDFProcessing (EEVMS Client)
| Variable | Type | Description |
|---|---|---|
| FILEGRANT_API_URL | Config | FileGrant API URL |
| FILEGRANT_API_SECRET | Secret | PFX certificate (base64) for EEVMS authentication |
| FILEGRANT_API_SECRET_PASSWORD | Secret | PFX password (empty if unprotected) |
FGLicense
| Variable | Type | Description |
|---|---|---|
| FG_API | Config | FileGrant API URL |
| MONITORING_API_KEY | Secret | Shared API key for monitoring |
| MONITORING_SIGNALR_URL | Config | SignalR health check URL |
| MONITORING_RABBITMQ_URL | Config | RabbitMQ health check URL |
| MONITORING_PDF_PROCESSING_URL | Config | PDF Processing health check URL |
| MONITORING_FILEGRANT_API_URL | Config | FileGrant API health check URL |
| MONITORING_LISTMONK_URL | Config | Listmonk health check URL |
| MONITORING_FILEGRANT_FE_URL | Config | Frontend health check URL |
| GRAFANA_URL | Config | Grafana URL |
| GRAFANA_TOKEN | Secret | Grafana service account token |
| GRAFANA_LOKI_DATASOURCE_ID | Config | Loki datasource ID in Grafana |
| GRAFANA_LOKI_LABEL_KEY | Config | Label key for Loki queries |
| GRAFANA_LOKI_SERVICE_NAMES | Config | Service names for Loki queries (pipe-separated) |
| EDITOR_API_KEY | Secret | Editor API key |
FileGrant Frontend
The frontend requires the following environment variables to work correctly. They are configured in values-secrets.yaml under filegrantfe.env:
| Variable | Type | Description |
|---|---|---|
| VITE_APP_PDF_PROCESSING_BASE_URL | Config | PDF Processing service base URL |
| VITE_APP_OFFICE_EXCEL_ICON_URL | Config | Excel icon URL for Office Online |
| VITE_APP_OFFICE_WORD_ICON_URL | Config | Word icon URL for Office Online |
| VITE_APP_OFFICE_WOPISOURCE_URL | Config | WOPI source URL for Office Online |
| VITE_APP_OFFICE_WOPITEST_URL | Config | WOPI test URL (OneNote) |
| VITE_APP_OFFICE_POWERPOINT_URL | Config | PowerPoint Online URL |
| VITE_APP_OFFICE_EXCEL_URL | Config | Excel Online URL |
| VITE_APP_OFFICE_WORD_URL | Config | Word Online URL |
| VITE_APP_STRIPE_PUBLIC_KEY | Config | Stripe public key for payments |
| VITE_APP_CRYPTO_KEY | Config | Application cryptographic key |
| VITE_APP_REMOTEGRANT_AGENT_BASE_URL | Config | RemoteGrant agent base URL |
| VITE_APP_API_BASE_URL | Config | FileGrant API base URL |
| VITE_APP_AZURE_RESOURCES_CONTAINER | Config | Azure container name for resources |
| VITE_APP_WASM_MODULE_BYTES | Config | WASM module bytes (pre-configured) |
| VITE_APP_WEBSOCKET_URL | Config | WebSocket service URL (SignalR) |
| VITE_APP_REACT_PDF_LICENSE_KEY | Config | React PDF license key |
Accessing Services (Port Map)
| Service | Command | URL |
|---|---|---|
| Frontend | oc port-forward -n filegrant-local svc/filegrantfe 4200:8080 | http://localhost:4200 |
| CGSignalR | oc port-forward -n filegrant-local svc/signalrserviceapi 5000:8080 | http://localhost:5000 |
| FileGrantAPI | oc port-forward -n filegrant-local svc/filegrantapi 5001:8080 | http://localhost:5001 |
| PDF Processing | oc port-forward -n filegrant-local svc/filegrantpdfprocessing 5002:8080 | http://localhost:5002 |
| FGLicense | oc port-forward -n filegrant-local svc/fglicense 5003:8080 | http://localhost:5003 |
| RabbitMQ Management | oc port-forward -n filegrant-local svc/rabbitmq 15672:15672 | http://localhost:15672 |
| RabbitMQ AMQP | oc port-forward -n filegrant-local svc/rabbitmq 5672:5672 | amqp://localhost:5672 |
| Grafana | oc port-forward -n filegrant-local svc/grafana 3000:3000 | http://localhost:3000 |
Quick Access Scripts
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/filegrantfe 4200:8080 }
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/signalrserviceapi 5000:8080 }
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/filegrantapi 5001:8080 }
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/filegrantpdfprocessing 5002:8080 }
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/fglicense 5003:8080 }
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/rabbitmq 15672:15672 }
Start-Job -ScriptBlock { oc port-forward -n filegrant-local svc/grafana 3000:3000 }
Write-Host "All port-forwards started."
Write-Host "Run 'Get-Job | Stop-Job' to stop all."#!/bin/bash
oc port-forward -n filegrant-local svc/filegrantfe 4200:8080 &
oc port-forward -n filegrant-local svc/signalrserviceapi 5000:8080 &
oc port-forward -n filegrant-local svc/filegrantapi 5001:8080 &
oc port-forward -n filegrant-local svc/filegrantpdfprocessing 5002:8080 &
oc port-forward -n filegrant-local svc/fglicense 5003:8080 &
oc port-forward -n filegrant-local svc/rabbitmq 15672:15672 &
oc port-forward -n filegrant-local svc/grafana 3000:3000 &
echo "All port-forwards started. Press Ctrl+C to stop."
waitDefault Credentials
| Service | Username | Password |
|---|---|---|
| RabbitMQ | admin-rmq | See values-localhost.yaml |
| Grafana | admin | See values-localhost.yaml |
Optional: Disable the Logging Stack
If you do not need logging, you can disable Loki, Alloy, and Grafana to save resources:
helm upgrade filegrant . \
--namespace filegrant-local \
-f values-localhost.yaml \
--set loki.enabled=false \
--set alloy.enabled=false \
--set grafana.enabled=falseCommon Operations
View Pod Logs
oc logs -n filegrant-local -l app=filegrantapi -f
oc logs -n filegrant-local -l app=signalrserviceapi --tail=50Restart a Service
oc rollout restart deployment filegrantapi -n filegrant-localCheck Resource Usage
oc adm top pods -n filegrant-localUpdate After Code Changes
# Restart with the current image
oc rollout restart deployment filegrantapi -n filegrant-local
# Or update with a specific image tag
helm upgrade filegrant . \
--namespace filegrant-local \
-f values-localhost.yaml \
--set filegrantapi.image.tag=v1.2.3Troubleshooting
CGSignalR or PDFProcessing in CrashLoopBackOff After Phase 2
Cause: EEVMS keys were not authorized, or some variables do not exist in EEVMS.
oc logs -n filegrant-local -l app=cgsignalr --tail=30Typical error messages:
"EEVMS: Not authorized for variable 'XXX'"-- public key not authorized"EEVMS: API returned 401"-- invalid PFX certificate"EEVMS: Failed to initialize"-- FileGrantAPI not reachable
Solution:
Verify FileGrantAPI is Running
oc get pods -n filegrant-local -l app=filegrantapiRe-run the authorization script
oc port-forward -n filegrant-local svc/filegrantapi 5001:8080 ./scripts/authorize-eevms-keys.sh --api-url http://localhost:5001 --api-key "<EDITOR_API_KEY>"Restart the pods
oc rollout restart deployment cgsignalr -n filegrant-local oc rollout restart deployment filegrantpdfprocessing -n filegrant-local
EEVMS Variables "not_found" During Authorization
Cause: The variable does not exist yet in the EEVMS document.
Solution: Create the missing variable (with an empty value for now) and then re-run the authorization:
# Create the missing variable
curl -s -X POST "http://localhost:5001/api/v1/secrets/admin/VARIABLE_NAME" \
-H "X-Editor-Api-Key: <EDITOR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{"value": ""}'
# Re-run the authorization
./scripts/authorize-eevms-keys.sh \
--api-url http://localhost:5001 \
--api-key "<EDITOR_API_KEY>"Pods Stuck in Pending
The machine may not have enough resources. Inspect the pod and node allocation:
oc describe pod -n filegrant-local <pod-name>
oc describe node | grep -A 5 "Allocated resources"Fix: Increase CRC resources (crc stop && crc start --cpus 8 --memory 16384) or disable unnecessary services:
helm upgrade filegrant . \
--namespace filegrant-local \
-f values-localhost.yaml \
--set filegrantpdfprocessing.enabled=false \
--set fglicense.enabled=falsePod in CrashLoopBackOff
# Check current logs
oc logs -n filegrant-local <pod-name>
# Check previous container logs
oc logs -n filegrant-local <pod-name> --previousSCC Errors (Permission Denied)
If a pod does not start due to permission issues:
oc get scc
oc describe scc alloy-scc
oc describe pod -n filegrant-local -l app=alloyPort-Forward Disconnects
Port-forwards may drop due to inactivity. Re-run the command or use the quick access script provided above.
Image Pull Errors
All images are hosted on Azure Container Registry. Verify that the imagePullSecret exists:
oc get secret acr-secret -n filegrant-local
# If missing, recreate it:
oc create secret docker-registry acr-secret \
--docker-server=cybergrantregistry-cuash9ckhse5gcha.azurecr.io \
--docker-username=<SERVICE_PRINCIPAL_ID> \
--docker-password=<SERVICE_PRINCIPAL_PASSWORD> \
-n filegrant-localCleanup
Stop All Services (Keep Data)
oc scale deployment --all -n filegrant-local --replicas=0
oc scale statefulset --all -n filegrant-local --replicas=0Resume Services
helm upgrade filegrant . \
--namespace filegrant-local \
-f values-localhost.yamlUninstall Everything
helm uninstall filegrant -n filegrant-local
oc delete project filegrant-localStop CRC
# Stop (keeps state)
crc stop
# Delete completely
crc deleteDevelopment Tips
- Don't enable everything -- Start only the services you need. Disable PDF Processing and FGLicense if you only need the API.
- Use Grafana for logs -- Access at
http://localhost:3000then navigate to Explore and select Loki as the data source. For quick debugging,oc logs -fworks just as well. - Shell into pods for debugging:
oc exec -it -n filegrant-local deploy/filegrantapi -- /bin/bash - Check internal connectivity between services:
oc exec -n filegrant-local deploy/signalrserviceapi -- curl -s http://rabbitmq:15672 - OpenShift Web Console: CRC provides a web console accessible with:
crc console