Skip to content

DecentraLabsCom/Lab-Gateway

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

577 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ DecentraLabs Gateway

Gateway Tests Security Scan Release

🎯 Overview

DecentraLabs Gateway provides a complete blockchain-based authentication system for laboratory access. It includes all components needed for a decentralized lab access solution with advanced features, wallet management, billing and service-credit operations, and remote FMU access through generated proxy.fmu artifacts.

This repository corresponds to the provider+consumer deployment mode. In that mode, the institution can publish labs, expose authentication endpoints, and also fund reservation/access costs for its own users.

If you need only a funding and cost-management backend for your own users, without publishing labs or exposing provider auth endpoints, use blockchain-services in standalone consumer-only mode instead.

πŸ—οΈ Architecture

flowchart LR
    User["User wallet / JWT / FMI tool"]
    OpenResty["OpenResty"]
    Blockchain["blockchain-services"]
    Guacamole["Guacamole"]
    FmuFacade["fmu-runner (public FMU facade)"]
    Ops["ops-worker"]
    Mysql[("MySQL")]
    Contracts["Smart contracts"]
    Station["Lab Station"]

    User --> OpenResty
    OpenResty --> Blockchain
    OpenResty --> Guacamole
    OpenResty --> FmuFacade
    OpenResty --> Ops
    Blockchain --> Contracts
    Blockchain --> Mysql
    Guacamole --> Mysql
    FmuFacade -. target internal backend .-> Station
Loading

FMU Remote Architecture

sequenceDiagram
    participant Tool as FMI Tool
    participant Proxy as proxy.fmu
    participant Gateway as Lab Gateway
    participant Auth as blockchain-services
    participant Station as Lab Station
    participant Model as real .fmu

    Tool->>Proxy: FMI 2 calls
    Proxy->>Gateway: WSS /fmu/api/v1/fmu/sessions
    Gateway->>Auth: issue/redeem session ticket
    Gateway->>Station: internal FMU describe/run/stream/session calls
    Station->>Model: load / initialize / step / outputs
    Station-->>Gateway: state and outputs
    Gateway-->>Proxy: model.description / sim.state / sim.outputs
    Proxy-->>Tool: FMI 2 responses
Loading

FMU target model:

  • The real .fmu remains on Lab Station.
  • The Gateway keeps the public REST/WSS surface, proxy generation, auth and ticketing.
  • The generated proxy.fmu contains interface metadata, runtime binaries and reservation-scoped config, never the real model.
  • This repository keeps a local FMU execution path in fmu-runner as a permanent dev/test mode. That local path is not the intended production topology.

🌟 Features

βœ… Blockchain Authentication

  • Flexible Signature Verification: Users authenticate using their crypto wallet or SSO credentials in an external trusted system that emits a signed JWT
  • Smart Contract Integration: Validates users' lab reservations on-chain
  • JWT Token Generation: Issues secure access tokens for lab sessions (to be consumed by Guacamole)

βœ… Blockchain Services (Spring Boot)

  • RESTful API: Comprehensive authentication endpoints
  • Blockchain Integration: Web3j for smart contract interaction
  • JWT Management: Token validation and generation
  • Wallet Operations: Create, import, and manage Ethereum wallets
  • Service-Credit Billing: Managed credit issuance with spending limits and period controls
  • Health Monitoring: Built-in health checks and metrics

βœ… Lab Access & Management (OpenResty & Guacamole)

  • Apache Guacamole Integration: Clientless RDP/VNC/SSH access through the browser
  • Session Cookie Management: JTI-based session validation with automatic expiration
  • Header Propagation: Authenticated username forwarded to Guacamole for auto-login
  • Ops Worker: Remote power management for lab stations (Wake-on-LAN, shutdown)

βœ… Remote FMU Access

  • Generated proxy.fmu delivery: Reservation-scoped download with signed metadata and one-shot session tickets
  • Public WSS facade: Stable WSS /fmu/api/v1/fmu/sessions contract for generated runtimes
  • Station-based execution target: Real FMUs are meant to live and execute on Lab Station, with Gateway acting as facade and router across internal REST/WSS channels
  • Permanent dev/test backend: Local FMU execution in fmu-runner remains available for development, smoke tests and automated tests

