Intial commit
This commit is contained in:
commit
28a534d74d
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.stack-work/
|
||||
abhinavsarkar-net-server.cabal
|
||||
*~
|
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
FROM haskell:8.4.3 as builder
|
||||
WORKDIR /opt/hastatic
|
||||
ADD . .
|
||||
RUN stack install && strip /root/.local/bin/hastatic
|
||||
|
||||
FROM fpco/haskell-scratch:integer-gmp
|
||||
COPY --from=builder /root/.local/bin/hastatic /usr/bin/hastatic
|
30
LICENSE
Normal file
30
LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright Abhinav Sarkar (c) 2018
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of Abhinav Sarkar nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
45
README.md
Normal file
45
README.md
Normal file
@ -0,0 +1,45 @@
|
||||
# hastatic
|
||||
|
||||
_hastatic_ is a tiny static web server for Docker.
|
||||
|
||||
## Features
|
||||
|
||||
- A tiny web server, just 3MB in size.
|
||||
- Statically compiled binary with no dependencies.
|
||||
- Built for Docker.
|
||||
- Supports custom 404 file.
|
||||
- Supports custom index files for URLs ending with "/".
|
||||
- Adds caching headers automatically.
|
||||
- Does not support HTTPS. It is expected that you run it behind a reverse-proxy server with HTTPS support, like nginx.
|
||||
|
||||
## Usage
|
||||
|
||||
Create a Dockerfile for your website, deriving from `abhin4v/hastatic`:
|
||||
|
||||
```dockerfile
|
||||
FROM abhin4v/hastatic:latest
|
||||
|
||||
COPY mywebsite /opt/mywebsite
|
||||
WORKDIR /opt/mywebsite
|
||||
CMD ["/usr/bin/hastatic"]
|
||||
```
|
||||
|
||||
Build and run:
|
||||
|
||||
```
|
||||
$ docker build -t mywebsite .
|
||||
$ docker run -p 8080:3000 mywebsite # run with default configs
|
||||
$ docker run -e PORT=2000 -e NF_FILE=404.html -e IDX_FILE=index.html -p 8080:2000 mywebsite
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The Docker image supports these environment variable for configuration:
|
||||
|
||||
- PORT: the port to run the web server on, default: 3000
|
||||
- NF_FILE: name of the custom 404 file, default: `404.html`
|
||||
- IDX_FILE: name of the custom index files, default: `index.html`
|
||||
|
||||
## Internals
|
||||
|
||||
_hastatic_ is written in Haskell, just 30 lines of it. It uses the excellent [Warp](https://hackage.haskell.org/package/warp) server underneath.
|
34
hastatic.cabal
Normal file
34
hastatic.cabal
Normal file
@ -0,0 +1,34 @@
|
||||
-- This file has been generated from package.yaml by hpack version 0.28.2.
|
||||
--
|
||||
-- see: https://github.com/sol/hpack
|
||||
--
|
||||
-- hash: e49204f2f26a2ed8552e95f4f543b1cb4148cc509790f5d550ab98b70a722323
|
||||
|
||||
name: hastatic
|
||||
version: 0.9.0
|
||||
description: Please see the README on GitHub at <https://github.com/abhin4v/hastatic#readme>
|
||||
author: Abhinav Sarkar
|
||||
maintainer: abhinav@abhinavsarkar.net
|
||||
copyright: 2018 Abhinav Sarkar
|
||||
license: BSD3
|
||||
license-file: LICENSE
|
||||
build-type: Simple
|
||||
cabal-version: >= 1.10
|
||||
extra-source-files:
|
||||
README.md
|
||||
|
||||
executable hastatic
|
||||
main-is: Main.hs
|
||||
other-modules:
|
||||
Paths_hastatic
|
||||
hs-source-dirs:
|
||||
src
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O2
|
||||
build-depends:
|
||||
base >=4.7 && <5
|
||||
, http-types
|
||||
, text
|
||||
, wai
|
||||
, wai-middleware-static
|
||||
, warp
|
||||
default-language: Haskell2010
|
30
package.yaml
Normal file
30
package.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
name: hastatic
|
||||
version: 0.9.0
|
||||
license: BSD3
|
||||
author: "Abhinav Sarkar"
|
||||
maintainer: "abhinav@abhinavsarkar.net"
|
||||
copyright: "2018 Abhinav Sarkar"
|
||||
|
||||
extra-source-files:
|
||||
- README.md
|
||||
|
||||
description: Please see the README on GitHub at <https://github.com/abhin4v/hastatic#readme>
|
||||
|
||||
dependencies:
|
||||
- base >= 4.7 && < 5
|
||||
|
||||
executables:
|
||||
hastatic:
|
||||
main: Main.hs
|
||||
source-dirs: src
|
||||
ghc-options:
|
||||
- -threaded
|
||||
- -rtsopts
|
||||
- -with-rtsopts=-N
|
||||
- -O2
|
||||
dependencies:
|
||||
- wai
|
||||
- warp
|
||||
- http-types
|
||||
- wai-middleware-static
|
||||
- text
|
43
src/Main.hs
Normal file
43
src/Main.hs
Normal file
@ -0,0 +1,43 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
module Main where
|
||||
|
||||
import Data.Maybe (fromMaybe)
|
||||
import qualified Data.List as List
|
||||
import qualified Data.Text as T
|
||||
import Network.Wai
|
||||
import Network.Wai.Middleware.Static
|
||||
import Network.HTTP.Types (status404)
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
import System.Environment (lookupEnv)
|
||||
import Text.Read (readMaybe)
|
||||
|
||||
indexHTML :: T.Text -> Middleware
|
||||
indexHTML indexFile app req respond =
|
||||
let path = pathInfo req
|
||||
in flip app respond $ req { pathInfo = fixPath path }
|
||||
where
|
||||
fixPath path = case path of
|
||||
[] -> [indexFile]
|
||||
[""] -> [indexFile]
|
||||
[x] -> if "." `T.isInfixOf` x then [x] else [x, indexFile]
|
||||
(x:xs) -> x : fixPath xs
|
||||
|
||||
notFoundHandler notFoundFile _ respond = respond $
|
||||
responseFile status404 [("Content-Type", "text/html")] notFoundFile Nothing
|
||||
|
||||
main = do
|
||||
mPort <- lookupEnv "PORT"
|
||||
let port = fromMaybe 3000 (readMaybe =<< mPort)
|
||||
mNotFoundFile <- lookupEnv "NF_FILE"
|
||||
let notFoundFile = fromMaybe "404.html" mNotFoundFile
|
||||
mIndexFile <- lookupEnv "IDX_FILE"
|
||||
let indexFile = T.pack $ fromMaybe "index.html" mIndexFile
|
||||
|
||||
cache <- initCaching PublicStaticCaching
|
||||
putStrLn $ "Starting server on port: " <> show port
|
||||
run port
|
||||
$ indexHTML indexFile
|
||||
$ staticPolicy' cache (predicate noDot)
|
||||
$ notFoundHandler notFoundFile
|
||||
where
|
||||
noDot = not . List.isPrefixOf "."
|
4
stack.yaml
Normal file
4
stack.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
resolver: lts-12.1
|
||||
|
||||
packages:
|
||||
- .
|
Loading…
Reference in New Issue
Block a user