Giter Site home page Giter Site logo

gostatic's Introduction

goStatic Docker Pulls Docker Build Build Status GoDoc

A really small, multi-arch, static web server for Docker

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.

Wait, I've been using old versions of GoStatic and things have changed!

Yeah, decided to drop support of unsecured HTTPS. Two-years ago, when I started GoStatic, there was no automatic HTTPS available. Nowadays, thanks to Let's Encrypt, it's really easy to do so. If you need HTTPS, I recommend caddy.

Features

  • A fully static web server embedded in a SCRATCH image
  • No framework
  • Web server built for Docker
  • Light container
  • More secure than official images (see below)
  • Log enabled
  • Specify custom response headers per path and filetype (info)

Why?

Because the official Golang image is wayyyy too big (around 1/2Gb as you can see below) and could be insecure.

For me, the whole point of containers is to have a light container... Many links should provide you with additional info to see my point of view:

How to use

docker run -d -p 80:8043 -v path/to/website:/srv/http --name goStatic pierrezemb/gostatic

Usage

./goStatic --help
Usage of ./goStatic:
  -append-header HeaderName:Value
        HTTP response header, specified as HeaderName:Value that should be added to all responses.
  -context string
        The 'context' path on which files are served, e.g. 'doc' will serve the files at 'http://localhost:<port>/doc/'
  -default-user-basic-auth string
        Define the user (default "gopher")
  -enable-basic-auth
        Enable basic auth. By default, password are randomly generated. Use --set-basic-auth to set it.
  -enable-health
        Enable health check endpoint. You can call /health to get a 200 response. Useful for Kubernetes, OpenFaas, etc.
  -enable-logging
        Enable log request
  -fallback string
        Default fallback file. Either absolute for a specific asset (/index.html), or relative to recursively resolve (index.html)
  -header-config-path string
        Path to the config file for custom response headers (default "/config/headerConfig.json")
  -https-promote
        All HTTP requests should be redirected to HTTPS
  -password-length int
        Size of the randomized password (default 16)
  -path string
        The path for the static files (default "/srv/http")
  -port int
        The listening port (default 8043)
  -set-basic-auth string
        Define the basic auth. Form must be user:password

Fallback

The fallback option is principally useful for single-page applications (SPAs) where the browser may request a file, but where part of the path is in fact an internal route in the application, not a file on disk. goStatic supports two possible usages of this option:

  1. Using an absolute path so that all not found requests resolve to the same file
  2. Using a relative file, which searches up the tree for the specified file

The second case is useful if you have multiple SPAs within the one filesystem. e.g., / and /admin.

Build

Docker images

docker buildx create --use --name=cross
docker buildx build --platform=linux/amd64,linux/arm64,linux/arm/v5,linux/arm/v6,linux/arm/v7,darwin/amd64,darwin/arm64,windows/amd64 .

gostatic's People

Contributors

aiomaster avatar andrewstucki avatar antoniofagardo avatar codepope avatar deranjer avatar dimitor115 avatar geshan avatar gomlgs avatar jessebluemr avatar konradhoeffner avatar marinacodes avatar meredrica avatar mgurov avatar nigelsim avatar phartenfeller avatar pierrez avatar solaris765 avatar teohrt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gostatic's Issues

gzip support?

i love this small static server,use for my frontend project,i generate index.js and index.js.gz,but on my browser,it default read index.js. can easily add gzip support without increase docker image size?

Feature request: Gzip pre-compressed

Would be great, if there exists a gzip option.
If a file requestes with the extension .gz exists, deliver that file, otherwise the one requested.
For example /index.html.gz instead of index.html

Un-priveledged user

I'm not too experienced with 'FROM scratch' images with Docker yet. And correct me if I'm wrong, but wouldn't this run as root in its current state?

And would you except a PR that adds an un-privileged user to the build?

Forwarding to fallback with URL encoded string

There seems to be an issue when running a SPA application when an URL encoded string is part of the URL.

Calling this: https://beol-test.dasch.swiss/letter/http:%2F%2Frdfh.ch%2F0801%2FNpZsD3aWQB2buNCjqRTcVw

results in this: https://beol-test.dasch.swiss/letter/http:/rdfh.ch/0801/NpZsD3aWQB2buNCjqRTcVw

which then of course fails.

The expected behavior would be to still have the originally called URL.

The links are live, so you can test by clicking on them.

Custom headers don't apply to directory indexes

Hi, thanks for your image.

