Compare commits

...

8 commits

Author SHA1 Message Date
9bb92785ef Aggiorna README.md
Some checks failed
CI to Docker Hub / build (push) Has been cancelled
2025-04-16 16:54:27 +08:00
2dae4e04ca Aggiorna README.md
Some checks are pending
CI to Docker Hub / build (push) Waiting to run
2025-04-15 20:46:03 +08:00
Pierre Zemb
72ed8fa4a9
Merge pull request #53 from KonradHoeffner/patch-1
Create clickable link. Resolve #52.
2022-03-03 14:19:46 +01:00
Konrad Höffner
d82050d9bd
Create clickable link. Resolve #52. 2022-03-03 12:52:30 +01:00
Pierre Zemb
603738491f
Merge pull request #49 from deranjer/logger
adding logging
2022-02-14 07:41:34 +01:00
deranjer
7892ac7921 updating logRequest to be deprecated but accepted with warning messages about deprecation 2022-02-13 12:51:23 -05:00
deranjer
183e471a00 adding logging 2022-02-11 21:29:55 -05:00
Pierre Zemb
758675c3a9
Merge pull request #45 from PierreZ/dev/gh-actions
chore: CI, multi-arch docker buildx
2021-06-19 11:32:35 +02:00
5 changed files with 116 additions and 15 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
vendor/
goStatic
goStatic*

View file

@ -1,6 +1,24 @@
# goStatic [![Docker Pulls](https://img.shields.io/docker/pulls/pierrezemb/gostatic.svg?style=plastic)](https://hub.docker.com/r/pierrezemb/gostatic/) [![Docker Build](https://img.shields.io/docker/build/pierrezemb/gostatic.svg?style=plastic)](https://hub.docker.com/r/pierrezemb/gostatic/) [![Build Status](https://travis-ci.org/PierreZ/goStatic.svg?branch=master)](https://travis-ci.org/PierreZ/goStatic) [![GoDoc](https://godoc.org/github.com/PierreZ/goStatic?status.svg)](https://godoc.org/github.com/PierreZ/goStatic)
A really small, multi-arch, static web server for Docker
# La mia applicazione
with docker
sudo docker run -d -p 8120:8043 -v /home/nvme/dockerdata/myweb:/srv/http --name myweb pierrezemb/gostatic
with docker compose or portainer
services:
gostatic:
ports:
- 8120:8043
volumes:
- /home/nvme/dockerdata/myweb:/srv/http
container_name: myweb
image: pierrezemb/gostatic
command: -set-basic-auth fabio:master66 #set auth login
## The goal
My goal is to create to smallest docker container for my web static files. The advantage of Go is that you can generate a fully static binary, so that you don't need anything else.

2
go.mod
View file

@ -1,3 +1,5 @@
module github.com/PierreZ/goStatic
go 1.16
require github.com/rs/zerolog v1.26.1

32
go.sum Normal file
View file

@ -0,0 +1,32 @@
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

77
main.go
View file

