mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00
new simpler setup method, readme and doc update
This commit is contained in:
parent
109c2460fa
commit
79ae26f1b5
12 changed files with 231 additions and 113 deletions
|
@ -19,6 +19,9 @@ COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
|
|||
COPY --from=builder /src/go-proxy /app/
|
||||
COPY schema/ /app/schema
|
||||
|
||||
# copy cert required for setup
|
||||
COPY --from=builder /etc/ssl/certs /etc/ssl/certs
|
||||
|
||||
ENV DOCKER_HOST=unix:///var/run/docker.sock
|
||||
ENV GOPROXY_DEBUG=0
|
||||
|
||||
|
|
24
README.md
24
README.md
|
@ -32,11 +32,12 @@ A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse p
|
|||
|
||||
- Easy to use
|
||||
- Effortless configuration
|
||||
- Simple multi-node setup
|
||||
- Error messages is clear and detailed, easy troubleshooting
|
||||
- Auto certificate obtaining and renewal (See [Supported DNS Challenge Providers](docs/dns_providers.md))
|
||||
- Auto configuration for docker containers
|
||||
- Auto hot-reload on container state / config file changes
|
||||
- Stop containers on idle, wake it up on traffic _(optional, see [showcase](#idlesleeper))_
|
||||
- **idlesleeper**: stop containers on idle, wake it up on traffic _(optional, see [showcase](#idlesleeper))_
|
||||
- HTTP(s) reserve proxy
|
||||
- TCP and UDP port forwarding
|
||||
- Web UI for configuration and monitoring (See [screenshots](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots))
|
||||
|
@ -48,18 +49,23 @@ A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse p
|
|||
|
||||
### Setup
|
||||
|
||||
1. Setup DNS Records, e.g.
|
||||
1. Pull docker image `docker pull ghcr.io/yusing/go-proxy:latest`
|
||||
|
||||
- A Record: `*.y.z` -> `10.0.10.1`
|
||||
- AAAA Record: `*.y.z` -> `::ffff:a00:a01`
|
||||
2. Create new directory, `cd` into it, then run setup
|
||||
|
||||
2. Setup `go-proxy` [See here](docs/docker.md)
|
||||
`docker run --rm -v .:/setup ghcr.io/yusing/go-proxy /app/go-proxy setup`
|
||||
|
||||
3. Setup `docker-socket-proxy` (see [example](docs/docker_socket_proxy.md) other machine that is running docker (if any)
|
||||
3. Setup DNS Records point to machine which runs `go-proxy`, e.g.
|
||||
|
||||
4. Configure `go-proxy`
|
||||
- with text editor (e.g. Visual Studio Code)
|
||||
- or with web config editor via `http://gp.y.z`
|
||||
- A Record: `*.y.z` -> `10.0.10.1`
|
||||
- AAAA Record: `*.y.z` -> `::ffff:a00:a01`
|
||||
|
||||
4. Setup `docker-socket-proxy` other docker nodes _(if any)_ (see [example](docs/docker_socket_proxy.md)) and then them inside `config.yml`
|
||||
|
||||
5. Done. You may now do some extra configuration
|
||||
- With text editor (e.g. Visual Studio Code)
|
||||
- With Web UI via `gp.y.z`
|
||||
- For more info, [See docker.md](docs/docker.md)
|
||||
|
||||
[🔼Back to top](#table-of-content)
|
||||
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
# options:
|
||||
# - auth_token: c1234565789-abcdefghijklmnopqrst # your zone API token
|
||||
|
||||
# 3. other providers, check readme for more
|
||||
# 3. other providers, check docs/dns_providers.md for more
|
||||
|
||||
providers:
|
||||
include:
|
||||
- providers.yml # config/providers.yml
|
||||
# add some more below if you want
|
||||
# - file1.yml # config/file_1.yml
|
||||
# - file2.yml
|
||||
# include:
|
||||
# - providers.yml # config/providers.yml
|
||||
# # add some more below if you want
|
||||
# - file1.yml # config/file_1.yml
|
||||
# - file2.yml
|
||||
docker:
|
||||
# for value format, see https://docs.docker.com/reference/cli/dockerd/
|
||||
# $DOCKER_HOST implies unix:///var/run/docker.sock by default
|
||||
|
@ -30,8 +30,7 @@ providers:
|
|||
# add more docker providers if needed
|
||||
# remote-1: tcp://10.0.2.1:2375
|
||||
# remote-2: ssh://root:1234@10.0.2.2
|
||||
|
||||
# Fixed options (optional, non hot-reloadable)
|
||||
|
||||
# timeout_shutdown: 5
|
||||
# redirect_to_https: false
|
||||
# redirect_to_https: false # redirect http requests to https (if enabled)
|
||||
|
|
|
@ -11,42 +11,70 @@
|
|||
|
||||
## Cloudflare
|
||||
|
||||
```yaml
|
||||
autocert:
|
||||
provider: cloudflare
|
||||
options:
|
||||
auth_token:
|
||||
```
|
||||
|
||||
`auth_token` your zone API token
|
||||
|
||||
Follow [this guide](https://cloudkul.com/blog/automcatic-renew-and-generate-ssl-on-your-website-using-lego-client/) to create a new token with `Zone.DNS` read and edit permissions
|
||||
|
||||
## CloudDNS
|
||||
|
||||
- `client_id`
|
||||
|
||||
- `email`
|
||||
|
||||
- `password`
|
||||
```yaml
|
||||
autocert:
|
||||
provider: clouddns
|
||||
options:
|
||||
client_id:
|
||||
email:
|
||||
password:
|
||||
```
|
||||
|
||||
## DuckDNS
|
||||
|
||||
- `token`: DuckDNS Token
|
||||
```yaml
|
||||
autocert:
|
||||
provider: duckdns
|
||||
options:
|
||||
token:
|
||||
```
|
||||
|
||||
Tested by [earvingad](https://github.com/earvingad)
|
||||
|
||||
## OVHCloud
|
||||
|
||||
```yaml
|
||||
autocert:
|
||||
provider: ovh
|
||||
options:
|
||||
api_endpoint:
|
||||
application_key:
|
||||
application_secret:
|
||||
consumer_key:
|
||||
oauth2_config:
|
||||
client_id:
|
||||
client_secret:
|
||||
```
|
||||
|
||||
_Note, `application_key` and `oauth2_config` **CANNOT** be used together_
|
||||
|
||||
- `api_endpoint`: Endpoint URL, or one of
|
||||
- `ovh-eu`,
|
||||
- `ovh-ca`,
|
||||
- `ovh-us`,
|
||||
- `kimsufi-eu`,
|
||||
- `kimsufi-ca`,
|
||||
- `soyoustart-eu`,
|
||||
- `soyoustart-ca`
|
||||
- `application_secret`
|
||||
- `application_key`
|
||||
- `consumer_key`
|
||||
- `oauth2_config`: Client ID and Client Secret
|
||||
- `client_id`
|
||||
- `client_secret`
|
||||
- `api_endpoint`: Endpoint URL, or one of
|
||||
- `ovh-eu`,
|
||||
- `ovh-ca`,
|
||||
- `ovh-us`,
|
||||
- `kimsufi-eu`,
|
||||
- `kimsufi-ca`,
|
||||
- `soyoustart-eu`,
|
||||
- `soyoustart-ca`
|
||||
- `application_secret`
|
||||
- `application_key`
|
||||
- `consumer_key`
|
||||
- `oauth2_config`: Client ID and Client Secret
|
||||
- `client_id`
|
||||
- `client_secret`
|
||||
|
||||
## Implement other DNS providers
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
- [Docker compose guide](#docker-compose-guide)
|
||||
- [Table of content](#table-of-content)
|
||||
- [Setup](#setup)
|
||||
- [Additional setup](#additional-setup)
|
||||
- [Labels](#labels)
|
||||
- [Syntax](#syntax)
|
||||
- [Fields](#fields)
|
||||
|
@ -16,34 +16,11 @@
|
|||
- [Docker compose examples](#docker-compose-examples)
|
||||
- [Services URLs for above examples](#services-urls-for-above-examples)
|
||||
|
||||
## Setup
|
||||
## Additional setup
|
||||
|
||||
1. Install `wget` if not already
|
||||
1. Enable HTTPs _(optional)_
|
||||
|
||||
- Ubuntu based: `sudo apt install -y wget`
|
||||
- Fedora based: `sudo yum install -y wget`
|
||||
- Arch based: `sudo pacman -Sy wget`
|
||||
|
||||
2. Run setup script
|
||||
|
||||
`bash <(wget -qO- https://github.com/yusing/go-proxy/raw/main/setup-docker.sh)`
|
||||
|
||||
It will setup folder structure and required config files
|
||||
|
||||
3. Verify folder structure and then `cd go-proxy`
|
||||
|
||||
```plain
|
||||
go-proxy
|
||||
├── certs
|
||||
├── compose.yml
|
||||
└── config
|
||||
├── config.yml
|
||||
└── providers.yml
|
||||
```
|
||||
|
||||
4. Enable HTTPs _(optional)_
|
||||
|
||||
Mount a folder (to store obtained certs) or (containing existing cert)
|
||||
Mount a folder to store obtained certs or to load existing cert
|
||||
|
||||
```yaml
|
||||
services:
|
||||
|
@ -69,15 +46,16 @@
|
|||
|
||||
```yaml
|
||||
autocert:
|
||||
provider: local
|
||||
cert_path: /app/certs/cert.crt
|
||||
key_path: /app/certs/priv.key
|
||||
```
|
||||
|
||||
5. Modify `compose.yml` to fit your needs
|
||||
2. Modify `compose.yml` to fit your needs
|
||||
|
||||
6. Run `docker compose up -d` to start the container
|
||||
3. Run `docker compose up -d` to start the container
|
||||
|
||||
7. Navigate to Web panel `http://gp.yourdomain.com` or use **Visual Studio Code (provides schema check)** to edit proxy config
|
||||
4. Navigate to Web panel `http://gp.yourdomain.com` or use **Visual Studio Code (provides schema check)** to edit proxy config
|
||||
|
||||
[🔼Back to top](#table-of-content)
|
||||
|
||||
|
@ -100,16 +78,16 @@
|
|||
|
||||
### Fields
|
||||
|
||||
| Field | Description | Default | Allowed Values / Syntax |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `scheme` | proxy protocol | <ul><li>`http` for numeric port</li><li>`tcp` for `x:y` port</li></ul> | `http`, `https`, `tcp`, `udp` |
|
||||
| `host` | proxy host | <ul><li>Docker: docker client IP / hostname </li><li>File: `localhost`</li></ul> | IP address, hostname |
|
||||
| `port` | proxy port **(http/s)** | first port returned from docker | number in range of `1 - 65535` |
|
||||
| `port` **(required)** | proxy port **(tcp/udp)** | N/A | `x:y` <br><ul><li>**x**: port for `go-proxy` to listen on.<br>**x** can be 0, which means listen on a random port</li><li>**y**: port or [_service name_](../src/common/constants.go#L55) of target container</li></ul> |
|
||||
| `no_tls_verify` | whether skip tls verify **(https only)** | `false` | boolean |
|
||||
| `path_patterns` | proxy path patterns **(http/s only)**<br> only requests that matched a pattern will be proxied | empty **(proxy all requests)** | yaml style list[<sup>1</sup>](#list-example) of ([path patterns](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) |
|
||||
| `set_headers` | header to set **(http/s only)** | empty | yaml style key-value mapping[<sup>2</sup>](#key-value-mapping-example) of header-value pairs |
|
||||
| `hide_headers` | header to hide **(http/s only)** | empty | yaml style list[<sup>1</sup>](#list-example) of headers |
|
||||
| Field | Description | Default | Allowed Values / Syntax |
|
||||
| --------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `scheme` | proxy protocol | <ul><li>`http` for numeric port</li><li>`tcp` for `x:y` port</li></ul> | `http`, `https`, `tcp`, `udp` |
|
||||
| `host` | proxy host | <ul><li>Docker: docker client IP / hostname </li><li>File: `localhost`</li></ul> | IP address, hostname |
|
||||
| `port` | proxy port **(http/s)** | first port returned from docker | number in range of `1 - 65535` |
|
||||
| `port` | proxy port **(tcp/udp)** | `0:first_port` | `x:y` <br><ul><li>**x**: port for `go-proxy` to listen on.<br>**x** can be 0, which means listen on a random port</li><li>**y**: port or [_service name_](../src/common/constants.go#L55) of target container</li></ul> |
|
||||
| `no_tls_verify` | whether skip tls verify **(https only)** | `false` | boolean |
|
||||
| `path_patterns` | proxy path patterns **(http/s only)**<br> only requests that matched a pattern will be proxied | `/` **(proxy all requests)** | yaml style list[<sup>1</sup>](#list-example) of ([path patterns](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) |
|
||||
| `set_headers` | header to set **(http/s only)** | empty | yaml style key-value mapping[<sup>2</sup>](#key-value-mapping-example) of header-value pairs |
|
||||
| `hide_headers` | header to hide **(http/s only)** | empty | yaml style list[<sup>1</sup>](#list-example) of headers |
|
||||
|
||||
[🔼Back to top](#table-of-content)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ docker-proxy:
|
|||
ports:
|
||||
- 2375:2375
|
||||
# or more secure
|
||||
- <machine_ip>:2375:2375
|
||||
- <machine_private_ip>:2375:2375
|
||||
```
|
||||
|
||||
```yml
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
if [ -z "$BRANCH" ]; then
|
||||
BRANCH="v0.5"
|
||||
fi
|
||||
BASE_URL="https://github.com/yusing/go-proxy/raw/${BRANCH}"
|
||||
mkdir -p go-proxy
|
||||
cd go-proxy
|
||||
mkdir -p config
|
||||
mkdir -p certs
|
||||
[ -f compose.yml ] || wget -cO - ${BASE_URL}/compose.example.yml > compose.yml
|
||||
[ -f config/config.yml ] || wget -cO - ${BASE_URL}/config.example.yml > config/config.yml
|
||||
[ -f config/providers.yml ] || touch config/providers.yml
|
|
@ -13,6 +13,7 @@ type Args struct {
|
|||
|
||||
const (
|
||||
CommandStart = ""
|
||||
CommandSetup = "setup"
|
||||
CommandValidate = "validate"
|
||||
CommandListConfigs = "ls-config"
|
||||
CommandListRoutes = "ls-routes"
|
||||
|
@ -23,6 +24,7 @@ const (
|
|||
|
||||
var ValidCommands = []string{
|
||||
CommandStart,
|
||||
CommandSetup,
|
||||
CommandValidate,
|
||||
CommandListConfigs,
|
||||
CommandListRoutes,
|
||||
|
|
|
@ -10,29 +10,24 @@ const (
|
|||
KeepAlive = 5 * time.Second
|
||||
)
|
||||
|
||||
const (
|
||||
ProviderKind_Docker = "docker"
|
||||
ProviderKind_File = "file"
|
||||
)
|
||||
|
||||
// file, folder structure
|
||||
|
||||
const (
|
||||
ConfigBasePath = "config/"
|
||||
ConfigFileName = "config.yml"
|
||||
ConfigPath = ConfigBasePath + ConfigFileName
|
||||
ConfigBasePath = "config"
|
||||
ConfigFileName = "config.yml"
|
||||
ConfigExampleFileName = "config.example.yml"
|
||||
ConfigPath = ConfigBasePath + "/" + ConfigFileName
|
||||
)
|
||||
|
||||
const (
|
||||
TemplatesBasePath = "templates/"
|
||||
PanelTemplatePath = TemplatesBasePath + "panel/index.html"
|
||||
ConfigEditorTemplatePath = TemplatesBasePath + "config_editor/index.html"
|
||||
SchemaBasePath = "schema"
|
||||
ConfigSchemaPath = SchemaBasePath + "/config.schema.json"
|
||||
FileProviderSchemaPath = SchemaBasePath + "/providers.schema.json"
|
||||
)
|
||||
|
||||
const (
|
||||
SchemaBasePath = "schema/"
|
||||
ConfigSchemaPath = SchemaBasePath + "config.schema.json"
|
||||
FileProviderSchemaPath = SchemaBasePath + "providers.schema.json"
|
||||
ComposeFileName = "compose.yml"
|
||||
ComposeExampleFileName = "compose.example.yml"
|
||||
)
|
||||
|
||||
const DockerHostFromEnv = "$DOCKER_HOST"
|
||||
|
|
|
@ -7,18 +7,18 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
NoSchemaValidation = getEnvBool("GOPROXY_NO_SCHEMA_VALIDATION")
|
||||
IsDebug = getEnvBool("GOPROXY_DEBUG")
|
||||
ProxyHTTPAddr = getEnv("GOPROXY_HTTP_ADDR", ":80")
|
||||
ProxyHTTPSAddr = getEnv("GOPROXY_HTTPS_ADDR", ":443")
|
||||
APIHTTPAddr = getEnv("GOPROXY_API_ADDR", "127.0.0.1:8888")
|
||||
NoSchemaValidation = GetEnvBool("GOPROXY_NO_SCHEMA_VALIDATION")
|
||||
IsDebug = GetEnvBool("GOPROXY_DEBUG")
|
||||
ProxyHTTPAddr = GetEnv("GOPROXY_HTTP_ADDR", ":80")
|
||||
ProxyHTTPSAddr = GetEnv("GOPROXY_HTTPS_ADDR", ":443")
|
||||
APIHTTPAddr = GetEnv("GOPROXY_API_ADDR", "127.0.0.1:8888")
|
||||
)
|
||||
|
||||
func getEnvBool(key string) bool {
|
||||
func GetEnvBool(key string) bool {
|
||||
return U.ParseBool(os.Getenv(key))
|
||||
}
|
||||
|
||||
func getEnv(key string, defaultValue string) string {
|
||||
func GetEnv(key string, defaultValue string) string {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
value = defaultValue
|
||||
|
|
|
@ -30,6 +30,12 @@ import (
|
|||
|
||||
func main() {
|
||||
args := common.GetArgs()
|
||||
|
||||
if args.Command == common.CommandSetup {
|
||||
Setup()
|
||||
return
|
||||
}
|
||||
|
||||
l := logrus.WithField("module", "main")
|
||||
onShutdown := F.NewSlice[func()]()
|
||||
|
||||
|
|
115
src/setup.go
Normal file
115
src/setup.go
Normal file
|
@ -0,0 +1,115 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
. "github.com/yusing/go-proxy/common"
|
||||
)
|
||||
|
||||
var branch = GetEnv("GOPROXY_BRANCH", "v0.5")
|
||||
var baseUrl = fmt.Sprintf("https://github.com/yusing/go-proxy/raw/%s", branch)
|
||||
var requiredConfigs = []Config{
|
||||
{ConfigBasePath, true, false, ""},
|
||||
{ComposeFileName, false, true, ComposeExampleFileName},
|
||||
{path.Join(ConfigBasePath, ConfigFileName), false, true, ConfigExampleFileName},
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Pathname string
|
||||
IsDir bool
|
||||
NeedDownload bool
|
||||
DownloadFileName string
|
||||
}
|
||||
|
||||
func Setup() {
|
||||
log.Println("setting up go-proxy")
|
||||
log.Println("branch:", branch)
|
||||
|
||||
os.Chdir("/setup")
|
||||
|
||||
for _, config := range requiredConfigs {
|
||||
config.setup()
|
||||
}
|
||||
|
||||
log.Println("done")
|
||||
}
|
||||
|
||||
func (c *Config) setup() {
|
||||
if c.IsDir {
|
||||
mkdir(c.Pathname)
|
||||
return
|
||||
}
|
||||
if !c.NeedDownload {
|
||||
touch(c.Pathname)
|
||||
return
|
||||
}
|
||||
|
||||
fetch(c.DownloadFileName, c.Pathname)
|
||||
}
|
||||
|
||||
func hasFileOrDir(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func mkdir(pathname string) {
|
||||
_, err := os.Stat(pathname)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
log.Printf("creating directory %q\n", pathname)
|
||||
err := os.MkdirAll(pathname, 0o755)
|
||||
if err != nil {
|
||||
log.Fatalf("failed: %s\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("failed: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func touch(pathname string) {
|
||||
if hasFileOrDir(pathname) {
|
||||
return
|
||||
}
|
||||
log.Printf("creating file %q\n", pathname)
|
||||
_, err := os.Create(pathname)
|
||||
if err != nil {
|
||||
log.Fatalf("failed: %s\n", err)
|
||||
}
|
||||
}
|
||||
func fetch(remoteFilename string, outFileName string) {
|
||||
if hasFileOrDir(outFileName) {
|
||||
return
|
||||
}
|
||||
log.Printf("downloading %q\n", remoteFilename)
|
||||
|
||||
url, err := url.JoinPath(baseUrl, remoteFilename)
|
||||
if err != nil {
|
||||
log.Fatalf("unexpected error: %s\n", err)
|
||||
}
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Fatalf("http request failed: %s\n", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatalf("error reading response body: %s\n", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(outFileName, body, 0o644)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to write to file: %s\n", err)
|
||||
}
|
||||
|
||||
log.Printf("downloaded %q\n", outFileName)
|
||||
}
|
Loading…
Add table
Reference in a new issue