Skip to content

Commit f7b28ad

Browse files
authored
Adds base option (#5)
* Adds base option * Removes base unused * Adds readme * Adds redirect
1 parent 52a9575 commit f7b28ad

File tree

7 files changed

+65
-19
lines changed

7 files changed

+65
-19
lines changed

README.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,22 @@ dozzle will be available at [http://localhost:8888/](http://localhost:8888/). Yo
2424

2525
#### Security
2626

27-
dozzle doesn't support authentication out of the box. You can control the device dozzle binds to by passing `-addr` parameter. For example,
27+
dozzle doesn't support authentication out of the box. You can control the device dozzle binds to by passing `--addr` parameter. For example,
2828

29-
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:1224 amir20/dozzle:latest -addr localhost:1224
29+
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:1224 amir20/dozzle:latest --addr localhost:1224
3030

3131
will bind to `localhost` on port `1224`. You can then use use reverse proxy to control who can see dozzle.
3232

33+
#### Changing base URL
34+
35+
dozzle by default mounts to "/". If you want to control the base path you can use the `--base` option. For example, if you want to mount at "/foobar",
36+
then you can override by using `--base /foobar`.
37+
38+
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:1224 amir20/dozzle:latest --base /foobar
39+
40+
dozzle will be available at [http://localhost:8080/foobar/](http://localhost:8080/foobar/).
41+
42+
3343
#### Environment variable, DOCKER_API_VERSION
3444

3545
If you see

assets/App.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default {
2929
};
3030
},
3131
async created() {
32-
this.containers = await (await fetch(`/api/containers.json`)).json();
32+
this.containers = await (await fetch(`${BASE_PATH}/api/containers.json`)).json();
3333
}
3434
};
3535
</script>

assets/index.html

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1" />
66
<title>Dozzle</title>
77
<link href="https://fonts.googleapis.com/css?family=Roboto|Roboto+Mono|Gafata" rel="stylesheet">
8-
<link href="./styles.scss" rel="stylesheet">
8+
<link href="styles.scss" rel="stylesheet">
9+
<script>
10+
window["BASE_PATH"] = "{{ .Base }}";
11+
</script>
912
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
1013
</head>
1114

1215
<body class="is-dark">
1316
<div id="app"></div>
14-
<script src="/main.js"></script>
17+
<script src="main.js"></script>
1518
</body>
1619
</html>

assets/main.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const routes = [
2222

2323
const router = new VueRouter({
2424
mode: "history",
25+
base: BASE_PATH + "/",
2526
routes
2627
});
2728

assets/pages/Container.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default {
6060
ws = null;
6161
this.messages = [];
6262
}
63-
ws = new WebSocket(`ws://${window.location.host}/api/logs?id=${this.id}`);
63+
ws = new WebSocket(`ws://${window.location.host}${BASE_PATH}/api/logs?id=${this.id}`);
6464
ws.onopen = e => console.log("Connection opened.");
6565
ws.onclose = e => console.log("Connection closed.");
6666
ws.onerror = e => console.error("Connection error: " + e.data);

main.go

+43-11
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@ import (
44
"context"
55
"encoding/binary"
66
"encoding/json"
7-
"flag"
87
"fmt"
8+
"html/template"
99
"log"
1010
"net/http"
11+
"strings"
1112

1213
"github.com/docker/docker/api/types"
1314
"github.com/docker/docker/client"
1415
"github.com/gobuffalo/packr"
16+
"github.com/gorilla/mux"
1517
"github.com/gorilla/websocket"
18+
flag "github.com/spf13/pflag"
1619
)
1720

1821
var (
1922
cli *client.Client
2023
addr = flag.String("addr", ":8080", "http service address")
24+
base = flag.String("base", "/", "base address of the application to mount")
2125
upgrader = websocket.Upgrader{}
2226
version = "dev"
2327
commit = "none"
@@ -34,21 +38,30 @@ func init() {
3438
}
3539

3640
func main() {
41+
r := mux.NewRouter()
42+
43+
if *base != "/" {
44+
r.HandleFunc(*base, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
45+
http.Redirect(w, req, *base+"/", http.StatusMovedPermanently)
46+
}))
47+
}
48+
49+
s := r.PathPrefix(*base).Subrouter()
3750
box := packr.NewBox("./static")
38-
http.HandleFunc("/api/containers.json", listContainers)
39-
http.HandleFunc("/api/logs", logs)
40-
http.HandleFunc("/version", versionHandler)
41-
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
51+
52+
s.HandleFunc("/api/containers.json", listContainers)
53+
s.HandleFunc("/api/logs", logs)
54+
s.HandleFunc("/version", versionHandler)
55+
s.PathPrefix("/").Handler(http.StripPrefix(*base, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
4256
fileServer := http.FileServer(box)
43-
if box.Has(req.URL.Path) {
57+
if box.Has(req.URL.Path) && req.URL.Path != "" && req.URL.Path != "/" {
4458
fileServer.ServeHTTP(w, req)
4559
} else {
46-
bytes, _ := box.Find("index.html")
47-
w.Write(bytes)
60+
handleIndex(box, w)
4861
}
49-
}))
62+
})))
5063

51-
log.Fatal(http.ListenAndServe(*addr, nil))
64+
log.Fatal(http.ListenAndServe(*addr, r))
5265
}
5366

5467
func versionHandler(w http.ResponseWriter, r *http.Request) {
@@ -65,6 +78,25 @@ func listContainers(w http.ResponseWriter, r *http.Request) {
6578
json.NewEncoder(w).Encode(containers)
6679
}
6780

81+
func handleIndex(box packr.Box, w http.ResponseWriter) {
82+
text, _ := box.FindString("index.html")
83+
text = strings.Replace(text, "__BASE__", "{{ .Base }}", -1)
84+
tmpl, err := template.New("index.html").Parse(text)
85+
if err != nil {
86+
panic(err)
87+
}
88+
89+
path := ""
90+
if *base != "/" {
91+
path = *base
92+
}
93+
data := struct{ Base string }{Base: path}
94+
err = tmpl.Execute(w, data)
95+
if err != nil {
96+
panic(err)
97+
}
98+
}
99+
68100
func logs(w http.ResponseWriter, r *http.Request) {
69101
id := r.URL.Query().Get("id")
70102
c, err := upgrader.Upgrade(w, r, nil)
@@ -86,7 +118,7 @@ func logs(w http.ResponseWriter, r *http.Request) {
86118
for {
87119
_, err := reader.Read(hdr)
88120
if err != nil {
89-
log.Panicln(err)
121+
log.Panicln(err)
90122
}
91123
count := binary.BigEndian.Uint32(hdr[4:])
92124
n, err := reader.Read(content[:count])

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"main": "index.js",
66
"scripts": {
77
"start": "concurrently 'go run main.go' 'npm run watch-assets'",
8-
"watch-assets": "parcel watch assets/index.html -d static",
9-
"build": "parcel build assets/index.html -d static",
8+
"watch-assets": "parcel watch --public-url '__BASE__' assets/index.html -d static",
9+
"build": "parcel build --public-url '__BASE__' assets/index.html -d static",
1010
"clean": "rm -rf static",
1111
"release": "goreleaser --rm-dist"
1212
},

0 commit comments

Comments
 (0)