@ -9,11 +9,14 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
"strings"
"sync"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
var (
@ -28,7 +31,8 @@ var (
setBasicAuth = flag.String("set-basic-auth", "", "Define the basic auth. Form must be user:password")
defaultUsernameBasicAuth = flag.String("default-user-basic-auth", "gopher", "Define the user")
sizeRandom = flag.Int("password-length", 16, "Size of the randomized password")
logRequest = flag.Bool("enable-logging", false, "Enable log request")
logLevel = flag.String("log-level", "info", "default: info - What level of logging to run, debug logs all requests (error, warn, info, debug)")
logRequest = flag.Bool("enable-logging", false, "Enable log request. NOTE: Deprecated, set log-level to debug to log all requests")
httpsPromote = flag.Bool("https-promote", false, "All HTTP requests should be redirected to HTTPS")
headerConfigPath = flag.String("header-config-path", "/config/headerConfig.json", "Path to the config file for custom response headers")
@ -36,6 +40,21 @@ var (
password string
)
func setupLogger(logLevel string) {
switch logLevel {
case "error":
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
case "warn":
zerolog.SetGlobalLevel(zerolog.WarnLevel)
case "info":
zerolog.SetGlobalLevel(zerolog.InfoLevel)
case "debug":
zerolog.SetGlobalLevel(zerolog.DebugLevel)
default:
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
}
func parseHeaderFlag(headerFlag string) (string, string) {
if len(headerFlag) == 0 {
return "", ""
@ -72,16 +91,10 @@ func handleReq(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if *httpsPromote && r.Header.Get("X-Forwarded-Proto") == "http" {
http.Redirect(w, r, "https://"+r.Host+r.RequestURI, http.StatusMovedPermanently)
if *logRequest {
log.Println(301, r.Method, r.URL.Path)
}
log.Debug().Int("http_code", 301).Str("Method", r.Method).Str("Path", r.URL.Path).Msg("Request Redirected")
return
}
if *logRequest {
log.Println(r.Method, r.URL.Path)
}
log.Debug().Str("Method", r.Method).Str("Path", r.URL.Path).Msg("Request Handled")
h.ServeHTTP(w, r)
})
}
@ -90,16 +103,46 @@ func main() {
flag.Parse()
// Setting up logging output before setting up level to print out deprecation warnings
// UNIX Time is faster and smaller than most timestamps
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
// Set a pretty console output
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
if *logRequest {
log.Warn().Msg("enable-logging is deprecated in favor of log-level")
}
//if log-level not default and enable-logging set to true, use log-level
if *logLevel != "info" && *logRequest {
log.Warn().Msg("log-level not 'info' and enable-logging set, using log-level")
*logRequest = false
}
//if log-level is info and we have enable-logging, set log-level to debug
if *logLevel == "info" && *logRequest {
log.Warn().Msg("since enable-logging is set, setting log-level to debug")
*logLevel = "debug"
}
//setting up the logger
setupLogger(*logLevel)
log.Debug().Str("Logging Level", zerolog.GlobalLevel().String()).Msg("Logger setup...")
// sanity check
if len(*setBasicAuth) != 0 && !*basicAuth {
log.Debug().Msg("Basic Auth Set")
*basicAuth = true
}
port := ":" + strconv.FormatInt(int64(*portPtr), 10)
var fileSystem http.FileSystem = http.Dir(*basePath)
log.Debug().Str("path", *basePath).Msg("File serve path set")
if *fallbackPath != "" {
log.Debug().Str("FallbackPath", *fallbackPath).Msg("Fallback path set")
fileSystem = fallback{
defaultPath: *fallbackPath,
fs: fileSystem,
@ -115,7 +158,7 @@ func main() {
}
if *basicAuth {
log.Println("Enabling Basic Auth")
log.Debug().Msg("Enabling Basic Auth")
if len(*setBasicAuth) != 0 {
parseAuth(*setBasicAuth)
} else {
@ -135,6 +178,7 @@ func main() {
if len(header) > 0 && len(headerValue) > 0 {
fileServer := handler
handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Debug().Str("URL", r.URL.Path).Str("header", header).Str("headerValue", headerValue).Msg("Extra Headers Handled")
w.Header().Set(header, headerValue)
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
fileServer.ServeHTTP(w, r)
@ -146,22 +190,27 @@ func main() {
gz.Reset(w)
defer gz.Close()
fileServer.ServeHTTP(&gzipResponseWriter{ResponseWriter: w, Writer: gz}, r)
}
})
} else {
log.Println("appendHeader misconfigured; ignoring.")
log.Warn().Msg("appendHeader misconfigured; ignoring.")
}
}
if *healthCheck {
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
log.Debug().Msg("Returning Service Health")
fmt.Fprintf(w, "Ok")
})
}
http.Handle(pathPrefix, handler)
log.Printf("Listening at 0.0.0.0%v %v...", port, pathPrefix)
log.Fatalln(http.ListenAndServe(port, nil))
log.Info().Msgf("Listening at http://0.0.0.0%v %v...", port, pathPrefix)
if err := http.ListenAndServe(port, nil); err != nil && err != http.ErrServerClosed {
log.Fatal().Err(err).Msg("Server startup failed")
}
}