Add caddy-proxy docker image to allow customization

This commit is contained in:
cruizba 2024-03-18 12:20:01 +01:00
parent a27aab0d81
commit c9aa15d124
8 changed files with 440 additions and 0 deletions

23
caddy-proxy/Dockerfile Normal file
View File

@ -0,0 +1,23 @@
FROM golang:1.22.1 as builder
ARG TARGETOS
ARG TARGETPLATFORM
ARG TARGETARCH
WORKDIR /workspace
COPY . .
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build
FROM caddy/caddy:2.7.6-alpine
ARG VERSION
RUN test -n "$VERSION" || (echo "VERSION arg is not set" && false)
ENV VERSION $VERSION
COPY --from=builder /workspace/local-caddy-generate /usr/bin/local-caddy-generate
COPY --from=builder /workspace/entrypoint.sh /entrypoint.sh
RUN chmod +x /usr/bin/local-caddy-generate /entrypoint.sh
# Run the binary.
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/caddy", "run", "--config", "/config/caddy/Caddyfile"]

7
caddy-proxy/README.md Normal file
View File

@ -0,0 +1,7 @@
# OpenVidu Local Deployment - Cadddy Proxy
If you want to modify any of the rules at the caddy-proxy container, just build the image again and run the local deployment with the new image.
```bash
docker build --build-arg VERSION=custom -t caddy-proxy .
```

26
caddy-proxy/entrypoint.sh Normal file
View File

@ -0,0 +1,26 @@
#!/bin/sh
set -e
# Generate Caddyfile and index.html
CURRENT_DIR="$(pwd)"
TMP_DIR="/tmp/caddy-local"
mkdir -p "$TMP_DIR"
cd "$TMP_DIR"
/usr/bin/local-caddy-generate
if [ ! -f /var/www/index.html ]; then
mkdir -p /var/www
cp "$TMP_DIR/index.html" /var/www/index.html
fi
if [ ! -f /var/www/app502.html ]; then
mkdir -p /var/www
cp "$TMP_DIR/app502.html" /var/www/app502.html
fi
if [ ! -f /config/caddy/Caddyfile ]; then
mkdir -p /config/caddy
cp "$TMP_DIR/Caddyfile" /config/caddy/Caddyfile
fi
cd "$CURRENT_DIR"
rm -rf /tmp/caddy-local
# Start Caddy
exec "$@"

3
caddy-proxy/go.mod Normal file
View File

@ -0,0 +1,3 @@
module local-caddy-generate
go 1.22.1

164
caddy-proxy/main.go Normal file
View File