I've tried to use the custom headers feature. They work for files, but not for directories, although requesting a directory leads to its index.html. To be more precise, a config entry with "path": "*", "fileExtension": "html" does apply when requesting /path/index.html, but does not for /path, although the response body is the same.

The code at

reqFileExtension := filepath.Ext(r.URL.Path)
shows that the middleware applies to the URL. Would it be possible to apply to the resolved file instead?

As a side note, I believe path + fileExtension should be superseded by a path glob or a regex, which is more powerful, and is actually not more complex. For instance, a rule with glob /**/ or regex \/$ would apply to any directory, and a rule with glob /**/*.css (or maybe even *.css) or regex \.css$ would apply to any CSS file.

vue/react based handling of sub path from root index.html

hi,

how do i redirect all missing files or 404 to index.html without returning 404?
is it possible todo so?
i think with gostatic, it is possible 404 in a function right?

sorry, what i mean is, when file is missing, it will fallback to index.html

thank you

Dockerfile: Apply header-config-path

I host a static site on Fly.io using goStatic and I want to use custom headers (by providing the argument -header-config-path string).

This is the Dockerfile:

FROM pierrezemb/gostatic
COPY ./public/ /srv/http/

Where can I specify the argument that goStatic reads on start?

Multiple headers?

Is it possible to set multiple http headers?

I've added to my deployment:

args: ['-append-header', 'Content-Type:application/json', '-append-header', 'Cache-Control:max-age=120']

but only the 2nd header was added (Cache-Control).

Option to set response status

200 OK is not always wanted case.
It could look like:

Usage of ./goStatic:
  (...)
  -status-code int
        Define response status code (default 200)

Add a logger

All printing is done through fmt.Println(""). We should add a logger and replace all fmt.Print calls.

We can use Zap, Logrus, or another.

Include "tar" in the container to be able to "kubectl cp"

gostatic is a very useful tool to publish files on the fly for testing. However putting files into the container in a kubernetes environement is not that easy as "kubectl cp" requires "tar" to be present in the container.

Is it an option for you ?

Can not run docker build due to upx package missing in go:latest

docker build .

 > [builder 4/4] RUN mkdir ./bin &&     apt-get update && apt-get install -y upx &&     GOOS=$(echo linux/amd64 | cut -f1 -d/) &&     GOARCH=$(echo linux/amd64 | cut -f2 -d/) &&     GOARM=$(echo linux/amd64 | cut -f3 -d/ | sed "s/v//" ) &&     CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} GOARM=${GOARM} go build ${BUILD_ARGS} -ldflags="-s" -tags netgo -installsuffix netgo -o ./bin/goStatic &&     mkdir ./bin/etc &&     ID=$(shuf -i 100-9999 -n 1) &&     upx -9 ./bin/goStatic &&     echo $ID &&     echo "appuser:x:$ID:$ID::/sbin/nologin:/bin/false" > ./bin/etc/passwd &&     echo "appgroup:x:$ID:appuser" > ./bin/etc/group:
0.975 Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB]
1.459 Get:2 http://deb.debian.org/debian bookworm-updates InRelease [52.1 kB]
1.547 Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
1.596 Get:4 http://deb.debian.org/debian bookworm/main amd64 Packages [8780 kB]
5.018 Get:5 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [6668 B]
5.026 Get:6 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [101 kB]
6.051 Fetched 9139 kB in 5s (1736 kB/s)
6.051 Reading package lists...
6.632 Reading package lists...
7.233 Building dependency tree...
7.377 Reading state information...
7.386 E: Unable to locate package upx

file listing

Hi there, is there any way to have this web server display a list of files in a directory rather than render the HTML? I would love to mount a persistent volume (that contains a bunch of files) to /srv/http and then be able to open the webpage of goStatic to download files from within that persistent volume

Feature Request: Clickable Link

When I run the container, I get a message like...

9:52AM INF Listening at 0.0.0.0:8043 /...

...in gnome-terminal, however I cannot open the link 0.0.0.0:8043 in a browser when I click on it, even when I hold CTRL.

However when I use python -m http.server I get the message:

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

When I hover over http://0.0.0.0:8000/, the link gets underlined and I can open it with CTRL+click.

Maybe that is something done by GNOME terminal because the link starts with http, but it would be great if goStatic could adopt the same format as python -m http.server as I prefer it for three reasons:

  1. It does not have the time in front, which I don't need
  2. It does not have "INF" in it, which I don't need
  3. It contains the clickable HTTP link

Add a flag to disable directory listing

There should be a way to disable directory listing. It can reveal files that shouldn't be visible.

