mirror of https://github.com/portainer/portainer
feat(dockerui): add support for TLS enabled engines (#63)
parent
e67e20ce18
commit
1fb008212a
14
README.md
14
README.md
|
@ -54,6 +54,19 @@ UI For Docker listens on port 9000 by default. If you run UI For Docker inside a
|
|||
$ docker run -d -p 10.20.30.1:80:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock cloudinovasi/cloudinovasi-ui
|
||||
```
|
||||
|
||||
### Access a Docker engine protected via TLS
|
||||
|
||||
Ensure that you have access to the CA, the cert and the public key used to access your Docker engine.
|
||||
|
||||
These files will need to be named `ca.pem`, `cert.pem` and `key.pem` respectively. Store them somewhere on your disk and mount a volume containing these files inside the UI container:
|
||||
|
||||
```
|
||||
# Note the access to the endpoint via https
|
||||
$ docker run -d -p 9000:9000 cloudinovasi/cloudinovasi-ui -v /path/to/certs:/certs -e https://my-docker-host.domain:2376
|
||||
```
|
||||
|
||||
*Note*: Replace `/path/to/certs` to the path to the certificate files on your disk.
|
||||
|
||||
### Hide containers with specific labels
|
||||
|
||||
You can hide specific containers in the containers view by using the `-hide-label` or `-l` options and specifying a label.
|
||||
|
@ -77,6 +90,7 @@ The following options are available for the `ui-for-docker` binary:
|
|||
* `--endpoint`, `-e`: Docker deamon endpoint (default: *"/var/run/docker.sock"*)
|
||||
* `--bind`, `-p`: Address and port to serve UI For Docker (default: *":9000"*)
|
||||
* `--data`, `-d`: Path to the data folder (default: *"."*)
|
||||
* `--certs`, `-c`: Path to the certificates used for TLS (default: *"/certs"*)
|
||||
* `--assets`, `-a`: Path to the assets (default: *"."*)
|
||||
* `--swarm`, `-s`: Swarm cluster support (default: *false*)
|
||||
* `--hide-label`, `-l`: Hide containers with a specific label in the UI
|
||||
|
|
43
dockerui.go
43
dockerui.go
|
@ -15,6 +15,8 @@ import (
|
|||
"fmt"
|
||||
"github.com/gorilla/securecookie"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -22,6 +24,7 @@ var (
|
|||
addr = kingpin.Flag("bind", "Address and port to serve UI For Docker").Default(":9000").Short('p').String()
|
||||
assets = kingpin.Flag("assets", "Path to the assets").Default(".").Short('a').String()
|
||||
data = kingpin.Flag("data", "Path to the data").Default(".").Short('d').String()
|
||||
certs = kingpin.Flag("certs", "Path to the certs").Default("/certs").Short('c').String()
|
||||
swarm = kingpin.Flag("swarm", "Swarm cluster support").Default("false").Short('s').Bool()
|
||||
labels = LabelParser(kingpin.Flag("hide-label", "Hide containers with a specific label in the UI").Short('l'))
|
||||
authKey []byte
|
||||
|
@ -114,18 +117,50 @@ func createTcpHandler(e string) http.Handler {
|
|||
return httputil.NewSingleHostReverseProxy(u)
|
||||
}
|
||||
|
||||
func createTlsConfig(c string) *tls.Config {
|
||||
cert, err := tls.LoadX509KeyPair(c + "/" + "cert.pem", c + "/" + "key.pem")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
caCert, err := ioutil.ReadFile(c + "/" + "ca.pem")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
caCertPool := x509.NewCertPool()
|
||||
caCertPool.AppendCertsFromPEM(caCert)
|
||||
tlsConfig := &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
RootCAs: caCertPool,
|
||||
}
|
||||
return tlsConfig;
|
||||
}
|
||||
|
||||
func createTcpHandlerWithTLS(e string, c string) http.Handler {
|
||||
u, err := url.Parse(e)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var tlsConfig = createTlsConfig(c)
|
||||
proxy := httputil.NewSingleHostReverseProxy(u)
|
||||
proxy.Transport = &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
func createUnixHandler(e string) http.Handler {
|
||||
return &UnixHandler{e}
|
||||
}
|
||||
|
||||
func createHandler(dir string, d string, e string, c Config) http.Handler {
|
||||
func createHandler(dir string, d string, certs string, e string, c Config) http.Handler {
|
||||
var (
|
||||
mux = http.NewServeMux()
|
||||
fileHandler = http.FileServer(http.Dir(dir))
|
||||
h http.Handler
|
||||
)
|
||||
|
||||
if strings.Contains(e, "http") {
|
||||
if strings.Contains(e, "https") {
|
||||
h = createTcpHandlerWithTLS(e, certs)
|
||||
} else if strings.Contains(e, "http") {
|
||||
h = createTcpHandler(e)
|
||||
} else {
|
||||
if _, err := os.Stat(e); err != nil {
|
||||
|
@ -181,7 +216,7 @@ func main() {
|
|||
HiddenLabels: *labels,
|
||||
}
|
||||
|
||||
handler := createHandler(*assets, *data, *endpoint, configuration)
|
||||
handler := createHandler(*assets, *data, *certs, *endpoint, configuration)
|
||||
if err := http.ListenAndServe(*addr, handler); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
14
gruntFile.js
14
gruntFile.js
|
@ -40,6 +40,7 @@ module.exports = function (grunt) {
|
|||
grunt.registerTask('run', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:run']);
|
||||
grunt.registerTask('run-swarm', ['if:binaryNotExist', 'build', 'shell:buildImage', 'shell:runSwarm', 'watch:buildSwarm']);
|
||||
grunt.registerTask('run-dev', ['if:binaryNotExist', 'shell:buildImage', 'shell:run', 'watch:build']);
|
||||
grunt.registerTask('run-ssl', ['if:binaryNotExist', 'shell:buildImage', 'shell:runSsl', 'watch:buildSsl']);
|
||||
grunt.registerTask('clear', ['clean:app']);
|
||||
|
||||
// Print a timestamp (useful for when watching)
|
||||
|
@ -224,6 +225,10 @@ module.exports = function (grunt) {
|
|||
buildSwarm: {
|
||||
files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl %>', '<%= src.html %>'],
|
||||
tasks: ['build', 'shell:buildImage', 'shell:runSwarm', 'shell:cleanImages']
|
||||
},
|
||||
buildSsl: {
|
||||
files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl %>', '<%= src.html %>'],
|
||||
tasks: ['build', 'shell:buildImage', 'shell:runSsl', 'shell:cleanImages']
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
|
@ -267,7 +272,14 @@ module.exports = function (grunt) {
|
|||
command: [
|
||||
'docker stop ui-for-docker',
|
||||
'docker rm ui-for-docker',
|
||||
'docker run --privileged -d -p 9000:9000 -v /tmp/docker-ui:/data --name ui-for-docker ui-for-docker -e http://10.0.7.10:4000 --swarm -d /data'
|
||||
'docker run -d -p 9000:9000 -v /tmp/docker-ui:/data --name ui-for-docker ui-for-docker -e http://10.0.7.10:4000 --swarm -d /data'
|
||||
].join(';')
|
||||
},
|
||||
runSsl: {
|
||||
command: [
|
||||
'docker stop ui-for-docker',
|
||||
'docker rm ui-for-docker',
|
||||
'docker run -d -p 9000:9000 -v /tmp/docker-ui:/data -v /tmp/docker-ssl:/certs --name ui-for-docker ui-for-docker -e https://10.0.7.10:2376 -d /data'
|
||||
].join(';')
|
||||
},
|
||||
cleanImages: {
|
||||
|
|
Loading…
Reference in New Issue