@ -0,0 +1,164 @@
package main
import (
"bytes"
"fmt"
"html/template"
"local-caddy-generate/templates"
"os"
"strconv"
"strings"
)
type TemplateData any
var indexData = &templates.IndexData{}
var caddyData = &templates.CaddyData{}
func main() {
err := Initialize()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rawIndex, err := GenerateTemplate(templates.IndexTemplate, indexData)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = WriteStringToFile("index.html", rawIndex)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rawCaddyfile, err := GenerateTemplate(templates.CaddyfileTemplate, caddyData)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = WriteStringToFile("Caddyfile", rawCaddyfile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rawApp502, err := GenerateTemplate(templates.App502Template, nil)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = WriteStringToFile("app502.html", rawApp502)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func Initialize() error {
version := os.Getenv("VERSION")
if version == "" {
return fmt.Errorf("VERSION is not set")
}
localDomain := os.Getenv("LOCAL_DOMAIN")
if localDomain == "" {
return fmt.Errorf("LOCAL_DOMAIN is not set")
}
rawUseTLS := os.Getenv("USE_TLS")
if rawUseTLS == "" {
return fmt.Errorf("USE_TLS is not set")
}
useTLS, err := strconv.ParseBool(rawUseTLS)
if err != nil {
return fmt.Errorf("USE_TLS is not a boolean")
}
livekitApiKey := os.Getenv("LIVEKIT_API_KEY")
if livekitApiKey == "" {
return fmt.Errorf("LIVEKIT_API_KEY is not set")
}
livekitApiSecret := os.Getenv("LIVEKIT_API_SECRET")
if livekitApiSecret == "" {
return fmt.Errorf("LIVEKIT_API_SECRET is not set")
}
openviduSecret := os.Getenv("OPENVIDU_SHIM_SECRET")
if openviduSecret == "" {
return fmt.Errorf("OPENVIDU_SHIM_SECRET is not set")
}
dashboadAdminUsername := os.Getenv("DASHBOARD_ADMIN_USERNAME")
if dashboadAdminUsername == "" {
return fmt.Errorf("DASHBOARD_ADMIN_USERNAME is not set")
}
dashboardAdminPassword := os.Getenv("DASHBOARD_ADMIN_PASSWORD")
if dashboardAdminPassword == "" {
return fmt.Errorf("DASHBOARD_ADMIN_PASSWORD is not set")
}
minioAccessKey := os.Getenv("MINIO_ACCESS_KEY")
if minioAccessKey == "" {
return fmt.Errorf("MINIO_ACCESS_KEY is not set")
}
minioSecretKey := os.Getenv("MINIO_SECRET_KEY")
if minioSecretKey == "" {
return fmt.Errorf("MINIO_SECRET_KEY is not set")
}
indexData = &templates.IndexData{
OpenViduVersion: version,
DomainName: localDomain,
IsLocalhost: localDomain == "localhost",
IsTLS: useTLS,
LiveKitApiKey: livekitApiKey,
LiveKitApiSecret: livekitApiSecret,
OpenViduSecret: openviduSecret,
DashboardAdminUsername: dashboadAdminUsername,
DashboardAdminPassword: dashboardAdminPassword,
MinioAdminKey: minioAccessKey,
MinioAdminSecret: minioSecretKey,
}
caddyData = &templates.CaddyData{
DomainName: localDomain,
IsLocalhost: localDomain == "localhost",
IsTLS: useTLS,
}
return nil
}
func GenerateTemplate(templateString string, data TemplateData) (string, error) {
funcs := map[string]any{
"contains": strings.Contains,
"hasPrefix": strings.HasPrefix,
"hasSuffix": strings.HasSuffix}
tmpl, err := template.New("template").Funcs(funcs).Parse(templateString)
if err != nil {
return "", err
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
func WriteStringToFile(filePath string, data string) error {
file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString(data)
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,46 @@
package templates
const App502Template = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>502 - Application Not Found</title>
<!-- Bootstrap CSS CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Custom styles -->
<style>
body {
padding-top: 50px;
background-color: #f7f7f7;
}
.container {
padding: 40px;
background: #fff;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
max-width: 600px;
margin: auto;
text-align: center;
}
.error-code {
font-size: 45px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<div>
<div class="error-code">502 - Bad Gateway</div>
<h1 class="display-5">OpenVidu Application Not Found</h1>
<hr class="my-4">
<p>If you are developing an application and <b>run it locally at port 5442</b>, you will see here your application, under
the same domain and TLS certificate as OpenVidu.</p>
</div>
</div>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-rwoI1CjyWz1p9q6Lwz3m6ZXjCp3S1/9pSNOWq37fRynwCEK9kwu1F9Mbc+JwDMTV" crossorigin="anonymous"></script>
</body>
</html>
`

View File

@ -0,0 +1,85 @@
package templates
type CaddyData struct {
DomainName string
IsLocalhost bool
IsTLS bool
}
const CaddyfileTemplate = `
# Minio
{{- if hasSuffix .DomainName ".openvidu-local.dev" }}
http{{if .IsTLS}}s{{end}}://*.openvidu-local.dev:9000, http{{if .IsTLS}}s{{end}}://openvidu-local.dev:9000 {
{{- else }}
http{{if .IsTLS}}s{{end}}://{{.DomainName}}:9000 {
{{- end }}
{{if .IsTLS}}{{if hasSuffix .DomainName "openvidu-local.dev"}}tls internal {
get_certificate http https://certs.openvidu-local.dev/caddy.pem
}{{else}}tls internal{{end}}{{end}}
reverse_proxy http://minio:9000
}
# General
{{- if hasSuffix .DomainName ".openvidu-local.dev" }}
http{{if .IsTLS}}s{{end}}://*.openvidu-local.dev:4443, http{{if .IsTLS}}s{{end}}://openvidu-local.dev:4443 {
{{- else }}
http{{if .IsTLS}}s{{end}}://{{.DomainName}}:4443 {
{{- end }}
{{if .IsTLS}}{{if hasSuffix .DomainName "openvidu-local.dev"}}tls internal {
get_certificate http https://certs.openvidu-local.dev/caddy.pem
}{{else}}tls internal{{end}}{{end}}
# Api
@openvidu path /twirp/* /rtc/* /rtc
handle @openvidu {
reverse_proxy http://openvidu:7880
}
# Minio console
redir /minio-console /minio-console/
handle_path /minio-console/* {
uri strip_prefix /minio-console
reverse_proxy http://minio:9001
}
# OpenVidu Dashboard
redir /dashboard /dashboard/
handle_path /dashboard/* {
rewrite * {path}
reverse_proxy http://dashboard:5000
}
# OpenVidu Call (Default App)
redir /openvidu-call /openvidu-call/
handle_path /openvidu-call/* {
rewrite * {path}
reverse_proxy http://default-app:5442
}
# Default /
handle_path /* {
root * /var/www/
file_server
}
}
# Your OpenVidu App
{{- if hasSuffix .DomainName ".openvidu-local.dev" }}
http{{if .IsTLS}}s{{end}}://*.openvidu-local.dev:8000, http{{if .IsTLS}}s{{end}}://openvidu-local.dev:8000 {
{{- else }}
http{{if .IsTLS}}s{{end}}://{{.DomainName}}:8000 {
{{- end }}
{{if .IsTLS}}{{if hasSuffix .DomainName "openvidu-local.dev"}}tls internal {
get_certificate http https://certs.openvidu-local.dev/caddy.pem
}{{else}}tls internal{{end}}{{end}}
handle_errors {
@502 expression {http.error.status_code} == 502
rewrite @502 /app502.html
file_server {
root /var/www
}
}
reverse_proxy http://host.docker.internal:5442
}
`

View File

@ -0,0 +1,86 @@
package templates
type IndexData struct {
OpenViduVersion string
DomainName string
IsLocalhost bool
IsTLS bool
DashboardAdminUsername string
DashboardAdminPassword string
MinioAdminKey string
MinioAdminSecret string
LiveKitApiKey string
LiveKitApiSecret string
OpenViduSecret string
}
const IndexTemplate = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenVidu Local Deployment</title>
<!-- Bootstrap CSS CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Custom styles -->
<style>
.container {
padding-top: 50px;
padding-left: 100px;
padding-right: 100px;
}
</style>
</head>
<body>
<div class="container">
<div>
<h1 class="display-4">Welcome to OpenVidu Local Deployment</h1>
<p class="lead">OpenVidu Version: <strong>{{ .OpenViduVersion }}</strong></p>
<div class="alert alert-warning" role="alert">
<span>This deployment is only for development purposes.</span>
</div>
<hr class="my-4">
<ul>
<li><strong>OpenVidu API URL:</strong> <a href="http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443" target="_blank">http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443</a>
<ul>
<li><strong>Secret:</strong> <code>{{ .OpenViduSecret }}</code></li>
</ul>
</li>
<li><strong>LiveKit API URL:</strong> <a href="http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443" target="_blank">http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443</a>
<ul>
<li><strong>API Key:</strong> <code>{{ .LiveKitApiKey }}</code></li>
<li><strong>API Secret:</strong> <code>{{ .LiveKitApiSecret }}</code></li>
</ul>
</li>
<li><strong>OpenVidu Dashboard:</strong> <a href="http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443/dashboard" target="_blank">http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443/dashboard</a>
<ul>
<li><strong>Username:</strong> <code>{{ .DashboardAdminUsername }}</code></li>
<li><strong>Password:</strong> <code>{{ .DashboardAdminPassword }}</code></li>
</ul>
</li>
<li><strong>Minio:</strong> <a href="http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443/minio-console" target="_blank">http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443/minio-console</a>
<ul>
<li><strong>Minio Admin User:</strong> <code>{{ .MinioAdminKey }}</code></li>
<li><strong>Minio Admin Password:</strong> <code>{{ .MinioAdminSecret }}</code></li>
</ul>
</li>
<li><strong>OpenVidu Call (Default App):</strong> <a href="http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443/openvidu-call" target="_blank">http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:4443/openvidu-call</a></li>
<hr class="my-4">
<li><strong>Your App:</strong> <a href="http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:8000" target="_blank">http{{if .IsTLS}}s{{end}}://{{ .DomainName }}:8000</a>:
<span>If you are developing an application and run it locally at port 5442, you will see your application here, under the same domain and TLS certificate as OpenVidu.</span></li>
</ul>
<hr class="my-4">
{{- if not .IsLocalhost }}
<p>If you want to access this deployment with <code>http(s)://localhost:4443</code>, just change the <code>LOCAL_DOMAIN</code> variable to <code>localhost</code> in the <code>.env</code> file.</p>
{{- else }}
<p>If you want to access this deployment with <code>http(s)://openvidu-local.dev:4443</code>, just change the <code>LOCAL_DOMAIN</code> variable to <code>openvidu-local.dev</code> in the <code>.env</code> file.</p>
{{- end }}
{{- if .IsTLS }}
<p>If you want to disable TLS, just change the <code>USE_TLS</code> variable to <code>false</code> in the <code>.env</code> file.</p>
{{- else }}
<p>If you want to enable TLS, just change the <code>USE_TLS</code> variable to <code>true</code> in the <code>.env</code> file.</p>
{{- end }}
</div>
</div>
</body>
</html>`