πŸš€ Quick Deployment

Choose an Installation Mode

Use one of these modes depending on your target:

  1. Setup Scripts (setup.sh / setup.bat)
    Best for first-time installs. It prepares env files, secrets, and can start the full stack.

  2. Manual Docker Compose
    Best if you want full control over compose commands and deployment flow.

  3. NixOS Compose-managed Host (nixos-rebuild --flake ...#gateway)
    Best for dedicated NixOS hosts where you want declarative system + service management.

Using Setup Scripts (Recommended)

The setup scripts will automatically:

  • βœ… Check Docker, Docker Compose, and Git prerequisites
  • βœ… Initialize/refresh the blockchain-services submodule and env files
  • βœ… Configure environment variables (database, domain, blockchain, CORS)
  • βœ… Generate database passwords
  • βœ… Create the blockchain-data/ directory for wallet persistence
  • βœ… Optionally start every container with docker compose up -d
  • βœ… Ask if you want to enable a Cloudflare Tunnel so the gateway is reachable without a public IP/DNS
  • βœ… Configure Guacamole admin credentials
  • βœ… Generate OPS worker secret for lab power operations
  • β˜‘οΈ Remind you to create/import the institutional wallet later from the blockchain-services web console

Windows:

setup.bat

Linux/macOS:

chmod +x setup.sh
./setup.sh

That's it! The script will guide you through the setup and start all services automatically.

NixOS Deployment

This repository also includes a flake.nix with:

  • nixosModules.default: NixOS module to manage the stack through systemd
  • nixosModules.gateway-host: host defaults for a dedicated NixOS gateway machine
  • nixosConfigurations.gateway: complete host config ready for nixos-rebuild

NixOS host configuration (compose-managed)

This mode is only for NixOS machines.

Use the module directly (example):

{
  inputs.lab-gateway.url = "path:/srv/lab-gateway";

  outputs = { nixpkgs, lab-gateway, ... }: {
    nixosConfigurations.gateway = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        lab-gateway.nixosModules.default
        {
          services.lab-gateway = {
            enable = true;
            projectDir = "/srv/lab-gateway";
            envFile = "/srv/lab-gateway/.env";
            # profiles = [ "cloudflare" ];
          };
        }
      ];
    };
  };
}

Then apply it:

sudo nixos-rebuild switch --flake /srv/lab-gateway#gateway

Complete host flow (real machine):

# 1) Put this repo on the target NixOS host
sudo mkdir -p /srv
sudo git clone https://github.com/DecentraLabsCom/lite-lab-gateway.git /srv/lab-gateway
cd /srv/lab-gateway

# 2) Prepare env files
sudo cp .env.example .env
sudo cp blockchain-services/.env.example blockchain-services/.env

# 3) Edit values (passwords, domain, tokens, RPC, contract address)
sudo nano .env
sudo nano blockchain-services/.env

# 4) Apply the full NixOS configuration shipped by this flake
sudo nixos-rebuild switch --flake /srv/lab-gateway#gateway

# 5) Validate the service
systemctl status lab-gateway.service

blockchain-services/.env must still exist under projectDir, because docker-compose.yml references it directly.

nixosConfigurations.gateway imports your existing /etc/nixos/configuration.nix and layers the gateway module on top, so host-specific settings (bootloader, users, disks, hardware) are preserved. Host-level values (hostname, timezone, firewall, profiles, SSH hardening) are installation-specific and should be overridden per environment.

Manual Deployment

