# 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 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 # If using a compiled binary ./grokway-client --server example.com:2222 --local ``` > **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 ```