# Deployment Guide This guide covers building `subconverter-go`, producing Docker images, and deploying the service without Kubernetes. It also describes every configuration file parameter so operators can tune behaviour confidently. ## 1. Prerequisites - Go 1.22 or later - GNU Make (optional, for the provided convenience targets) - A POSIX shell with standard toolchain (`git`, `curl`, `tar`) - Docker 24+ for container builds - No external services (Redis, Nginx, databases) are required; the binary is self-contained. Clone the repository and move into it: ```bash git clone https://github.com/subconverter-go/subconverter-go.git cd subconverter-go ``` ## 2. Building From Source ### 2.1 Fetch Dependencies The module uses Go modules. The first build pulls dependencies automatically, but you can pre-download them: ```bash go mod download ``` ### 2.2 Compile the Binary ```bash go build -o build/subconverter ./cmd/cli ``` The resulting binary reads configuration from `config.yaml` in the working directory by default. Override the path with `--config` when launching. ### 2.3 Run Tests (Recommended) Use the full suite to catch regressions: ```bash go test ./... ``` ### 2.4 Install via Makefile (Optional) A shorthand target is available: ```bash make build ``` This produces `build/subconverter` as well. ## 3. Docker Workflow ### 3.1 Build the Image The repository ships with a parameterised Dockerfile. Build and tag an image: ```bash docker build -t subconverter-go:latest . ``` ### 3.2 Run the Container Provide a configuration file and optional rule assets via bind mounts or named volumes. The example below mounts the local `config.yaml` and exposes the HTTP port: ```bash docker run \ --name subconverter \ -p 25500:25500 \ -v $(pwd)/config.yaml:/app/config.yaml:ro \ -v $(pwd)/base:/app/base:ro \ subconverter-go:latest ``` Environment variables forwarded into the container override configuration entries when present (see section 4). ### 3.3 Using docker-compose For repeatable setups a ready-made `docker-compose.yml` is included: ```bash docker compose up -d ``` Edit the compose file to adjust host ports, volume bindings, or environment variables before starting. ## 4. Configuration Reference `config.yaml` controls service behaviour. The configuration loader also honours environment variables using the same keys but upper-cased and prefixed with `SUBCONVERTER_` (e.g. `SUBCONVERTER_SERVER_PORT`). ### 4.1 `server` | Key | Type | Description | | --- | ---- | ----------- | | `host` | string | Bind address for the HTTP server (`0.0.0.0` to serve all interfaces). | | `port` | int | TCP port exposed by the service. Default `25500`. | | `read_timeout` | int | Maximum seconds allowed to read a request body before timing out. | | `write_timeout` | int | Maximum seconds allowed to write a response before timing out. | | `max_request_size` | int | Maximum request payload size in bytes. Requests larger than this trigger `413 Payload Too Large`. | ### 4.2 `logging` | Key | Type | Description | | --- | ---- | ----------- | | `level` | string | Minimum level to emit (`debug`, `info`, `warn`, `error`). | | `format` | string | Output format: `json` for structured logs, `text` for human-readable lines. | | `output` | string | `stdout` to log to standard output, or `file` to log to the path in `file`. | | `file` | string | Destination file when `output` is `file`. Directories are created automatically. | | `max_size` | int | Maximum size in megabytes before the log rotates. | | `max_age` | int | Maximum days to retain old log files. | | `max_backups` | int | Maximum number of rotated log files to keep. | | `compress` | bool | Compress rotated logs with gzip when true. | ### 4.3 `security` | Key | Type | Description | | --- | ---- | ----------- | | `access_tokens` | list[string] | Static bearer tokens. When non-empty all `/api` and legacy endpoints require `token=` query parameter or `Authorization: Bearer`. | | `cors_origins` | list[string] | Allowed `Origin` headers for CORS preflight requests. Use `"*"` to allow all. | | `rate_limit` | int | Maximum number of requests per minute per client IP. `0` disables rate limiting. | | `timeout` | int | Request processing timeout in seconds. Requests exceeding this duration return `504`. | ### 4.4 `conversion` | Key | Type | Description | | --- | ---- | ----------- | | `default_target` | string | Format used when the client omits `target` (e.g. `clash`, `surge`). | | `supported_targets` | list[string] | Whitelist of allowed output formats. Requests for other formats return `400`. | | `default_emoji` | bool | Whether generated node names should include emoji when the client does not specify `add_emoji`. | | `default_udp` | bool | Enables UDP by default unless the client overrides `udp`. | | `max_nodes` | int | Maximum number of proxies returned per conversion. `0` means unlimited. | | `cache_timeout` | int | Minutes to cache conversion responses when the cache manager is on. | Additional options parsed from requests (for example `upload`, `rename`, `ruleset`) are stored per request and influence output but are not global configuration keys. ### 4.5 `cache` (optional block) If present it overrides cache manager defaults. | Key | Type | Description | | --- | ---- | ----------- | | `enabled` | bool | Toggles the in-memory conversion cache. Defaults to `true`. | | `ttl` | duration | Expiration window (e.g. `5m`, `1h`). | | `maxSize` | int | Maximum number of cached entries before evictions occur. | | `cleanup` | duration | Background cleanup interval. | ### 4.6 Environment Overrides Each configuration entry is mapped to an environment variable by concatenating section and key names. Examples: - `SUBCONVERTER_SERVER_PORT=8080` - `SUBCONVERTER_LOGGING_LEVEL=debug` - `SUBCONVERTER_CONVERSION_DEFAULT_UDP=true` When both environment variable and YAML entry exist, the environment variable wins. ## 5. Running the Binary ```bash ./build/subconverter --config /path/to/config.yaml ``` Common overrides: - `--port` (short-hand for `server.port`) - `--host` - `--config` Use `./build/subconverter --help` to inspect all flags. ## 6. Deploying on a Single Host (Systemd Example) 1. Copy the compiled binary to `/usr/local/bin/subconverter`. 2. Copy `config.yaml` and supporting assets (e.g. `base/`) to `/etc/subconverter/`. 3. Create `/etc/systemd/system/subconverter.service`: ```ini [Unit] Description=SubConverter-Go After=network.target [Service] Type=simple ExecStart=/usr/local/bin/subconverter --config /etc/subconverter/config.yaml Restart=on-failure User=subconverter Group=subconverter WorkingDirectory=/etc/subconverter Environment=SUBCONVERTER_LOGGING_OUTPUT=stdout [Install] WantedBy=multi-user.target ``` 4. Enable and start: ```bash sudo systemctl daemon-reload sudo systemctl enable --now subconverter ``` Monitor logs with `journalctl -u subconverter -f`. ## 7. Updating - For binary deployments: stop the service, replace the binary, restart. - For Docker deployments: rebuild the image (`docker build`) and recreate the container (`docker compose up -d --build`). Always re-run `go test ./...` after upgrading dependencies or modifying conversion logic. ## 8. Troubleshooting Checklist - **Startup fails:** ensure the configured port is free and the `base/` directory is mounted (contains default templates and rule sets). - **403 responses:** populate `security.access_tokens` and pass `token` query parameter (or clear the list to disable auth). - **Slow conversions:** consider increasing `server.write_timeout` and enabling cache (`cache.enabled: true`). - **Large payloads rejected:** raise `server.max_request_size`. For additional compatibility notes see `docs/compatibility.md`.