As a work-around, I know I can put empty index.html files in every directories but it is not convenient for large file trees.

exec format error

The image builds fine and runs but exits immediately. docker logs gives:

❯ docker logs 3f55e51770b9
standard_init_linux.go:178: exec user process caused "exec format error"

Any idea what might be the issue?

Thanks

Feature request: usage without mounts!

Hej, very cool project!

It would be cool to get content in without adding files.
Ofc, i just can built my own container out of it, but its not really super dynamic.

It would be nice to:

  • Inject some basic text into index.html via ENV
  • specifiy a link to a tar with some files that are loaded on start

Thats something within your scope?

With that possibility you could easily deploy landing pages based on knative!

Allow configuration from environment variables

Docker convention tends to encourage environment variables for configuration of container parameters.

I need a 404 for my static sites, so I override the entrypoint with -fallback, but I find this method is extremely rare among docker containers (and not well documented in this project).

Was wondering if you would consider looking at the namsral/flag package for allowing setting parameters from environment variables. The best part is that it appears to be a drop in replacement for the std library flag package.

Per the documentation, cmd line params would always take precedence over environment variables if there was a conflict. As long as it really is a drop-in replacement, there shouldn't be any breaking changes while aligning more closely with Docker standards.

The namsral/flag pkg does also allow loading from a .conf file, but that would require some additional code, and I don't see a need to add that feature at this time.

Let me know what you think.

Docker Hub ARM image

Hi, I noted that the image at Docker hub is only built for linux/amd64. Do you plan on pushing a new image for ARM in the near future?

Would be wonderful to be able to use this image on our small raspberry pi :)

I'm not sure how what's your process to push the image to docker-hub but I only had to change the GOARCH parameter to GOARCH=arm in the RUN command in the stage 0 of the Dockerfile to generate it locally on my pi

Out of memory because of recursive call to fallback.OpenDefault

Was running successfully on fly.io but then set entrypoint = ["/goStatic", "-fallback", "index.html"]

Now I see