If you prefer manual configuration:

  1. Copy environment template:

    cp .env.example .env
    cp blockchain-services/.env.example blockchain-services/.env
  2. Edit .env and blockchain-services/.env with your configuration (see Configuration section below)

  • Configure the two gateway access tokens for production:
    • ADMIN_ACCESS_TOKEN: protects wallet/billing routes (/wallet, /billing, /wallet-dashboard, /billing/admin/**)
    • LAB_MANAGER_TOKEN: protects /lab-manager and /ops from public networks
  • For this repository's normal provider+consumer deployment, also set these in blockchain-services/.env:
    FEATURES_PROVIDERS_ENABLED=true
    FEATURES_PROVIDERS_REGISTRATION_ENABLED=true
  1. Set host UID/GID for bind mounts (Linux/macOS) so containers can write to certs/ and blockchain-data/:

    # Choose the user that will own the folders
    id -u
    id -g

    Then set in .env (use 0/0 if you run everything as root):

    HOST_UID=1000
    HOST_GID=1000

    Ensure the folders are owned by that user:

    chown -R 1000:1000 certs blockchain-data
  2. Add SSL certificates to certs/ folder:

    certs/
    β”œβ”€β”€ fullchain.pem      # SSL certificate chain
    β”œβ”€β”€ privkey.pem        # SSL private key
    └── public_key.pem     # JWT public key (optional if blockchain-services generates it)
    

    public_key.pem is generated automatically by blockchain-services on first start when missing. You only need to provide it manually if you use an external auth signer.

    Database schema: When blockchain-services has a MySQL datasource configured, it runs Flyway migrations on startup to create the auth, WebAuthn, and intents tables automatically.

  3. Start the services:

    docker compose up -d --build

βš™οΈ Configuration

πŸ”§ Environment Variables

The gateway uses modular configuration with separate .env files:

  • .env - Gateway-specific configuration (server, database, Guacamole)
  • blockchain-services/.env - Blockchain service configuration (contracts, wallets, RPC)

This separation keeps concerns isolated and makes the blockchain service independently configurable.

Gateway Configuration (.env)

# Basic Configuration
SERVER_NAME=yourdomain.com
HTTPS_PORT=443
HTTP_PORT=80

# OpenResty bind address (127.0.0.1 for local-only, 0.0.0.0 for public)
OPENRESTY_BIND_ADDRESS=0.0.0.0
# OpenResty bind ports (local ports on the host)
OPENRESTY_BIND_HTTPS_PORT=443
OPENRESTY_BIND_HTTP_PORT=80

# Host UID/GID for bind mounts (Linux/macOS)
HOST_UID=1000
HOST_GID=1000

# Database Configuration
MYSQL_ROOT_PASSWORD=secure_password
MYSQL_DATABASE=guacamole_db
MYSQL_USER=guacamole_user
MYSQL_PASSWORD=db_password
BLOCKCHAIN_MYSQL_DATABASE=blockchain_services

# Guacamole
GUAC_ADMIN_USER=guacadmin
GUAC_ADMIN_PASS=secure_admin_password
AUTO_LOGOUT_ON_DISCONNECT=true

# OpenResty CORS allowlist (comma-separated, optional)
CORS_ALLOWED_ORIGINS=https://your-frontend.com,https://marketplace.com

# Lab Manager + Ops Worker
LAB_MANAGER_TOKEN=your_lab_manager_token
LAB_MANAGER_TOKEN_HEADER=X-Lab-Manager-Token
LAB_MANAGER_TOKEN_COOKIE=lab_manager_token

# Blockchain Services remote access
ADMIN_ACCESS_TOKEN=your_admin_access_token
ADMIN_ACCESS_TOKEN_HEADER=X-Access-Token
ADMIN_ACCESS_TOKEN_COOKIE=access_token
ADMIN_ACCESS_TOKEN_REQUIRED=true
ADMIN_DASHBOARD_LOCAL_ONLY=true
ADMIN_ALLOWED_CIDRS=
SECURITY_ALLOW_PRIVATE_NETWORKS=false
ADMIN_DASHBOARD_ALLOW_PRIVATE=false

# Certbot / ACME (optional - for Let's Encrypt automation)
CERTBOT_DOMAINS=yourdomain.com,www.yourdomain.com
CERTBOT_EMAIL=you@example.com
CERTBOT_STAGING=0

Use a strong GUAC_ADMIN_PASS. Common defaults are rejected at startup to avoid insecure deployments. The same check applies to MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD (defaults like CHANGE_ME will stop MySQL from initializing). Set a strong LAB_MANAGER_TOKEN (or leave it empty to keep /ops disabled and /lab-manager private-network-only). Set ADMIN_ACCESS_TOKEN to protect wallet/billing endpoints exposed through OpenResty for remote access.

blockchain-services uses a dedicated schema named blockchain_services by default. If you want a different name, set BLOCKCHAIN_MYSQL_DATABASE in .env.

OpenResty and blockchain-services derive public URLs (issuer, OpenID metadata, etc.) from SERVER_NAME and HTTPS_PORT. If you ever need to override that computed value, set BASE_DOMAIN inside blockchain-services/.env or export it in the container's environment. All authentication endpoints live under the fixed /auth base path to match both services.

Gateway mode: Full vs Lite
  • Full mode: leave ISSUER empty. This gateway exposes its own auth endpoints and validates its own locally generated JWT signing keys.
  • Lite mode: set ISSUER=https://<full-gateway-or-external-issuer>/auth. This gateway no longer acts as the JWT issuer. Instead, it trusts JWTs issued elsewhere and synchronizes the remote public key automatically.
Deployment modes: Direct vs Router forwarding
  • Direct (default): Gateway has a public IP or you're testing locally.

    • Local-only access: OPENRESTY_BIND_ADDRESS=127.0.0.1
    • Public access: OPENRESTY_BIND_ADDRESS=0.0.0.0
    • If you change HTTPS_PORT/HTTP_PORT, also set OPENRESTY_BIND_HTTPS_PORT/OPENRESTY_BIND_HTTP_PORT to the same values.
    docker compose up -d
  • Behind a router/NAT: External traffic arrives via port forwarding (e.g., router:8043 -> host:443). Set OPENRESTY_BIND_ADDRESS=0.0.0.0.

    • Public port (what clients use): HTTPS_PORT=8043
    • Local bind port (what the host listens on): OPENRESTY_BIND_HTTPS_PORT=443
    docker compose up -d

Optional Cloudflare Tunnel settings (filled automatically if you opt in during setup):

CLOUDFLARE_TUNNEL_TOKEN=your_cloudflare_tunnel_token_or_empty_for_quick_tunnel

Runtime activation requires Compose profiles (--profile cloudflare or --profile cloudflare-token).

Blockchain Service Configuration (blockchain-services/.env)

# Smart Contract
CONTRACT_ADDRESS=0xYourSmartContractAddress

# Network RPC URLs (with failover support)
ETHEREUM_MAINNET_RPC_URL=https://eth.public-rpc.com
ETHEREUM_SEPOLIA_RPC_URL=https://ethereum-sepolia-rpc.publicnode.com,https://0xrpc.io/sep,https://ethereum-sepolia-public.nodies.app

# Institutional Wallet (for automated transactions)
INSTITUTIONAL_WALLET_ADDRESS=0xYourWalletAddress
INSTITUTIONAL_WALLET_PASSWORD=YourSecurePassword

# Security
ALLOWED_ORIGINS=https://your-frontend.com,https://marketplace.com
MARKETPLACE_PUBLIC_KEY_URL=https://marketplace.com/.well-known/public-key.pem

Access Controls (Important)

  • /wallet-dashboard, /wallet, /billing: require ADMIN_ACCESS_TOKEN for non-private clients. If the token is unset, access is limited to loopback/Docker networks.
  • /billing/admin/**: uses ADMIN_ACCESS_TOKEN only (header/cookie). If the token is unset, access is limited to loopback/Docker ranges.
  • /billing/admin/execute: additionally requires an EIP-712 signature from the institutional wallet, including a fresh timestamp.
  • Initial setup: Click "Wallet & Treasuryβ†’" from the homepage, enter your ADMIN_ACCESS_TOKEN when prompted. The token will be stored in your browser and automatically included in all requests.
  • Strict localhost-only mode for the wallet dashboard and related wallet/billing routes: ADMIN_DASHBOARD_LOCAL_ONLY=true, ADMIN_DASHBOARD_ALLOW_PRIVATE=false, SECURITY_ALLOW_PRIVATE_NETWORKS=false
  • Private-network mode for those routes: ADMIN_DASHBOARD_LOCAL_ONLY=true, ADMIN_DASHBOARD_ALLOW_PRIVATE=true, SECURITY_ALLOW_PRIVATE_NETWORKS=true, and keep ADMIN_ACCESS_TOKEN_REQUIRED=true
  • To limit private-network mode to specific subnets, set ADMIN_ALLOWED_CIDRS: ADMIN_ALLOWED_CIDRS=10.20.0.0/16,192.168.50.0/24
  • /lab-manager: allows loopback and RFC1918 private networks by default; requires LAB_MANAGER_TOKEN for non-private clients. Click "Lab Managerβ†’" from the homepage and enter your token when prompted. The bootstrap ?token=... is stripped from the browser URL after the cookie is set.
  • /ops: network-restricted to loopback plus RFC1918 private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), and also requires LAB_MANAGER_TOKEN.
  • /aas-admin/**: always requires LAB_MANAGER_TOKEN via header/cookie, even from private networks. This keeps AAS write operations aligned with explicit admin auth instead of LAN-only trust.
  • If wallet actions return JSON.parse errors in the browser, ensure CORS_ALLOWED_ORIGINS includes your gateway origin.

Institutional Wallet Setup

The institutional wallet is managed automatically by blockchain-services:

  1. First-time setup: Create or import the wallet via:

    • Web console: https://localhost:8443/wallet-dashboard (or https://your-domain/wallet-dashboard)
    • Or API: Call /wallet/create or /wallet/import endpoints
  2. Automatic configuration: After creation/import, blockchain-services automatically:

    • Stores the encrypted wallet in blockchain-data/wallets.json
    • Writes credentials to blockchain-data/wallet-config.properties
    • Loads the wallet on every restart using the stored configuration
  3. Manual override (optional): Only needed if using external secret management:

    # In blockchain-services/.env - leave empty for automatic configuration
    INSTITUTIONAL_WALLET_ADDRESS=  # Auto-configured from wallet-config.properties
    INSTITUTIONAL_WALLET_PASSWORD= # Auto-configured from wallet-config.properties

The encrypted wallet and configuration files are stored in blockchain-data/ which is mounted as a Docker volume and excluded from git.

πŸ’» System Requirements

Operating System:

  • Linux (recommended) - Ubuntu 20.04+, Debian 11+, CentOS 8+
  • Unix-like systems (BSD, macOS) - supported
  • Windows - via WSL2 or Docker Desktop

Hardware (Minimum):

  • 2 CPU cores
  • 4GB RAM
  • 20GB disk space (including Docker images and logs)
  • Network interface with internet connectivity

Software:

  • Docker Engine 20.10+ (Linux) or Docker Desktop (Windows/macOS)
  • Docker Compose 2.0+ (included with Docker Desktop)

Network Requirements

The Lab Gateway requires network connectivity to:

  1. External Users - To accept incoming HTTP(s) connections
  2. Internal Laboratory Servers - To proxy RDP/VNC/SSH connections

This can be achieved through various network topologies:

Option A: Dual Network Interface (Most Secure)

Internet ──> [NIC1: Public IP] Lab Gateway [NIC2: Private IP] ──> Lab Computers
  • βœ… Two physical or virtual Network Interface Cards (NICs)
  • βœ… Physical network isolation between public and lab networks
  • βœ… Highest security level
  • ❌ Requires specific hardware/VM configuration

Option B: Single Network Interface (Most Common)

Internet ──> Router/Firewall ──> [NIC: Private IP] Lab Gateway ──> Lab Computers
  • βœ… Single NIC with routing configuration
  • βœ… Works with cloud providers (AWS, Azure, GCP, DigitalOcean, etc.)
  • βœ… Works with CDN/proxies (CloudFlare, CloudFront, etc.)
  • βœ… Works with VPS/dedicated servers
  • βœ… Labs accessed via private IPs or VPN tunnels
  • βœ… Most flexible and commonly deployed

Option C: VLAN Segmentation (Enterprise)

Internet ──> [NIC with VLAN tagging] Lab Gateway ──> VLAN 10 / VLAN 20
  • βœ… Single NIC with 802.1Q VLAN tagging
  • βœ… Logical separation of public and lab traffic
  • βœ… Common in enterprise/datacenter environments

🌐 Remote Access without Public IP (Cloudflare Tunnel)

  • Enable the Cloudflare Tunnel option during setup.sh / setup.bat to spin up the cloudflared sidecar (Compose profile cloudflare) and expose the gateway without opening inbound ports.
  • Works behind campus/corporate NAT as long as outbound HTTPS (443) is allowed; WebSockets for Guacamole are supported through the tunnel.
  • Token mode: paste a Cloudflare Tunnel token from your Zero Trust dashboard and Cloudflare will publish the hostname in your zone.
  • Quick Tunnel mode: leave the token empty and a random *.cfargotunnel.com hostname will appear in docker compose --profile cloudflare logs cloudflared.
  • Start/stop with the profile when needed: docker compose --profile cloudflare up -d / docker compose --profile cloudflare down.

πŸ” SSL/TLS Certificates

Development:

  • Self-signed certificates (auto-generated)
  • Valid for localhost testing

Production:

  • Valid SSL certificate from trusted CA
  • Let's Encrypt (free, automated renewal)
  • Commercial certificate providers
  • Wildcard certificates for multiple subdomains

πŸ› οΈ Technology Stack

Core Components

  • OpenResty - Reverse proxy and load balancer with Lua scripting
  • Apache Guacamole - Clientless remote desktop gateway (RDP/VNC/SSH)
  • MySQL 8.0 - Primary database for configuration and user data
  • Docker - Containerization platform with Compose orchestration

Blockchain Integration

  • Blockchain Services (Spring Boot 4.x) - Authentication and wallet operations microservice
  • Web3j - Ethereum blockchain integration library
  • JWT - Generates authentication tokens with blockchain claims
  • Smart Contract Events - Real-time blockchain monitoring

πŸ“ Project Structure

lab-gateway/
β”œβ”€β”€ πŸ“„ flake.nix                 # Nix flake outputs (NixOS config/module)
β”œβ”€β”€ πŸ“„ docker-compose.yml        # Main service orchestration
β”œβ”€β”€ πŸ“„ .env.example              # Gateway configuration template
β”œβ”€β”€ πŸ“„ setup.sh / setup.bat      # Guided setup scripts
β”œβ”€β”€ πŸ“„ selfsigned-refresh.sh     # Self-signed cert helper
β”œβ”€β”€ πŸ“ nix/
β”‚   β”œβ”€β”€ nixos-module.nix         # services.lab-gateway (compose-managed) module
β”‚   └── hosts/gateway.nix        # Host defaults for nixosConfigurations.gateway
β”œβ”€β”€ πŸ“ blockchain-services/       # Blockchain auth/wallet service (submodule)
β”œβ”€β”€ πŸ“ openresty/                # Reverse proxy (Nginx + Lua)
β”‚   β”œβ”€β”€ nginx.conf
β”‚   β”œβ”€β”€ lab_access.conf
β”‚   β”œβ”€β”€ lua/
β”‚   └── tests/                   # Lua unit test runner/specs
β”œβ”€β”€ πŸ“ guacamole/                # Guacamole image customizations
β”œβ”€β”€ πŸ“ mysql/                    # DB bootstrap and schema scripts
β”œβ”€β”€ πŸ“ ops-worker/               # Lab station operations API worker
β”œβ”€β”€ πŸ“ web/                      # Static frontend assets/pages
β”œβ”€β”€ πŸ“ certbot/                  # ACME webroot/support files
β”œβ”€β”€ πŸ“ tests/
β”‚   β”œβ”€β”€ smoke/                   # End-to-end smoke tests
β”‚   └── integration/             # Integration tests with mocks
β”œβ”€β”€ πŸ“ docs/                     # Install guides, eduGAIN integration, and provider tutorials
β”œβ”€β”€ πŸ“ certs/                    # Runtime certificates/keys (not in git)
β”œβ”€β”€ πŸ“ blockchain-data/          # Runtime wallet/provider data (not in git)
└── πŸ“ configuring-lab-connections/ # Guacamole connection setup docs

certs/ and blockchain-data/ are runtime directories and may not exist until first setup. blockchain-services/ is a Git submodule and must be initialized/updated before running the stack.

🀝 Contributing

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

About

Docker container that lab providers can deploy in seconds on any computer to function as a gateway, access and management system for their lab resources

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors