mirror of
https://github.com/gl-inet/glkvm-cloud.git
synced 2026-10-04 04:32:22 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed3da45ddf | |||
| b089169270 | |||
| 2349554c22 | |||
| 77886cf052 | |||
| 9be7a854ce | |||
| 2b6aecf72a | |||
| efa73caf75 |
@@ -36,6 +36,10 @@ build-run: build run
|
||||
# Build frontend, build Go binary, and run
|
||||
full-run: ui build run
|
||||
|
||||
# Build Docker image
|
||||
docker-build: ui build
|
||||
docker build -t glkvm:v1 .
|
||||
# Build Docker image without updating ui
|
||||
docker-build: build
|
||||
docker build -t glkvm-cloud:build .
|
||||
|
||||
# Full Build Docker image
|
||||
docker-fullbuild: ui build
|
||||
docker build -t glkvm-cloud:build .
|
||||
@@ -13,6 +13,7 @@ Self-Deployed Lightweight Cloud is a lightweight KVM remote cloud platform tailo
|
||||
- **Batch Operations** - Batch command execution capabilities
|
||||
- **Rapid Deployment** - Quick self-deployment with simple operations
|
||||
- **Data Security** - Private deployment with full data control
|
||||
- **Dedicated Bandwidth** - Exclusive bandwidth for self-hosted deployments
|
||||
- **Lightweight Design** - Optimized for small businesses and individual users
|
||||
|
||||
## Self-Hosting Guide
|
||||
@@ -34,9 +35,10 @@ The following mainstream operating systems have been tested and verified
|
||||
|
||||
| Component | Minimum Requirement |
|
||||
| :-----------------: | :-----------------: |
|
||||
| CPU | 1 cores or above |
|
||||
| CPU | 1 core or above |
|
||||
| Memory | ≥ 1 GB |
|
||||
| Storage | ≥ 40 GB |
|
||||
| Network Bandwidth | ≥ 3 Mbps |
|
||||
| KVM Device Firmware | ≥ v1.5.0 |
|
||||
|
||||
#### 🔐 Cloud Security Group Settings
|
||||
@@ -56,12 +58,22 @@ If your server provider uses a **cloud security group** (e.g., AWS, Aliyun, etc.
|
||||
------
|
||||
### 📦 Installation
|
||||
|
||||
Run the following command **as root** to install GLKVM Cloud:
|
||||
We provide **two** ways to install GLKVM Cloud:
|
||||
|
||||
#### A) One-line installer (recommended)
|
||||
|
||||
> **Note:** The one-line installer is **Docker-based**. It automates Docker/Compose setup, pulls images, renders configs from templates, and starts services for you.
|
||||
|
||||
Run **as root**:
|
||||
|
||||
```bash
|
||||
( command -v curl >/dev/null 2>&1 && curl -fsSL https://kvm-cloud.gl-inet.com/selfhost/install.sh || wget -qO- https://kvm-cloud.gl-inet.com/selfhost/install.sh ) | sudo bash
|
||||
```
|
||||
|
||||
#### B) Docker manual install
|
||||
|
||||
> Full reference: see [`docker-compose/README.md`](https://github.com/gl-inet/glkvm-cloud/blob/main/docker-compose/README.md)
|
||||
|
||||
### 🌐 Platform Access
|
||||
|
||||
Once the installation is complete, access the platform via:
|
||||
|
||||
+3
-1
@@ -14,6 +14,7 @@
|
||||
* **批量操作** - 支持批量执行命令
|
||||
* **快速部署** - 简单命令即可完成自部署
|
||||
* **数据安全** - 私有化部署,数据完全可控
|
||||
* **独享带宽** - 自部署环境下可享受专属带宽
|
||||
* **轻量设计** - 专为小型企业和个人优化
|
||||
|
||||
## 自部署指南
|
||||
@@ -34,10 +35,11 @@
|
||||
#### 系统要求
|
||||
|
||||
| 组件 | 最低配置要求 |
|
||||
| ------------ | ------------ |
|
||||
| :------------: | :------------: |
|
||||
| CPU | 1 核及以上 |
|
||||
| 内存 | ≥ 1 GB |
|
||||
| 存储 | ≥ 40 GB |
|
||||
| 网络带宽 | ≥ 3 Mbps |
|
||||
| KVM 固件版本 | ≥ v1.5.0 |
|
||||
|
||||
#### 🔐 云安全组端口要求
|
||||
|
||||
@@ -295,15 +295,23 @@ func (srv *RttyServer) ListenAPI() error {
|
||||
host := c.Request.Host
|
||||
hostname, _, err := net.SplitHostPort(host)
|
||||
if err != nil {
|
||||
// 没有端口时直接使用 host
|
||||
hostname = host
|
||||
hostname = host // Use host directly if no port
|
||||
}
|
||||
|
||||
// Choose value by priority:
|
||||
// 1) If request host is a domain (not an IP), keep it.
|
||||
// 2) Else if it's an IP and cfg.WebrtcIP is set, use cfg.WebrtcIP.
|
||||
// 3) Else keep the request IP.
|
||||
chosen := hostname
|
||||
if isIP(hostname) && cfg.WebrtcIP != "" {
|
||||
chosen = cfg.WebrtcIP
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"hostname": hostname,
|
||||
"hostname": chosen, // reuse the same chosen value
|
||||
"port": cfg.AddrDev,
|
||||
"token": cfg.Token,
|
||||
"webrtcIP": cfg.WebrtcIP,
|
||||
"webrtcIP": chosen, // same as hostname
|
||||
"webrtcPort": cfg.WebrtcPort,
|
||||
"webrtcUsername": cfg.WebrtcUsername,
|
||||
"webrtcPassword": cfg.WebrtcPassword,
|
||||
@@ -332,6 +340,10 @@ func (srv *RttyServer) ListenAPI() error {
|
||||
return r.RunListener(ln)
|
||||
}
|
||||
|
||||
func isIP(addr string) bool {
|
||||
return net.ParseIP(addr) != nil
|
||||
}
|
||||
|
||||
func callUserHookUrl(cfg *Config, c *gin.Context) bool {
|
||||
if cfg.UserHookUrl == "" {
|
||||
return true
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw
|
||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
|
||||
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||
RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G
|
||||
h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV
|
||||
6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw
|
||||
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
|
||||
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj
|
||||
v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
|
||||
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
|
||||
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
|
||||
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc
|
||||
MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL
|
||||
pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp
|
||||
eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH
|
||||
pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7
|
||||
s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu
|
||||
h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv
|
||||
YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8
|
||||
ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0
|
||||
LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+
|
||||
EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY
|
||||
Ig46v9mFmBvyH04=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,22 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDkzCCAxmgAwIBAgISBQsXxrfK6EpotI2fXWteV3kMMAoGCCqGSM49BAMDMDIx
|
||||
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
|
||||
NjAeFw0yNTA3MjgwNTM5MjNaFw0yNTEwMjYwNTM5MjJaMBcxFTATBgNVBAMTDGNs
|
||||
YW54aWUubGlmZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKcExKR+nZ21Hpm6
|
||||
rqR/QuJ35yRwhBtTim+5cColIDIocjasMhB1ho49IINEa/hp5EHqTsMsgSkGEZ6R
|
||||
unr3D0qjggIoMIICJDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUH
|
||||
AwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKlsFBhG/CpyaZvz
|
||||
3/gFZdP0vxsWMB8GA1UdIwQYMBaAFJMnRpgDqVFojpjWxEJI2yO/WJTSMDIGCCsG
|
||||
AQUFBwEBBCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL2U2LmkubGVuY3Iub3JnLzAn
|
||||
BgNVHREEIDAegg4qLmNsYW54aWUubGlmZYIMY2xhbnhpZS5saWZlMBMGA1UdIAQM
|
||||
MAowCAYGZ4EMAQIBMC0GA1UdHwQmMCQwIqAgoB6GHGh0dHA6Ly9lNi5jLmxlbmNy
|
||||
Lm9yZy8xMy5jcmwwggECBgorBgEEAdZ5AgQCBIHzBIHwAO4AdQDtPEvW6AbCpKIA
|
||||
V9vLJOI4Ad9RL+3EhsVwDyDdtz4/4AAAAZhPwIK1AAAEAwBGMEQCIGoi+WQh9Bhb
|
||||
4f68AFmojUBHdj0cJhH8Wgv26QxqKUXZAiAyrxtJ9viGLjivjDUPm8NjmgquuLeH
|
||||
UAMkhSdvZmKK1QB1AA3h8jAr0w3BQGISCepVLvxHdHyx1+kw7w5CHrR+Tqo0AAAB
|
||||
mE/AmiYAAAQDAEYwRAIgbXMFtU65Mrr1ZaQSdX3Jc+5YO1Y/yApwx7vbGKOzriQC
|
||||
IFgfpun9rGzPSXUBW+oEjkvUeN1Yf2Thu4YIvkUfuceiMAoGCCqGSM49BAMDA2gA
|
||||
MGUCMCU9wGtvD/A/LqIdeNFtS8/Um7Sv0iyAn8JGcAu/GCI2oavEQk90mPvqMuqX
|
||||
W2rUQgIxANHH0WTA3121/bK4Rhu5w8kXUI8AWnxizZ4hDjGCKi6WmJCGhLqtleYK
|
||||
hhrMK8WjmQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,15 +0,0 @@
|
||||
Le_Domain='clanxie.life'
|
||||
Le_Alt='*.clanxie.life'
|
||||
Le_Webroot='dns_cf'
|
||||
Le_PreHook=''
|
||||
Le_PostHook=''
|
||||
Le_RenewHook=''
|
||||
Le_API='https://acme-v02.api.letsencrypt.org/directory'
|
||||
Le_Keylength='ec-256'
|
||||
Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/2400063957/411715523371'
|
||||
Le_LinkOrder='https://acme-v02.api.letsencrypt.org/acme/order/2400063957/411715523371'
|
||||
Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/050b17c6b7cae84a68b48d9f5d6b5e57790c'
|
||||
Le_CertCreateTime='1753684679'
|
||||
Le_CertCreateTimeStr='2025-07-28T06:37:59Z'
|
||||
Le_NextRenewTimeStr='2025-09-25T06:37:59Z'
|
||||
Le_NextRenewTime='1758782279'
|
||||
@@ -1,9 +0,0 @@
|
||||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIBKzCB0gIBADAXMRUwEwYDVQQDDAxjbGFueGllLmxpZmUwWTATBgcqhkjOPQIB
|
||||
BggqhkjOPQMBBwNCAASnBMSkfp2dtR6Zuq6kf0Lid+ckcIQbU4pvuXAqJSAyKHI2
|
||||
rDIQdYaOPSCDRGv4aeRB6k7DLIEpBhGekbp69w9KoFkwVwYJKoZIhvcNAQkOMUow
|
||||
SDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwJwYDVR0RBCAwHoIMY2xh
|
||||
bnhpZS5saWZlgg4qLmNsYW54aWUubGlmZTAKBggqhkjOPQQDAgNIADBFAiEAvyNm
|
||||
66wN/4Ni5cLfH8KpwHcgoVGXDoVAawiVaMdmsD0CIAKsdhG5SWWqvNYhYjKIVKbh
|
||||
Fv8cJ8R1rsaQPO98zj5k
|
||||
-----END CERTIFICATE REQUEST-----
|
||||
@@ -1,8 +0,0 @@
|
||||
[ req_distinguished_name ]
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
[ v3_req ]
|
||||
extendedKeyUsage=serverAuth,clientAuth
|
||||
|
||||
subjectAltName=DNS:clanxie.life,DNS:*.clanxie.life
|
||||
@@ -1,5 +0,0 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIJW3lmfzDnyLpgkX0Jlu0J3Bo1OyVa610GHAdvQmah8loAoGCCqGSM49
|
||||
AwEHoUQDQgAEpwTEpH6dnbUembqupH9C4nfnJHCEG1OKb7lwKiUgMihyNqwyEHWG
|
||||
jj0gg0Rr+GnkQepOwyyBKQYRnpG6evcPSg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -1,49 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDkzCCAxmgAwIBAgISBQsXxrfK6EpotI2fXWteV3kMMAoGCCqGSM49BAMDMDIx
|
||||
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
|
||||
NjAeFw0yNTA3MjgwNTM5MjNaFw0yNTEwMjYwNTM5MjJaMBcxFTATBgNVBAMTDGNs
|
||||
YW54aWUubGlmZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKcExKR+nZ21Hpm6
|
||||
rqR/QuJ35yRwhBtTim+5cColIDIocjasMhB1ho49IINEa/hp5EHqTsMsgSkGEZ6R
|
||||
unr3D0qjggIoMIICJDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUH
|
||||
AwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKlsFBhG/CpyaZvz
|
||||
3/gFZdP0vxsWMB8GA1UdIwQYMBaAFJMnRpgDqVFojpjWxEJI2yO/WJTSMDIGCCsG
|
||||
AQUFBwEBBCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL2U2LmkubGVuY3Iub3JnLzAn
|
||||
BgNVHREEIDAegg4qLmNsYW54aWUubGlmZYIMY2xhbnhpZS5saWZlMBMGA1UdIAQM
|
||||
MAowCAYGZ4EMAQIBMC0GA1UdHwQmMCQwIqAgoB6GHGh0dHA6Ly9lNi5jLmxlbmNy
|
||||
Lm9yZy8xMy5jcmwwggECBgorBgEEAdZ5AgQCBIHzBIHwAO4AdQDtPEvW6AbCpKIA
|
||||
V9vLJOI4Ad9RL+3EhsVwDyDdtz4/4AAAAZhPwIK1AAAEAwBGMEQCIGoi+WQh9Bhb
|
||||
4f68AFmojUBHdj0cJhH8Wgv26QxqKUXZAiAyrxtJ9viGLjivjDUPm8NjmgquuLeH
|
||||
UAMkhSdvZmKK1QB1AA3h8jAr0w3BQGISCepVLvxHdHyx1+kw7w5CHrR+Tqo0AAAB
|
||||
mE/AmiYAAAQDAEYwRAIgbXMFtU65Mrr1ZaQSdX3Jc+5YO1Y/yApwx7vbGKOzriQC
|
||||
IFgfpun9rGzPSXUBW+oEjkvUeN1Yf2Thu4YIvkUfuceiMAoGCCqGSM49BAMDA2gA
|
||||
MGUCMCU9wGtvD/A/LqIdeNFtS8/Um7Sv0iyAn8JGcAu/GCI2oavEQk90mPvqMuqX
|
||||
W2rUQgIxANHH0WTA3121/bK4Rhu5w8kXUI8AWnxizZ4hDjGCKi6WmJCGhLqtleYK
|
||||
hhrMK8WjmQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw
|
||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
|
||||
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||
RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G
|
||||
h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV
|
||||
6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw
|
||||
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
|
||||
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj
|
||||
v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
|
||||
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
|
||||
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
|
||||
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc
|
||||
MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL
|
||||
pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp
|
||||
eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH
|
||||
pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7
|
||||
s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu
|
||||
h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv
|
||||
YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8
|
||||
ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0
|
||||
LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+
|
||||
EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY
|
||||
Ig46v9mFmBvyH04=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,29 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
rttys:
|
||||
container_name: glkvm_cloud
|
||||
image: glkvm:v1
|
||||
ports:
|
||||
- "443:443"
|
||||
- "10443:10443"
|
||||
- "5912:5912"
|
||||
volumes:
|
||||
- ./rttys.conf:/home/rttys.conf:ro
|
||||
- ./certificate/glkvm.cer:/home/certificate/glkvm_cer:ro
|
||||
- ./certificate/glkvm.key:/home/certificate/glkvm_key:ro
|
||||
command: ["-c", "/home/rttys.conf"]
|
||||
restart: always
|
||||
|
||||
coturn:
|
||||
image: coturn/coturn:edge-alpine
|
||||
container_name: glkvm_coturn
|
||||
restart: always
|
||||
ports:
|
||||
- "3478:3478"
|
||||
- "3478:3478/udp"
|
||||
- "5349:5349"
|
||||
- "5349:5349/udp"
|
||||
volumes:
|
||||
- ./turnserver.conf:/etc/turnserver.conf:ro
|
||||
command: ["-c", "/etc/turnserver.conf"]
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
# Images
|
||||
GLKVM_IMAGE=glzhitong/glkvm-cloud:latest
|
||||
COTURN_IMAGE=coturn/coturn:edge-alpine
|
||||
|
||||
# GLKVM access IP seen by devices/users.
|
||||
# Leave empty to auto-detect at container start.
|
||||
GLKVM_ACCESS_IP=
|
||||
|
||||
# rttys
|
||||
RTTYS_TOKEN=DeviceTokenYouCanChangeMe
|
||||
RTTYS_PASS=StrongP@ssw0rd
|
||||
RTTYS_DEVICE_PORT=5912
|
||||
RTTYS_WEBUI_PORT=443
|
||||
RTTYS_HTTP_PROXY_PORT=10443
|
||||
|
||||
# TURN
|
||||
TURN_PORT=3478
|
||||
TURN_USER=glkvmcloudwebrtcuser
|
||||
TURN_PASS=AnotherS3cret
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
# Quick Start
|
||||
|
||||
This guide shows how to deploy **glkvm-cloud** using the provided Docker Compose environment template.
|
||||
|
||||
1. **Clone the repository and prepare the environment template**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/gl-inet/glkvm-cloud.git
|
||||
cd glkvm-cloud/docker-compose/
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. **Configure environment variables**
|
||||
|
||||
Edit `.env` and update the required parameters:
|
||||
|
||||
- `RTTYS_TOKEN`: device connection token (leave empty to use the default)
|
||||
- `RTTYS_PASS`: web management password (leave empty to use the default **StrongP@ssw0rd**)
|
||||
- `TURN_USER` / `TURN_PASS`: coturn authentication credentials (leave empty to use the default)
|
||||
- `GLKVM_ACCESS_IP`: glkvm cloud access address (leave empty to auto-detect at startup)
|
||||
|
||||
⚠️ **Note:** All configuration should be done in the `.env` file.
|
||||
You don’t need to modify `docker-compose.yml`, templates, or scripts directly.
|
||||
|
||||
3. **Start the services**
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
If you modify `.env` or template files, make sure to apply the updates:
|
||||
|
||||
```bash
|
||||
docker-compose down && docker-compose up -d
|
||||
```
|
||||
|
||||
4. **Platform Access**
|
||||
|
||||
Once the installation is complete, access the platform via:
|
||||
|
||||
```bash
|
||||
https://<your_server_public_ip>
|
||||
```
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
version: "2.0"
|
||||
|
||||
services:
|
||||
rttys:
|
||||
image: ${GLKVM_IMAGE:-glzhitong/glkvm-cloud:latest}
|
||||
container_name: glkvm_cloud
|
||||
restart: always
|
||||
environment:
|
||||
# Preferred: set GLKVM_ACCESS_IP explicitly; if empty, entrypoint will auto-detect once.
|
||||
GLKVM_ACCESS_IP: ${GLKVM_ACCESS_IP:-}
|
||||
|
||||
# ---- rttys ----
|
||||
RTTYS_TOKEN: ${RTTYS_TOKEN:-DeviceTokenYouCanChangeMe}
|
||||
RTTYS_PASS: ${RTTYS_PASS:-StrongP@ssw0rd}
|
||||
|
||||
# Ports inside container (mirrored to host via `ports` below)
|
||||
RTTYS_DEVICE_PORT: ${RTTYS_DEVICE_PORT:-5912} # addr-dev
|
||||
RTTYS_WEBUI_PORT: ${RTTYS_WEBUI_PORT:-443} # addr-user
|
||||
RTTYS_HTTP_PROXY_PORT: ${RTTYS_HTTP_PROXY_PORT:-10443} # addr-http-proxy
|
||||
|
||||
# WebRTC / TURN reference (used by rttys template)
|
||||
TURN_PORT: ${TURN_PORT:-3478}
|
||||
TURN_USER: ${TURN_USER:-glkvmcloudwebrtcuser}
|
||||
TURN_PASS: ${TURN_PASS:-AnotherS3cret}
|
||||
volumes:
|
||||
- ./templates/rttys.conf.template:/tpl/rttys.conf.tmpl:ro
|
||||
- ./scripts/docker-entrypoint.sh:/docker-entrypoint.sh:ro
|
||||
- ./certificate/glkvm.cer:/home/certificate/glkvm_cer:ro
|
||||
- ./certificate/glkvm.key:/home/certificate/glkvm_key:ro
|
||||
entrypoint: ["/bin/sh", "/docker-entrypoint.sh"]
|
||||
command: ["rttys"]
|
||||
ports:
|
||||
- "${RTTYS_WEBUI_PORT:-443}:${RTTYS_WEBUI_PORT:-443}"
|
||||
- "${RTTYS_HTTP_PROXY_PORT:-10443}:${RTTYS_HTTP_PROXY_PORT:-10443}"
|
||||
- "${RTTYS_DEVICE_PORT:-5912}:${RTTYS_DEVICE_PORT:-5912}"
|
||||
|
||||
coturn:
|
||||
image: ${COTURN_IMAGE:-coturn/coturn:edge-alpine}
|
||||
container_name: glkvm_coturn
|
||||
restart: always
|
||||
environment:
|
||||
# Same semantics as above: prefer explicit value, else auto-detect
|
||||
GLKVM_ACCESS_IP: ${GLKVM_ACCESS_IP:-}
|
||||
TURN_PORT: ${TURN_PORT:-3478}
|
||||
TURN_USER: ${TURN_USER:-glkvmcloudwebrtcuser}
|
||||
TURN_PASS: ${TURN_PASS:-AnotherS3cret}
|
||||
entrypoint: ["/bin/sh", "/docker-entrypoint.sh"]
|
||||
command: ["coturn"]
|
||||
volumes:
|
||||
- ./templates/turnserver.conf.template:/tpl/turnserver.conf.tmpl:ro
|
||||
- ./scripts/docker-entrypoint.sh:/docker-entrypoint.sh:ro
|
||||
ports:
|
||||
- "${TURN_PORT:-3478}:3478/tcp"
|
||||
- "${TURN_PORT:-3478}:3478/udp"
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# -------- GLKVM access IP resolver (IPv4) --------
|
||||
resolve_glkvm_access_ip() {
|
||||
# 1) Prefer user-provided env
|
||||
if [ -n "${GLKVM_ACCESS_IP:-}" ]; then
|
||||
echo "${GLKVM_ACCESS_IP}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
is_ipv4() { echo "$1" | grep -Eq '^[0-9]{1,3}(\.[0-9]{1,3}){3}$'; }
|
||||
try_cmd() {
|
||||
val="$("$@" 2>/dev/null | tr -d '\r\n')"
|
||||
if is_ipv4 "$val"; then
|
||||
echo "$val"; return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# 2) Best-effort auto-detection from multiple sources
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
try_cmd wget -qO- --timeout=3 https://api.ipify.org && return 0
|
||||
try_cmd wget -qO- --timeout=3 https://ifconfig.me && return 0
|
||||
fi
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
try_cmd curl -fsS --max-time 3 https://api.ipify.org && return 0
|
||||
try_cmd curl -fsS --max-time 3 https://ifconfig.me && return 0
|
||||
fi
|
||||
if command -v dig >/dev/null 2>&1; then
|
||||
try_cmd sh -c "dig +short -4 myip.opendns.com @resolver1.opendns.com" && return 0
|
||||
fi
|
||||
|
||||
# 3) Fallback
|
||||
echo "127.0.0.1"
|
||||
}
|
||||
|
||||
# -------- Minimal template renderer ({{KEY}}) --------
|
||||
render() {
|
||||
in="$1"; out="$2"; shift 2
|
||||
cp "$in" "$out"
|
||||
for key in "$@"; do
|
||||
val="$(printenv "$key" || true)"
|
||||
# Special-case: GLKVM_ACCESS_IP prefers env, else auto-detect once
|
||||
if [ "$key" = "GLKVM_ACCESS_IP" ] && [ -z "$val" ]; then
|
||||
val="$(resolve_glkvm_access_ip)"
|
||||
fi
|
||||
# Escape '/' and '&' for sed
|
||||
esc=$(printf '%s' "$val" | sed -e 's/[\/&]/\\&/g')
|
||||
sed -i "s/{{${key}}}/${esc}/g" "$out"
|
||||
done
|
||||
}
|
||||
|
||||
# -------- Dispatch by first arg --------
|
||||
case "$1" in
|
||||
rttys)
|
||||
: "${RTTYS_DEVICE_PORT:=5912}"
|
||||
: "${RTTYS_WEBUI_PORT:=443}"
|
||||
: "${RTTYS_HTTP_PROXY_PORT:=10443}"
|
||||
: "${TURN_PORT:=3478}"
|
||||
|
||||
render /tpl/rttys.conf.tmpl /home/rttys.conf \
|
||||
RTTYS_TOKEN RTTYS_PASS \
|
||||
GLKVM_ACCESS_IP TURN_PORT TURN_USER TURN_PASS \
|
||||
RTTYS_DEVICE_PORT RTTYS_WEBUI_PORT RTTYS_HTTP_PROXY_PORT
|
||||
|
||||
exec rttys -c /home/rttys.conf
|
||||
;;
|
||||
|
||||
coturn)
|
||||
: "${TURN_PORT:=3478}"
|
||||
|
||||
mkdir -p /tmp
|
||||
render /tpl/turnserver.conf.tmpl /tmp/turnserver.conf \
|
||||
GLKVM_ACCESS_IP TURN_PORT TURN_USER TURN_PASS
|
||||
|
||||
exec turnserver -c /tmp/turnserver.conf
|
||||
;;
|
||||
|
||||
*)
|
||||
exec "$@"
|
||||
;;
|
||||
esac
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
# Authentication token for device connections
|
||||
token: {{RTTYS_TOKEN}}
|
||||
|
||||
# Web management password
|
||||
password: {{RTTYS_PASS}}
|
||||
|
||||
# WebRTC
|
||||
webrtc-ip: {{GLKVM_ACCESS_IP}}
|
||||
webrtc-port: {{TURN_PORT}}
|
||||
webrtc-username: {{TURN_USER}}
|
||||
webrtc-password: {{TURN_PASS}}
|
||||
|
||||
# Listen addresses
|
||||
addr-dev: :{{RTTYS_DEVICE_PORT}}
|
||||
addr-user: :{{RTTYS_WEBUI_PORT}}
|
||||
addr-http-proxy: :{{RTTYS_HTTP_PROXY_PORT}}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
listening-port={{TURN_PORT}}
|
||||
lt-cred-mech
|
||||
user={{TURN_USER}}:{{TURN_PASS}}
|
||||
realm=glkvm
|
||||
no-multicast-peers
|
||||
allowed-peer-ip=0.0.0.0/0
|
||||
external-ip={{GLKVM_ACCESS_IP}}
|
||||
Reference in New Issue
Block a user