2023-11-13T23:18:12Z app[48ed43dc20e198] lhr [info] INFO Preparing to run: `/goStatic -fallback index.html` as appuser
2023-11-13T23:18:12Z app[48ed43dc20e198] lhr [info] INFO [fly api proxy] listening at /.fly/api
2023-11-13T23:18:12Z app[48ed43dc20e198] lhr [info]2023/11/13 23:18:12 listening on [fdaa:0:5267:a7b:13e:bab0:fa98:2]:22 (DNS: [fdaa::3]:53)
2023-11-13T23:18:12Z app[48ed43dc20e198] lhr [info]11:18PM INF Listening at http://0.0.0.0:8043 /...
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]fatal error: runtime: out of memory
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime stack:
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.throw({0x6898ae, 0x10000000})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/panic.go:1198 +0x71
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.sysMap(0xc010400000, 0x429180, 0x7ffda274ae00)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/mem_linux.go:169 +0x96
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.(*mheap).grow(0x8a1ec0, 0x8000)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/mheap.go:1393 +0x225
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.(*mheap).allocSpan(0x8a1ec0, 0x8000, 0x1, 0x0)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/mheap.go:1179 +0x165
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.(*mheap).allocManual(0x0, 0x0, 0x0)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/mheap.go:949 +0x1f
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.stackalloc(0x10000000)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/stack.go:409 +0x151
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.copystack(0xc0000ac1a0, 0x10000000)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/stack.go:859 +0x74
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.newstack()
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/stack.go:1097 +0x47b
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.morestack()
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/asm_amd64.s:461 +0x8b
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]goroutine 8 [copystack]:
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.(*mspan).nextFreeIndex(0x7f5f4095de30)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/mbitmap.go:166 +0x152 fp=0xc0082003a8 sp=0xc0082003a0 pc=0x413512
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.(*mcache).nextFree(0x7f5f40952108, 0x7)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/malloc.go:879 +0x4d fp=0xc0082003f0 sp=0xc0082003a8 pc=0x40c12d
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.mallocgc(0x15, 0x63bd00, 0x1)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/malloc.go:1077 +0x4e8 fp=0xc008200470 sp=0xc0082003f0 pc=0x40c7e8
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]runtime.makeslice(0xc008200560, 0x491fec, 0x7f5f40952108)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/slice.go:98 +0x52 fp=0xc008200498 sp=0xc008200470 pc=0x4493f2
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]path/filepath.(*lazybuf).append(...)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/path/filepath/path.go:47
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]path/filepath.Clean({0xc0001657d0, 0x15})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/path/filepath/path.go:150 +0x93a fp=0xc008200570 sp=0xc008200498 pc=0x56103a
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]path/filepath.join({0xc0082005e0, 0xd, 0xc008200620})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/path/filepath/path_unix.go:46 +0x8a fp=0xc0082005a8 sp=0xc008200570 pc=0x5619ea
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]path/filepath.Join(...)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/path/filepath/path.go:213
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net/http.Dir.Open({0x684fb3, 0x9}, {0xc0004c6610, 0xa})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/http/fs.go:79 +0xa5 fp=0xc008200610 sp=0xc0082005a8 pc=0x5c6b45
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net/http.(*Dir).Open(0xc000042d00, {0xc0004c6610, 0xc0001657a0})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     <autogenerated>:1 +0x45 fp=0xc008200640 sp=0xc008200610 pc=0x5fc9e5
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124b10}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:19 +0xb4 fp=0xc0082006d8 sp=0xc008200640 pc=0x61f054
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124ae0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200770 sp=0xc0082006d8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124ab0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200808 sp=0xc008200770 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124a80}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082008a0 sp=0xc008200808 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124a50}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200938 sp=0xc0082008a0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124a20}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082009d0 sp=0xc008200938 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001249f0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200a68 sp=0xc0082009d0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001249c0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200b00 sp=0xc008200a68 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124990}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200b98 sp=0xc008200b00 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124960}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200c30 sp=0xc008200b98 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124930}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200cc8 sp=0xc008200c30 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124900}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200d60 sp=0xc008200cc8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001248d0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200df8 sp=0xc008200d60 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001248a0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200e90 sp=0xc008200df8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124870}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200f28 sp=0xc008200e90 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124840}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008200fc0 sp=0xc008200f28 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124810}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201058 sp=0xc008200fc0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001247e0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082010f0 sp=0xc008201058 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001247b0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201188 sp=0xc0082010f0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124780}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201220 sp=0xc008201188 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124750}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082012b8 sp=0xc008201220 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124720}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201350 sp=0xc0082012b8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001246f0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082013e8 sp=0xc008201350 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001246c0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201480 sp=0xc0082013e8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124690}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201518 sp=0xc008201480 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124660}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082015b0 sp=0xc008201518 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124630}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201648 sp=0xc0082015b0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124600}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082016e0 sp=0xc008201648 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001245d0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201778 sp=0xc0082016e0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001245a0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201810 sp=0xc008201778 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124570}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082018a8 sp=0xc008201810 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124540}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201940 sp=0xc0082018a8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124510}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082019d8 sp=0xc008201940 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001244e0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201a70 sp=0xc0082019d8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001244b0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201b08 sp=0xc008201a70 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124480}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201ba0 sp=0xc008201b08 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124450}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201c38 sp=0xc008201ba0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124420}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201cd0 sp=0xc008201c38 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001243f0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201d68 sp=0xc008201cd0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001243c0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201e00 sp=0xc008201d68 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124390}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201e98 sp=0xc008201e00 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124360}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201f30 sp=0xc008201e98 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124330}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008201fc8 sp=0xc008201f30 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124300}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202060 sp=0xc008201fc8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001242d0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082020f8 sp=0xc008202060 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001242a0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202190 sp=0xc0082020f8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124270}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202228 sp=0xc008202190 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124240}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082022c0 sp=0xc008202228 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124210}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202358 sp=0xc0082022c0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001241e0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082023f0 sp=0xc008202358 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001241b0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202488 sp=0xc0082023f0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124180}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202520 sp=0xc008202488 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124150}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082025b8 sp=0xc008202520 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124120}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202650 sp=0xc0082025b8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001240f0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082026e8 sp=0xc008202650 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001240c0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202780 sp=0xc0082026e8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124090}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202818 sp=0xc008202780 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124060}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082028b0 sp=0xc008202818 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124030}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202948 sp=0xc0082028b0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000124000}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082029e0 sp=0xc008202948 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117fb0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202a78 sp=0xc0082029e0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117f80}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202b10 sp=0xc008202a78 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117f50}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202ba8 sp=0xc008202b10 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117f20}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202c40 sp=0xc008202ba8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117ef0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202cd8 sp=0xc008202c40 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117ec0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202d70 sp=0xc008202cd8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117e90}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202e08 sp=0xc008202d70 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117e60}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202ea0 sp=0xc008202e08 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117e30}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202f38 sp=0xc008202ea0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117e00}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008202fd0 sp=0xc008202f38 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117dd0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203068 sp=0xc008202fd0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117da0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203100 sp=0xc008203068 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117d70}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203198 sp=0xc008203100 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117d40}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203230 sp=0xc008203198 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117d10}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082032c8 sp=0xc008203230 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117ce0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203360 sp=0xc0082032c8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117cb0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082033f8 sp=0xc008203360 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117c80}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203490 sp=0xc0082033f8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117c50}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203528 sp=0xc008203490 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117c20}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082035c0 sp=0xc008203528 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117bf0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203658 sp=0xc0082035c0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117bc0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082036f0 sp=0xc008203658 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117b90}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203788 sp=0xc0082036f0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117b60}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203820 sp=0xc008203788 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117b30}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082038b8 sp=0xc008203820 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117b00}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203950 sp=0xc0082038b8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117ad0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc0082039e8 sp=0xc008203950 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117aa0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203a80 sp=0xc0082039e8 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117a70}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203b18 sp=0xc008203a80 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117a40}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203bb0 sp=0xc008203b18 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc000117a10}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203c48 sp=0xc008203bb0 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.OpenDefault({{0x7ffda274cde6, 0xc0001179e0}, {0x6dee60, 0xc000042d00}}, {0xc0000146f0, 0x7ffda274cde6})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /go/src/github.com/PierreZ/goStatic/fallback.go:22 +0x165 fp=0xc008203ce0 sp=0xc008203c48 pc=0x61f105
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]created by net/http.(*Server).Serve
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/http/server.go:3034 +0x4e8
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]goroutine 1 [IO wait]:
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]internal/poll.runtime_pollWait(0x7f5f407d8798, 0x72)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/runtime/netpoll.go:234 +0x89
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]internal/poll.(*pollDesc).wait(0xc0000ae180, 0xc00001e000, 0x0)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]internal/poll.(*pollDesc).waitRead(...)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/internal/poll/fd_poll_runtime.go:89
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]internal/poll.(*FD).Accept(0xc0000ae180)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/internal/poll/fd_unix.go:402 +0x22c
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net.(*netFD).accept(0xc0000ae180)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/fd_unix.go:173 +0x35
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net.(*TCPListener).accept(0xc00000c180)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/tcpsock_posix.go:140 +0x28
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net.(*TCPListener).Accept(0xc00000c180)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/tcpsock.go:262 +0x3d
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net/http.(*Server).Serve(0xc0000b2000, {0x6e35b0, 0xc00000c180})
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/http/server.go:3002 +0x394
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net/http.(*Server).ListenAndServe(0xc0000b2000)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/http/server.go:2931 +0x7d
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]net/http.ListenAndServe(...)
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]     /usr/local/go/src/net/http/server.go:3185
2023-11-13T23:20:00Z app[48ed43dc20e198] lhr [info]main.main()
2023-11-13T23:20:00Z proxy[48ed43dc20e198] lhr [error]could not complete HTTP request to instance: connection closed before message completed
``

Latest build raises HTTP 403 when folder security is 644

Up to now we mounted a folder with security 644 into the docker container and all worked fine.
In our test stage we rebuild 4 weeks ago from goStatic:latest and face the problem that access to files in the root of mounted folder fail with HTTP 403 access denied.

Changing the folder security to 755 fixed the problem.

Was there some change that introduced this changed behaviour?
is this now the new required default for the mounted folder?

Large memory usage when downloading large files

I have a folder on my site called "archive", where I store large zips of data. Navigating to http://site/archive gives me a nice interface by default for downloading files, much like how FTP is handled.
Every time a download of a large file is initiated (~800 mb) goStatic consumes large amounts of ram for a while.

Every time a request is initiated shows up as red in the top graph. The bottom graph is container memory usage in a range of 0 - 1 GB.

Image

To reproduce:

run sudo docker run -d -p 1935:8043 -v /srv/goStatic:/srv/http --name goStatic pierrezemb/gostatic

Place large zip file in /srv/goStatic

Navigate to localhost:1935/largeFile.zip

Observe memory usage.

Error "flag provided but not defined: -header-config-path" when using :latest tag

I was trying to try out the new headerConfig feature. But when I've created configMap with the file under /config/, there was no effect and no error message. So I've tried to use '-header-config-path' parameter:

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - args:
        - -header-config-path
        - /config/headers/headerConfig.json
        image: pierrezemb/gostatic:latest
        imagePullPolicy: IfNotPresent
        name: static-cms
        ports:
        - containerPort: 8043
          name: http
          protocol: TCP
        volumeMounts:
        - mountPath: /srv/http/cms/api/public
          name: cmsfiles
        - mountPath: /config/headers
          name: headers
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      volumes:
      - configMap:
          defaultMode: 420
          name: static-cmsfiles
        name: cmsfiles
      - configMap:
          defaultMode: 420
          name: static-headers
        name: headers

