Added readme
This commit is contained in:
parent
eee5fec678
commit
c727a8f621
3 changed files with 60 additions and 5 deletions
25
README.md
Normal file
25
README.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Cloud Proxy
|
||||
|
||||
Simple cloud proxy for docker
|
||||
|
||||
## Usage
|
||||
|
||||
# Run proxy itself
|
||||
```
|
||||
docker run --name proxy --restart=always \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v $(pwd)/certs:/usr/app/certs \
|
||||
-p 80:80 -p 443:443 -d \
|
||||
docker.pkg.github.com/neonxp/cloudproxy/proxy
|
||||
```
|
||||
|
||||
# Add service to proxy
|
||||
|
||||
```
|
||||
docker run -l "cp.host=HOST" -l "cp.port=PORT" -l "cp.tls=true" -d service
|
||||
```
|
||||
|
||||
Here:
|
||||
* `cp.host` - label sets hostname of service
|
||||
* `cp.port` - label sets port that service binds (inside container)
|
||||
* `cp.tls` - if this label presents, service will work over auto TLS (let's encrypt)
|
13
main.go
13
main.go
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/neonxp/rutina"
|
||||
|
@ -14,19 +15,22 @@ var httpSrv *http.Server
|
|||
var httpsSrv *http.Server
|
||||
|
||||
func main() {
|
||||
certDir := os.Getenv("CERTDIR")
|
||||
if certDir == "" {
|
||||
certDir = "/usr/app/certs"
|
||||
}
|
||||
r := rutina.New(rutina.WithListenOsSignals())
|
||||
w, err := newWatcher()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
handler := getHandler(w)
|
||||
|
||||
// Docker
|
||||
r.Go(w.watch)
|
||||
|
||||
// HTTPS
|
||||
r.Go(func(ctx context.Context) error {
|
||||
httpsSrv = &http.Server{Addr: ":https", Handler: handler}
|
||||
httpsSrv = &http.Server{Addr: ":https", Handler: getTlsHandler(w)}
|
||||
hosts := []string{}
|
||||
w.Range(func(key, value interface{}) bool {
|
||||
h := value.(host)
|
||||
|
@ -37,7 +41,7 @@ func main() {
|
|||
return true
|
||||
})
|
||||
m := &autocert.Manager{
|
||||
Cache: autocert.DirCache("certs"),
|
||||
Cache: autocert.DirCache(certDir),
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(hosts...),
|
||||
}
|
||||
|
@ -48,7 +52,6 @@ func main() {
|
|||
}
|
||||
return nil
|
||||
}, rutina.RestartIfDone)
|
||||
|
||||
r.Go(func(ctx context.Context) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
|
@ -65,7 +68,7 @@ func main() {
|
|||
|
||||
// HTTP
|
||||
r.Go(func(ctx context.Context) error {
|
||||
httpSrv = &http.Server{Addr: ":http", Handler: handler}
|
||||
httpSrv = &http.Server{Addr: ":http", Handler: getHandler(w)}
|
||||
if err := httpSrv.ListenAndServe(); err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
|
|
27
server.go
27
server.go
|
@ -15,6 +15,33 @@ func getHandler(watcher *watcher) http.Handler {
|
|||
return
|
||||
}
|
||||
h := hostInfo.(host)
|
||||
if h.TLS {
|
||||
newUrl := *r.URL
|
||||
newUrl.Scheme = "https"
|
||||
http.Redirect(w, r, newUrl.String(), http.StatusPermanentRedirect)
|
||||
}
|
||||
remoteUrl := &url.URL{
|
||||
Scheme: "http",
|
||||
Host: fmt.Sprintf("%s:%d", h.Addr, h.Port),
|
||||
}
|
||||
proxy := httputil.NewSingleHostReverseProxy(remoteUrl)
|
||||
proxy.ServeHTTP(w, r)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func getTlsHandler(watcher *watcher) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
hostInfo, loaded := watcher.Load(r.Host)
|
||||
if !loaded {
|
||||
w.WriteHeader(404)
|
||||
return
|
||||
}
|
||||
h := hostInfo.(host)
|
||||
if !h.TLS {
|
||||
w.WriteHeader(404)
|
||||
return
|
||||
}
|
||||
remoteUrl := &url.URL{
|
||||
Scheme: "http",
|
||||
Host: fmt.Sprintf("%s:%d", h.Addr, h.Port),
|
||||
|
|
Loading…
Reference in a new issue