Files
grokway/docs/how_deploy_prod.md

223 lines
6.4 KiB
Markdown
Raw Normal View History

2026-01-27 02:26:17 +01:00
# Deploying GrokwayV2 to Production
This guide explains how to deploy the **GrokwayV2 Server** using Docker and Docker Compose.
## Prerequisites
- A Linux server (Ubuntu/Debian recommended) with a public IP.
- **Docker** and **Docker Compose** installed.
- A domain name (e.g., `example.com`) pointing to your server's IP.
- **Wildcard DNS** configured (e.g., `*.example.com` -> Server IP) to support dynamic subdomains.
## 1. Installation
1. **Clone the repository** (or copy the files) to your server:
```bash
git clone <repository-url>
cd GrokwayV2
```
2. **Verify Configuration**
- Ensure `Dockerfile` and `docker-compose.yml` are present.
- The default configuration uses ports `2222` (SSH) and `8080` (HTTP). Open these ports in your firewall (e.g., Security Groups, UFW).
## 2. Deploy with Docker Compose
Run the following command to build and start the server in detached mode:
```bash
docker-compose up -d --build
```
### Verify Status
Check if the container is running:
```bash
docker-compose ps
```
Check logs:
```bash
docker-compose logs -f
```
## 3. Client Connection
Clients can now connect to your server using the public IP or domain.
**Command:**
```bash
# If running locally (dev)
go run cmd/client/main.go --server example.com:2222 --local <local-port>
# If using a compiled binary
./grokway-client --server example.com:2222 --local <local-port>
```
> **Note:** Ensure the client points to port `2222` (or your mapped SSH port).
## 4. Updates
To deploy a new version:
1. Pull the latest code:
```bash
git pull origin main
```
2. Rebuild and restart:
```bash
docker-compose up -d --build
```
## Troubleshooting
- **Connection Refused:** Check if ports 2222 and 8080 are open in the firewall.
- **DNS Issues:** Ensure your wildcard DNS (`*.example.com`) is correctly propagating.
- **Permission Denied:** Ensure your user has rights to run docker commands (add user to docker group).
## Nginx Configuration
Since you already have `api.orin.remote.band` configured, you can add a new configuration for the main application and its subdomains.
### 1. HTTP/HTTPS Configuration (sites-available)
Create a new file `/etc/nginx/sites-available/grokway`:
```nginx
server {
# Main domain and wildcard subdomains
server_name grokway.orin.remote.band *.grokway.orin.remote.band;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support (important for future interactive features)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen 80;
}
```
Enable it:
```bash
ln -s /etc/nginx/sites-available/grokway /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
```
**SSL Certificate (Crucial Step):**
To support dynamic subdomains (e.g., `client1.grokway.orin.remote.band`), you **MUST** obtain a **Wildcard Certificate**. A standard certificate for `grokway.orin.remote.band` is **NOT valid** for its subdomains.
You need a certificate that covers both:
1. `grokway.orin.remote.band`
2. `*.grokway.orin.remote.band`
**How to get a Wildcard Certificate with Certbot:**
Wildcard certificates require **DNS validation** (you cannot use HTTP validation).
```bash
# Request a wildcard certificate
sudo certbot certonly --manual --preferred-challenges dns -d "grokway.orin.remote.band" -d "*.grokway.orin.remote.band"
```
1. Run the command.
2. Certbot will ask you to create a specific **TXT record** in your DNS provider (where you manage `orin.remote.band`).
3. Create the TXT record as instructed.
4. Wait a minute for propagation, then press Enter.
Once obtained, update your Nginx config (`/etc/nginx/sites-available/grokway`) to use the new certificates.
**Full Configuration with SSL:**
```nginx
server {
server_name grokway.orin.remote.band *.grokway.orin.remote.band;
# SSL Configuration
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/grokway.orin.remote.band/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/grokway.orin.remote.band/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# Redirect HTTP to HTTPS
server {
if ($host = grokway.orin.remote.band) {
return 301 https://$host$request_uri;
}
# Also redirect subdomains if needed, or use a wildcard match here
listen 80;
server_name grokway.orin.remote.band *.grokway.orin.remote.band;
return 404;
}
```
### 2. SSH Proxy Configuration (nginx.conf)
**Important:** The SSH proxy uses the `stream` module. This block **CANNOT** go inside `sites-available` (which are included inside the `http` block). It must go at the top level of `/etc/nginx/nginx.conf`.
Edit `/etc/nginx/nginx.conf` and add this **at the very end of the file**, outside of any `http {}` block:
```nginx
stream {
upstream grokway_ssh {
# Forward to the internal port where Grokway server is running (e.g., 2223)
server 127.0.0.1:2223;
}
server {
listen 2222; # Public facing SSH port
proxy_pass grokway_ssh;
}
}
```
After changing `nginx.conf`:
```bash
nginx -t
systemctl reload nginx
```
### 3. Run the Server
Since Nginx is now listening on port `2222` (public), you must run the Grokway server on a **different internal port** (e.g., `2223`) to avoid conflicts.
Running locally with Go:
```bash
go run cmd/server/main.go -ssh :2223
```
Running with Docker (update `docker-compose.yml`):
- Ensure the container exposes/maps port `2223` internally if needed, or simply let it run on default but map `2223:2222`?
- Actually, better just pass the arg:
```bash
command: ["/app/grokway-server", "-ssh", ":2223"]
```
And update ports mapping:
```yaml
ports:
- "127.0.0.1:2223:2223" # Only bind to localhost if Nginx is proxying
```