LabCaptain is a tiny daemon + CLI tool that helps to deploy lab environment in cluster.
I have planned to build a lab environment or dev platform first. Then thought about this abstraction layer which will help to build and deploy lab environment easily. So, I decided to build this lightweight tool to manage it.
The name LabCaptain
is due to the fact that it takes the responsibility of lab environment management. You will just say it you need to deploy a lab environment for certain period of time and it will do the task.
Now, the most interesing part is -
- Labcaptain project is providing a docker base image, so that you can build your own lab environment easily.
FROM registry.hub.docker.com/tanmoysrt/labcaptain_base # Write your own configuration
- Simple API to manage lab environment.
- Web terminal, code server, VNC, port forwarding is pre-configured out of the box.
- https://terminal-{lab_id}.example.com : Web terminal
- https://editor-{lab_id}.example.com : Code server (VSCode like)
- https://vnc-{lab_id}.example.com : VNC
- https://port-{port_no}.{lab_id}.example.com : Port forwarding out of the box. You can run your own tool inside the container and access it via the url format. Just small restrictions - you cant use 8000, 8001, 8002, 8003, 8004 ports.
To know more, how can you disable specific feature like VNC, check the image documentation. https://hub.docker.com/r/tanmoysrt/labcaptain_base
- Golang
- SQLite3 (for database)
- Podman
- Prometheus (for monitoring)
- HAProxy
- NoVNC + noVNC proxy
- ttyd
Caution
Before we procced, remember these points.
- Your lab deployment lab server doesn't receive incoming traffice directly from internet, Only your
LabCaptain
server or management server receives the traffic. - So, you must use firewall to block incoming traffic from internet to your lab server except the traffic which is coming from your
LabCaptain
server or management server. - If you are hosting all the servers in same cloud provider, consider to create a private network and assign public IP to your
LabCaptain
server. It can communicate with your lab server via private IPs.
Configure SSH Agent
- Generate a ssh private key for all of your other servers (if you haven't already)
Put the private key in
ssh-keygen -t rsa -b 4096 -C "[email protected]"
/root/.ssh/id_rsa
and the public key in/root/.ssh/id_rsa.pub
- Create/edit
/etc/rc.local
file and add the following lineand make that file executable with#!/bin/sh -e eval $(ssh-agent) ssh-add /root/.ssh/id_rsa exit 0
chmod +x /etc/rc.local
and reboot the server. - That's it.
- Install golang (https://go.dev/doc/install)
- Clone the repo
- Go inside
labcaptain
folder - Run
go build
to build the binary - Move the
labcaptain
binary to/usr/local/bin
- Run
labcaptain local-setup
to setup labcaptain on the local machine - Run
labcaptain server add <ip>
to add a new server - Run
labcaptain server list
to list all servers - Run
labcaptain server setup-podman <ip>
to setup podman on the server - Run
labcaptain server setup-prometheus <ip>
to setup prometheus exporter on the server - Run
labcaptain server enable <ip>
to enable a server - Create a systemd service file
/etc/systemd/system/labcaptain.service
like this
[Unit]
Description=LabCaptain
After=network.target
[Service]
WorkingDirectory="<provide_a_path_here_to_store_labcaptain_data>"
User=root
Type=simple
Environment="LAB_CAPTAIN_BASE_DOMAIN=example.com"
Environment="LABCAPTAIN_API_TOKEN=random_secret"
ExecStartPre=/bin/bash -c 'ssh-agent -s | grep -E "SSH_AUTH_SOCK|SSH_AGENT_PID" > /tmp/ssh-agent.env && source /tmp/ssh-agent.env && ssh-add /root/.ssh/id_rsa'
ExecStart=/bin/bash -c 'source /tmp/ssh-agent.env && /usr/local/bin/labcaptain start'
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
- Run
systemctl daemon-reload
andsystemctl enable labcaptain
- Run
systemctl start labcaptain
to start labcaptain
- Deploy a lab
- Method: POST
- URL: http://localhost:8888/start
- Body:
{ "image": "registry.hub.docker.com/tanmoysrt/labcaptain_base:1", "expiry_time": "2024-09-21T13:04:05Z", "web_terminal_enabled": true, "code_server_enabled": true, "vnc_enabled": true, "port_proxy_enabled": true, "environment_variables": "" }
- Response:
{ "id": "tqtw1fl7ku2imcp", "status": "requested", "expiry_time": "2024-01-01T00:00:00Z" }
- Get lab status
- Method: GET
- URL: http://localhost:8888/status/:lab_id
- Response:
{ "id": "tqtw1fl7ku2imcp", "status": "provisioned", "expiry_time": "2024-01-01T00:00:00Z" }
- Stop a lab
- Method: POST
- URL: http://localhost:8888/stop/:lab_id
- Response:
If you got 200 OK, it means the lab is destroyed successfully.
Lab destroyed successfully
- Implement SSH connection pool for faster communication
- Implement support for resource limits
- Configurable option for lab proxy at port 443 ssl (P.S : currently it's also possible by editing
labcaptain/nginx.conf.template
) - Remote storage mount support
MIT License
Special thanks to these projects
- https://github.com/ConSol/docker-headless-vnc-container (Apache License 2.0). It made it possible to have proper configuration for Xfce4 + noVNC setup for headsup.
- https://github.com/tsl0922/ttyd (MIT License). It made it possible to have a web terminal.
- https://github.com/coder/code-server (MIT License). It made it possible to have a code server.