Compare commits

..

23 Commits

Author SHA1 Message Date
80b2544f36 Fix issue #3 2020-08-31 14:03:48 +05:00
090767ba6b Readme file updated 2020-07-16 15:20:29 +05:00
a040c913e7 Set server_tokens off; in nginx server configuration 2020-07-16 15:19:44 +05:00
5ab113ba1a Update README.md 2020-07-16 12:15:57 +05:00
ea46e9f738 Update README.md 2020-07-16 12:14:34 +05:00
aeb6018a57 Update README.md 2020-07-14 15:05:36 +05:00
158856bebd Add 418 error (#2)
* Update config.json

Add 418 error

* Update CHANGELOG.md
2020-07-10 19:38:26 +05:00
f140dd3ad8 v1.2.0 2020-07-10 12:43:48 +05:00
699cccbdec v1.1.0 2020-07-10 00:15:05 +05:00
abc317955f Update README.md 2020-07-09 22:55:46 +05:00
be0d3b9e1f Update README.md 2020-07-09 16:59:14 +05:00
29fdeef742 Update README.md 2020-07-08 23:32:08 +05:00
96a47527e4 Workflow fixed 2020-07-08 22:56:45 +05:00
bce0277e7b Workflow fixed 2020-07-08 22:46:17 +05:00
a4a996c292 Readme updated 2020-07-08 22:41:41 +05:00
615310be7a Readme updated 2020-07-08 22:34:33 +05:00
be057d5988 Readme updated 2020-07-08 22:32:22 +05:00
657835f7f6 Readme updated 2020-07-08 22:27:33 +05:00
a0c9c7ab47 Readme updated 2020-07-08 22:26:40 +05:00
c58b9470c9 Repo workflow updated 2020-07-08 22:18:30 +05:00
f347c03965 Changelog updated 2020-07-08 22:16:50 +05:00
5e29c30c23 Improve repository 2020-07-08 22:15:53 +05:00
10ba04b263 repo renamed 2020-07-08 20:01:36 +05:00
15 changed files with 374 additions and 86 deletions

View File

@ -26,7 +26,13 @@ jobs:
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- name: Install dependencies
run: ./bin/generator.js -c ./configuration.json -o ./out
run: yarn install
- name: Generate pages
run: ./bin/generator.js -c ./config.json -o ./out
- name: Copy static files
run: cp ./static/* ./out
- name: Upload artifact
uses: actions/upload-artifact@v2
@ -54,7 +60,7 @@ jobs:
run: git add .
- name: Commit changes
run: git commit -m "Deploying ${GITHUB_SHA} to Github Pages"
run: git commit --allow-empty -m "Deploying ${GITHUB_SHA} to Github Pages"
- name: Push changes
run: git push github --force

View File

@ -30,7 +30,7 @@ jobs: # Docs: <https://git.io/JvxXE>
run: yarn install
- name: Run generator
run: ./bin/generator.js -c ./configuration.json -o ./out
run: ./bin/generator.js -c ./config.json -o ./out
- name: Test file creation
run: test -f ./out/ghost/404.html
@ -48,5 +48,11 @@ jobs: # Docs: <https://git.io/JvxXE>
- name: Run docker image
run: docker run --rm -d -p "8080:8080" -e "TEMPLATE_NAME=ghost" image:local
- name: Send HTTP request
- name: Pause
run: sleep 2
- name: Verify 500.html error file exists in root
run: curl -sS --fail "http://127.0.0.1:8080/500.html"
- name: Verify root request HTTP code
run: test $(curl --write-out %{http_code} --silent --output /dev/null http://127.0.0.1:8080/) -eq 404

View File

@ -4,6 +4,64 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
## v1.3.1
### Fixed
- `can't create directory '/opt/html/nginx-error-pages'` error [#3]
[#3]:https://github.com/tarampampam/error-pages/issues/3
## v1.3.0
### Added
- `418` status code error page
- Set `server_tokens off;` in `nginx` server configuration
## v1.2.0
### Fixed
- By default `nginx` in docker container returns 404 http code instead 200 when `/` requested
### Changed
- Default value for `TEMPLATE_NAME` is `ghost` now
### Removed
- Environment variable `DEFAULT_ERROR_CODE` support in docker image
### Added
- Templates `l7-light` and `l7-dark`
## v1.1.0
### Added
- Environment variable `DEFAULT_ERROR_CODE` support in docker image
## v1.0.1
### Changed
- Repository (not docker image) renamed from `error-pages-docker` to `error-pages`
- `configuration.json` renamed to `config.json`
- Makefile contains new targets (`install`, `gen`, `preview`)
- Generator logging messages
### Added
- `docker-compose` for development
### Fixed
- Readme file content [#1]
[#1]:https://github.com/tarampampam/error-pages/issues/1
## v1.0.0
### Changed

View File

@ -7,7 +7,7 @@ COPY . .
RUN set -x \
&& yarn install --frozen-lockfile \
&& ./bin/generator.js -c ./configuration.json -o ./out
&& ./bin/generator.js -c ./config.json -o ./out
# Image page: <https://hub.docker.com/_/nginx>
FROM nginx:1.18-alpine

View File

@ -5,17 +5,28 @@
SHELL = /bin/sh
DOCKER_BIN = $(shell command -v docker 2> /dev/null)
DC_BIN = $(shell command -v docker-compose 2> /dev/null)
DC_RUN_ARGS = --rm --user "$(shell id -u):$(shell id -g)"
APP_NAME = $(notdir $(CURDIR))
.PHONY : help install gen preview
.DEFAULT_GOAL : help
help: ## Show this help
@printf "\033[33m%s:\033[0m\n" 'Available commands'
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[32m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
image: ## Build docker image
install: ## Install all dependencies
$(DC_BIN) run $(DC_RUN_ARGS) app yarn install
gen: ## Generate error pages
$(DC_BIN) run $(DC_RUN_ARGS) app nodejs ./bin/generator.js -c ./config.json -o ./out
preview: ## Build docker image and start preview
$(DOCKER_BIN) build -f ./Dockerfile -t $(APP_NAME):local .
@printf "\n \e[30;42m %s \033[0m\n\n" 'Now you can use image like `docker run --rm -p 8080:8080 $(APP_NAME):local ...`'
@printf "\n \e[30;42m %s \033[0m\n\n" 'Now open in your favorite browser <http://127.0.0.1:8081> and press CTRL+C for stopping'
$(DOCKER_BIN) run --rm -i -p 8081:8080 -e "TEMPLATE_NAME=l7-light" $(APP_NAME):local
shell: ## Start shell into container with node
$(DOCKER_BIN) run --rm -ti -v "$(shell pwd):/src:rw" -w "/src" --user "$(shell id -u):$(shell id -g)" node:12.16.2-alpine sh
$(DC_BIN) run $(DC_RUN_ARGS) app sh

214
README.md
View File

@ -1,65 +1,173 @@
<p align="center">
<img src="https://hsto.org/webt/rg/ys/c3/rgysc33oc7jiufdzmwrkohpmef8.png" width="94" alt="" />
<img src="https://hsto.org/webt/rm/9y/ww/rm9ywwx3gjv9agwkcmllhsuyo7k.png" width="94" alt="" />
</p>
# Static error pages in a Docker container
# HTTP's error pages in Docker image
[![Build Status][badge_build_status]][link_build_status]
[![Image size][badge_size_latest]][link_docker_hub]
[![Docker Pulls][badge_docker_pulls]][link_docker_hub]
[![License][badge_license]][link_license]
This repository contains a very simple generator for server error pages _(like `404: Not found`)_ and ready docker image with web server for error pages serving.
This repository contains:
Generator ([`bin/generator.js`](./bin/generator.js)) allows you:
- Use different templates (section `templates` in configuration file)
- Generate pages with arbitrary content according to a specific template
- A very simple [generator](./bin/generator.js) _(`nodejs`)_ for HTTP error pages _(like `404: Not found`)_ with different templates supports
- Dockerfile for [docker image][link_docker_hub] with generated pages and `nginx` as web server
Can be used for [Traefik error pages customization](https://docs.traefik.io/middlewares/errorpages/).
### Usage
### Demo
Just execute (installed `nodejs` is required):
Generated pages (from the latest release) always [accessible here][link_branch_gh_pages] _(sources)_ and on GitHub pages [here][link_gh_pages].
## Development
> For project development we use `docker-ce` + `docker-compose`. Make sure you have them installed.
Install `nodejs` dependencies:
```bash
$ bin/generator.js -c ./configuration.json -o ./out
$ make install
```
And watch into `./out` directory:
```text
./out
└── ghost
├── 400.html
├── 401.html
├── 403.html
├── 404.html
├── ...
└── 505.html
```
Default configuration can be found in [`configuration.json`](./configuration.json) file.
### Docker
[![Image size][badge_size_latest]][link_docker_build]
Start image (`nginx` inside):
If you want to generate error pages on your machine _(after that look into output directory)_:
```bash
$ docker run --rm -p "8080:8080" tarampampam/error-pages:1.0.0
$ make gen
```
And open in your browser `http://127.0.0.1:8080/ghost/400.html`. Additionally, you can set "default" pages theme by passing `TEMPLATE_NAME` environment variable (eg.: `-e "TEMPLATE_NAME=ghost"`) - in this case all error pages will be accessible in root directory (eg.: `http://127.0.0.1:8080/400.html`).
If you want to preview the pages using the Docker image:
Also you can use generated error pages in your own docker images:
```bash
$ make preview
```
## Templates
Name | Preview
:--------: | :-----:
`ghost` | ![ghost](https://hsto.org/webt/zg/ul/cv/zgulcvxqzhazoebxhg8kpxla8lk.png)
`l7-light` | ![ghost](https://hsto.org/webt/xc/iq/vt/xciqvty-aoj-rchfarsjhutpjny.png)
`l7-dark` | ![ghost](https://hsto.org/webt/s1/ih/yr/s1ihyrqs_y-sgraoimfhk6ypney.png)
## Usage
Generated error pages in our [docker image][link_docker_hub] permanently located in directory `/opt/html/%TEMPLATE_NAME%`. `nginx` in a container listen for `8080` (`http`) port.
#### Supported environment variables
Name | Description
--------------- | -----------
`TEMPLATE_NAME` | (`ghost` by default) "default" pages template _(allows to use error pages without passing theme name in URL - `http://127.0.0.1/500.html` instead `http://127.0.0.1/ghost/500.html`)_
### HTTP server for error pages serving only
Execute in your shell:
```bash
$ docker run --rm -p "8082:8080" tarampampam/error-pages:1.3.0
```
And open in your browser `http://127.0.0.1:8082/ghost/400.html`.
### Custom error pages for [nginx][link_nginx]
You can build your own docker image with `nginx` and our error pages:
```nginx
# File `./nginx.conf`
server {
listen 80;
server_name localhost;
error_page 401 /_error-pages/401.html;
error_page 403 /_error-pages/403.html;
error_page 404 /_error-pages/404.html;
error_page 500 /_error-pages/500.html;
error_page 502 /_error-pages/502.html;
error_page 503 /_error-pages/503.html;
location ^~ /_error-pages/ {
internal;
root /usr/share/nginx/errorpages;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
```
```dockerfile
FROM nginx:1.18-alpine
COPY --from=tarampampam/error-pages:1.0.0 /opt/html/ghost /usr/share/nginx/html/error-pages
COPY --chown=nginx \
./nginx.conf /etc/nginx/conf.d/default.conf
COPY --chown=nginx \
--from=tarampampam/error-pages:1.3.0 \
/opt/html/ghost /usr/share/nginx/errorpages/_error-pages
```
> [`error_page` for `nginx` configuration](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page)
> More info about `error_page` directive can be [found here](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page).
### Custom error pages for [Traefik][link_traefik]
Simple traefik (tested on `v2.2.1`) service configuration for usage in [docker swarm][link_swarm] (**change with your needs**):
```yaml
version: '3.4'
services:
error-pages:
image: tarampampam/error-pages:1.3.0
environment:
TEMPLATE_NAME: l7-dark
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role == worker
labels:
traefik.enable: 'true'
traefik.docker.network: traefik-public
# use as "fallback" for any non-registered services (with priority below normal)
traefik.http.routers.error-pages-router.rule: HostRegexp(`{host:.+}`)
traefik.http.routers.error-pages-router.priority: 10
# should say that all of your services work on https
traefik.http.routers.error-pages-router.tls: 'true'
traefik.http.routers.error-pages-router.entrypoints: https
traefik.http.routers.error-pages-router.middlewares: error-pages-middleware@docker
traefik.http.services.error-pages-service.loadbalancer.server.port: 8080
# "errors" middleware settings
traefik.http.middlewares.error-pages-middleware.errors.status: 400-599
traefik.http.middlewares.error-pages-middleware.errors.service: error-pages-service@docker
traefik.http.middlewares.error-pages-middleware.errors.query: /{status}.html
any-another-http-service:
image: nginx:alpine
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role == worker
labels:
traefik.enable: 'true'
traefik.docker.network: traefik-public
traefik.http.routers.another-service.rule: Host(`subdomain.example.com`)
traefik.http.routers.another-service.tls: 'true'
traefik.http.routers.another-service.entrypoints: https
# next line is important
traefik.http.routers.another-service.middlewares: error-pages-middleware@docker
traefik.http.services.another-service.loadbalancer.server.port: 80
networks:
traefik-public:
external: true
```
## Changes log
@ -79,19 +187,25 @@ If you will find any package errors, please, [make an issue][link_create_issue]
This is open-sourced software licensed under the [MIT License][link_license].
[badge_build_status]:https://img.shields.io/github/workflow/status/tarampampam/error-pages-docker/tests/master
[badge_release_date]:https://img.shields.io/github/release-date/tarampampam/error-pages-docker.svg?style=flat-square&maxAge=180
[badge_commits_since_release]:https://img.shields.io/github/commits-since/tarampampam/error-pages-docker/latest.svg?style=flat-square&maxAge=180
[badge_issues]:https://img.shields.io/github/issues/tarampampam/error-pages-docker.svg?style=flat-square&maxAge=180
[badge_pulls]:https://img.shields.io/github/issues-pr/tarampampam/error-pages-docker.svg?style=flat-square&maxAge=180
[badge_license]:https://img.shields.io/github/license/tarampampam/error-pages-docker.svg?longCache=true
[badge_build_status]:https://img.shields.io/github/workflow/status/tarampampam/error-pages/tests/master
[badge_release_date]:https://img.shields.io/github/release-date/tarampampam/error-pages.svg?style=flat-square&maxAge=180
[badge_commits_since_release]:https://img.shields.io/github/commits-since/tarampampam/error-pages/latest.svg?style=flat-square&maxAge=180
[badge_issues]:https://img.shields.io/github/issues/tarampampam/error-pages.svg?style=flat-square&maxAge=180
[badge_pulls]:https://img.shields.io/github/issues-pr/tarampampam/error-pages.svg?style=flat-square&maxAge=180
[badge_license]:https://img.shields.io/github/license/tarampampam/error-pages.svg?longCache=true
[badge_size_latest]:https://img.shields.io/docker/image-size/tarampampam/error-pages/latest?maxAge=30
[link_releases]:https://github.com/tarampampam/error-pages-docker/releases
[link_commits]:https://github.com/tarampampam/error-pages-docker/commits
[link_changes_log]:https://github.com/tarampampam/error-pages-docker/blob/master/CHANGELOG.md
[link_issues]:https://github.com/tarampampam/error-pages-docker/issues
[link_pulls]:https://github.com/tarampampam/error-pages-docker/pulls
[link_build_status]:https://travis-ci.org/tarampampam/error-pages-docker
[link_create_issue]:https://github.com/tarampampam/error-pages-docker/issues/new
[link_license]:https://github.com/tarampampam/error-pages-docker/blob/master/LICENSE
[link_docker_build]:https://hub.docker.com/r/tarampampam/error-pages/
[badge_docker_pulls]:https://img.shields.io/docker/pulls/tarampampam/error-pages.svg
[link_releases]:https://github.com/tarampampam/error-pages/releases
[link_commits]:https://github.com/tarampampam/error-pages/commits
[link_changes_log]:https://github.com/tarampampam/error-pages/blob/master/CHANGELOG.md
[link_issues]:https://github.com/tarampampam/error-pages/issues
[link_pulls]:https://github.com/tarampampam/error-pages/pulls
[link_build_status]:https://travis-ci.org/tarampampam/error-pages
[link_create_issue]:https://github.com/tarampampam/error-pages/issues/new
[link_license]:https://github.com/tarampampam/error-pages/blob/master/LICENSE
[link_docker_hub]:https://hub.docker.com/r/tarampampam/error-pages/
[link_nginx]:http://nginx.org/
[link_traefik]:https://docs.traefik.io/
[link_swarm]:https://docs.docker.com/engine/swarm/
[link_branch_gh_pages]:https://github.com/tarampampam/error-pages/tree/gh-pages
[link_gh_pages]:https://tarampampam.github.io/error-pages/

View File

@ -46,7 +46,9 @@ try {
// Loop over all pages
configContent.pages.forEach((pageConfig) => {
console.info(`Page with code ${pageConfig.code} generation...`);
let outPath = path.join(templateOutDir, `${pageConfig.code}.${configContent.output.file_extension}`);
console.info(` [${templateConfig.name}:${pageConfig.code}] Output: ${outPath}`);
// Make replaces
let result = layoutContent
@ -55,7 +57,7 @@ try {
.replace(/{{\s?description\s?}}/g, pageConfig.description);
// And write into result file
fs.writeFileSync(path.join(templateOutDir, `${pageConfig.code}.${configContent.output.file_extension}`), result, {
fs.writeFileSync(outPath, result, {
encoding: "utf8",
flag: "w+",
mode: 0o644

View File

@ -3,6 +3,14 @@
{
"name": "ghost",
"path": "./templates/ghost.html"
},
{
"name": "l7-light",
"path": "./templates/l7-light.html"
},
{
"name": "l7-dark",
"path": "./templates/l7-dark.html"
}
],
"output": {
@ -74,6 +82,11 @@
"message": "Requested Range Not Satisfiable",
"description": "The requested byte range is not available and is out of bounds"
},
{
"code": 418,
"message": "I'm a teapot",
"description": "Attempt to brew coffee with a teapot is not supported"
},
{
"code": 429,
"message": "Too Many Requests",

17
docker-compose.yml Normal file
View File

@ -0,0 +1,17 @@
version: '3.2'
volumes:
tmp-data:
services:
app:
image: node:12.16.2-alpine # Image page: <https://hub.docker.com/_/node>
working_dir: /src
environment:
HOME: /tmp
PS1: '\[\033[1;32m\]\[\033[1;36m\][\u@docker] \[\033[1;34m\]\w\[\033[0;35m\] \[\033[1;36m\]# \[\033[0m\]'
volumes:
- /etc/passwd:/etc/passwd:ro
- /etc/group:/etc/group:ro
- .:/src:cached
- tmp-data:/tmp:cached

View File

@ -1,7 +1,7 @@
#!/usr/bin/env sh
set -e
TEMPLATE_NAME=${TEMPLATE_NAME:-} # string|empty
TEMPLATE_NAME=${TEMPLATE_NAME:-ghost} # string|empty
if [ -n "$TEMPLATE_NAME" ]; then
echo "$0: set pages for template '$TEMPLATE_NAME' as default (make accessible in root directory)";
@ -11,6 +11,15 @@ if [ -n "$TEMPLATE_NAME" ]; then
fi;
ln -f -s "/opt/html/$TEMPLATE_NAME/"* /opt/html;
# on `docker restart` next directory keep existing: <https://github.com/tarampampam/error-pages/issues/3>
if [ -d /opt/html/nginx-error-pages ]; then
rm -Rf /opt/html/nginx-error-pages;
fi;
# next directory is required for easy nginx `error_page` usage
mkdir /opt/html/nginx-error-pages;
ln -f -s "/opt/html/$TEMPLATE_NAME/"* /opt/html/nginx-error-pages;
fi;
exec "$@"

View File

@ -2,8 +2,24 @@ server {
listen 8080;
server_name _;
server_tokens off;
index index.html index.htm;
root /opt/html;
error_page 400 /nginx-error-pages/400.html;
error_page 401 /nginx-error-pages/401.html;
error_page 403 /nginx-error-pages/403.html;
error_page 404 /nginx-error-pages/404.html;
error_page 500 /nginx-error-pages/500.html;
error_page 502 /nginx-error-pages/502.html;
location ^~ /nginx-error-pages/ {
internal;
root /opt/html;
}
location / {
root /opt/html;
index index.html index.htm;
try_files $uri =404;
}
}

View File

@ -2,7 +2,7 @@
"name": "error-pages",
"repository": {
"type": "git",
"url": "git://github.com/tarampampam/error-pages-docker.git"
"url": "git://github.com/tarampampam/error-pages.git"
},
"dependencies": {
"yargs": "15.3"

View File

@ -1,22 +0,0 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="robots" content="noindex, nofollow" />
<title>Error pages</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css" />
<style type="text/css">
html,body {background-color:#fff;font-family:'Montserrat',sans-serif;color:#1a1a1a;overflow:hidden}
.wrap {top:50%;left:50%;width:350px;height:260px;margin-left:-175px;margin-top:-130px;position:absolute;text-align:center}
.wrap h1 {font-size: 3em; margin-top: 0}
.wrap p {font-size: 0.85em}
.wrap p.small {font-size: 0.6em}
</style>
</head><body>
<div class="wrap">
<h1>Error pages</h1>
<p class="small">
For online documentation and support please refer to <a href="https://github.com/tarampampam/error-pages-docker">project repository</a>.
</p>
</div>
</body></html>

29
templates/l7-dark.html Normal file
View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow" />
<title>{{ message }}</title>
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<style>
html,body {background-color: #222526;color:#fff;font-family:'Nunito',sans-serif;font-weight:100;height:100vh;margin:0}
.full-height {height:100vh}
.flex-center {align-items:center;display:flex;justify-content:center}
.position-ref {position:relative}
.code {border-right:2px solid;font-size:26px;padding:0 10px 0 15px;text-align:center}
.message {font-size:18px;text-align:center;padding:10px}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
<div class="code">
{{ code }}
</div>
<div class="message">
{{ message }}
</div>
</div>
</body>
</html>

29
templates/l7-light.html Normal file
View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow" />
<title>{{ message }}</title>
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<style>
html,body {background-color:#fff;color:#636b6f;font-family:'Nunito',sans-serif;font-weight:100;height:100vh;margin:0}
.full-height {height:100vh}
.flex-center {align-items:center;display:flex;justify-content:center}
.position-ref {position:relative}
.code {border-right:2px solid;font-size:26px;padding:0 10px 0 15px;text-align:center}
.message {font-size:18px;text-align:center;padding:10px}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
<div class="code">
{{ code }}
</div>
<div class="message">
{{ message }}
</div>
</div>
</body>
</html>