where the static-headers configmap is:

apiVersion: v1
data:
  headerConfig.json: |-
    {
     "configs": [{"fileExtension":"*","headers":[{"key":"Content-Type","value":"application/json;charset=UTF-8"},{"key":"Cache-Control","value":"public, max-age=0, must-revalidate"}],"path":"*"}]
    }
kind: ConfigMap

However, I get the error message:

flag provided but not defined: -header-config-path 
Usage of /goStatic: 
  -append-header HeaderName:Value 
    	HTTP response header, specified as HeaderName:Value that should be added to all responses. 
  -context string 
    	The 'context' path on which files are served, e.g. 'doc' will serve the files at 'http://localhost:<port>/doc/' 
  -default-user-basic-auth string 
    	Define the user (default "gopher") 
  -enable-basic-auth 
    	Enable basic auth. By default, password are randomly generated. Use --set-basic-auth to set it. 
  -enable-health 
    	Enable health check endpoint. You can call /health to get a 200 response. Useful for Kubernetes, OpenFaas, etc. 
  -fallback string 
    	Default fallback file. Either absolute for a specific asset (/index.html), or relative to recursively resolve (index.html) 
  -password-length int 
    	Size of the randomized password (default 16) 
  -path string 
    	The path for the static files (default "/srv/http") 
  -port int 
    	The listening port (default 8043) 
  -set-basic-auth string 
    	Define the basic auth. Form must be user:password 

The new parameter is not in the list.
Could you please check if the :latest tag in docker-hub contains really the actual version of the code, or if it was overwriten by old version?

Fallback for multiple subdirectories

I use goStatic in a docker/traefik setup where goStatic serves as errorpages and a catch-all. So any route that isn't matched by traefik will get routed to goStatic. The setup works well.

Traefik will handle: doesnotexist.example.com
The goStatic fallback will handle: doesnotexist.example.com/doesnotexist

The only case which currently isn't being handled nicely is: doesnotexist.example.com/doesnotexist/doesnotexist (or even more subdirs).
If there are multiple subdirectories the html page will be shown, but any css/js/images will fail to load.

Refused to apply style from 'https://doesnotexist.example.com/doesnotexist/css/404.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Refused to execute script from 'https://doesnotexist.example.com/doesnotexist/js/tsparticles.bundle.min.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
Refused to execute script from 'https://doesnotexist.example.com/doesnotexist/js/404.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
Refused to apply style from 'https://doesnotexist.example.com/doesnotexist/css/404.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

I have tried both setting -fallback /index.html and -fallback index.html, the result seems to be the same.
My file structure inside the container looks as follows:

/srv/
├─ http/
│  ├─ css/
│  │  ├─ 404.css
│  ├─ images/
│  │  ├─ image.svg
│  ├─ js/
│  │  ├─ 404.js
│  │  ├─ tsparticles.bundle.min.js
│  ├─ index.html

Is there a way to redirect all requests to a specified path and not just one level of subdirectories?
Am I missing something else?

adding goStatic in docker-compose with forceHTTP

I'an new with docker and search a method to add your container to an compose file, but find no dokumentation who can i add the --forceHTTP parameter in the docker-composer.yml
I get the same error without --forceHTTP:
2017/05/18 19:23:53 Failed generating certs: open /etc/ssl/server/cert.pem: no such file or directory

Fallback not working at least for me...

Hello there,

I have an Angular SPA app with 3 routes setup like this :

  • / -> this one is working on reload and through navigation.
  • /another-route-1 -> this one is working only through navigation.
  • /another-route-2 -> this one is working only through navigation.

I have only one index.html. I think this is caused by the fallback not working properly.

Here's my dockerfile :

FROM pierrezemb/gostatic:latest as frontend
COPY --from=builder /app/dist/apps/frontend /srv/http
EXPOSE 8043
CMD ["goStatic", "--fallback", "index.html"]

I also tried without the option but none are working.

Thank you for your help.

htdocs folder

Where to keep index.html file on host to serve it from goStatic container?
Config says it's /srv/http. But where to find this folder on host?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.