Configurable website in Docker
This commit is contained in:
commit
e6cd7a0f6d
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
npm-debug.log
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@ -0,0 +1,17 @@
|
||||
# Based on node
|
||||
FROM node:13-alpine
|
||||
|
||||
RUN apk add git
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install app dependencies
|
||||
RUN git clone https://git.heshapps.com/asolkar/mma-website.git .
|
||||
|
||||
RUN npm install
|
||||
RUN npm ci --only=production
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["node", "website.js"]
|
||||
|
54
README.md
Normal file
54
README.md
Normal file
@ -0,0 +1,54 @@
|
||||
# Build docker image
|
||||
|
||||
% cd <app source directory>
|
||||
% docker build --tag mahesh/mma-website --no-cache .
|
||||
|
||||
*Note*: If `--no-cache` is not used, cloning of git repo from the docker file does not work in subsequent builds
|
||||
|
||||
# Run docker container
|
||||
|
||||
% docker run --publish 49330:3000 --detach mahesh/mma-website
|
||||
7e4dfed65d776e3c8cd8e5c6e970699b561bbbc6f2d63d5d75b7ee68c9672358
|
||||
|
||||
# Get a shell in running container
|
||||
|
||||
% docker exec --interactive --tty 7e4dfed65d776e3c8cd8e5c6e970699b561bbbc6f2d63d5d75b7ee68c9672358 /bin/bash
|
||||
|
||||
# Manage docker containers
|
||||
|
||||
* List running containers
|
||||
|
||||
```
|
||||
% docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
d511b20c73d6 mahesh/mma-website "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:49330->3000/tcp upbeat_lederberg
|
||||
```
|
||||
|
||||
* List all docker containrs
|
||||
|
||||
```
|
||||
% docker ps --all
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
d511b20c73d6 mahesh/mma-website "docker-entrypoint.s…" 12 minutes ago Exited (137) 3 minutes ago upbeat_lederberg
|
||||
% docker ps --all --quiet
|
||||
d511b20c73d6
|
||||
```
|
||||
|
||||
* Stop a running container
|
||||
|
||||
```
|
||||
% docker stop d511b20c73d6
|
||||
```
|
||||
|
||||
* Remove a container
|
||||
|
||||
```
|
||||
% docker rm d511b20c73d6
|
||||
```
|
||||
|
||||
# Local debug
|
||||
|
||||
```
|
||||
% SITE_NAME="asolkar.net" SITE_URL="https://asolkar.net" SITE_TITLE="Home of the Asolkars ..." node website.js
|
||||
Server running at http://0.0.0.0:3000/
|
||||
```
|
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "mma_website_docker",
|
||||
"version": "0.1",
|
||||
"description": "Generic Website",
|
||||
"author": "Mahesh Asolkar <mahesh@mahesha.com>",
|
||||
"main": "website.js",
|
||||
"scripts": {
|
||||
"start": "node website.js"
|
||||
}
|
||||
}
|
48
siteinfo.js
Normal file
48
siteinfo.js
Normal file
@ -0,0 +1,48 @@
|
||||
// Exported functions
|
||||
module.exports = {
|
||||
site_info: function (req) {
|
||||
|
||||
var ret = {
|
||||
"site_name": "Website Template",
|
||||
"site_url": "https://website.template",
|
||||
"site_title": "Title of website",
|
||||
};
|
||||
|
||||
if ("SITE_NAME" in process.env) {
|
||||
ret.name = process.env.SITE_NAME;
|
||||
}
|
||||
if ("SITE_URL" in process.env) {
|
||||
ret.url = process.env.SITE_URL;
|
||||
}
|
||||
if ("SITE_TITLE" in process.env) {
|
||||
ret.title = process.env.SITE_TITLE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
site_ga_stub: function (req) {
|
||||
// Tracking disabled by DNT
|
||||
if (("dnt" in req.headers) && (req.headers["dnt"] == 1)) {
|
||||
return `<!-- DNT - Tracking disabled -->`;
|
||||
}
|
||||
|
||||
// Google Analytics stub
|
||||
if ("SITE_GA_ID" in process.env) {
|
||||
return `
|
||||
<!-- Google Analytics stuff -->
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var pageTracker = _gat._getTracker("${process.env.SITE_GA_ID}");
|
||||
pageTracker._trackPageview();
|
||||
} catch(err) {}</script>`;
|
||||
}
|
||||
|
||||
// Default - no tracking information provided
|
||||
return "<!-- No GA Tracking -->";
|
||||
|
||||
}
|
||||
}
|
294
website.js
Normal file
294
website.js
Normal file
@ -0,0 +1,294 @@
|
||||
'use strict';
|
||||
|
||||
const http = require('http');
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
const hostname = '0.0.0.0';
|
||||
const port = 3000;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
var siteinfo = require('./siteinfo.js');
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
function getPage(req) {
|
||||
var route = req.url.substring(1);
|
||||
var website = siteinfo.site_info(req);
|
||||
var ga_tracking_stub = siteinfo.site_ga_stub(req);
|
||||
|
||||
console.log(`Serving route ${route}`);
|
||||
|
||||
return `<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
|
||||
<title>${website.title}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="description" content="${website.title}">
|
||||
<meta name="keywords" content="">
|
||||
|
||||
<!-- Mobile stylesheet -->
|
||||
<style type="text/css" media="handheld">
|
||||
body {
|
||||
font-family : "Trebuchet MS", sans-serif;
|
||||
font-size : 13px;
|
||||
background-color : white;
|
||||
color: gray;
|
||||
margin : 0 0 0 0;
|
||||
}
|
||||
* {
|
||||
visibility : visible;
|
||||
overflow : auto;
|
||||
margin : 0;
|
||||
padding : 0;
|
||||
}
|
||||
img {
|
||||
display : none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- All other media -->
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
font-family : "Trebuchet MS", sans-serif;
|
||||
font-size : 13px;
|
||||
background-color : white;
|
||||
margin : 0 0 0 0;
|
||||
}
|
||||
|
||||
#osc_txt {
|
||||
margin: 0pt auto;
|
||||
display: block;
|
||||
width: 600px;
|
||||
font-size: 64px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 3px solid #eeeeee;
|
||||
border-top: 3px solid #eeeeee;
|
||||
}
|
||||
#col_1, #col_2, #col_3, #col_4, #col_5 {
|
||||
text-align: center;
|
||||
padding-top: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
#col_1 {
|
||||
opacity: 1;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
|
||||
filter: alpha(opacity=100);
|
||||
font-size: 30px;
|
||||
}
|
||||
#col_2 {
|
||||
opacity: .8;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
||||
filter: alpha(opacity=80);
|
||||
font-size: 25px;
|
||||
}
|
||||
#col_3 {
|
||||
opacity: .6;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
|
||||
filter: alpha(opacity=60);
|
||||
font-size: 20px;
|
||||
}
|
||||
#col_4 {
|
||||
opacity: .4;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
|
||||
filter: alpha(opacity=40);
|
||||
font-size: 16px;
|
||||
}
|
||||
#col_5 {
|
||||
opacity: .2;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
|
||||
filter: alpha(opacity=20);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Navigation strip */
|
||||
#nav_strip {
|
||||
/*float: right;*/
|
||||
text-align: center;
|
||||
margin-top: 150px;
|
||||
margin-bottom: 20px;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
#nav_strip a {
|
||||
color: #777777;
|
||||
text-decoration: none;
|
||||
}
|
||||
#nav_strip a:hover {
|
||||
color: #77aa77;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Setlist, control */
|
||||
#foot {
|
||||
position: fixed;
|
||||
bottom: 5px;
|
||||
text-align: center;
|
||||
color: #cccccc;
|
||||
width: 100%;
|
||||
}
|
||||
#setlist a, #control a {
|
||||
color: #777777;
|
||||
text-decoration: none;
|
||||
}
|
||||
#setlist a:hover, #control a:hover {
|
||||
color: #77aa77;
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var rd = {val:0, max:0, min:0, step:0, trend:1, itr:0};
|
||||
var gr = {val:0, max:0, min:0, step:0, trend:1, itr:0};
|
||||
var bl = {val:0, max:0, min:0, step:0, trend:1, itr:0};
|
||||
var col_update_timer = 50;
|
||||
var color_display = 'dot';
|
||||
var player_state = 'play';
|
||||
|
||||
function advance_color(clr) {
|
||||
if ((clr.itr == 0) && (clr.trend == 1)) {
|
||||
clr.min = Math.ceil(Math.random() * 50);
|
||||
clr.max = 206 + (Math.ceil(Math.random() * 50));
|
||||
clr.val = clr.min;
|
||||
clr.step = 1;
|
||||
}
|
||||
|
||||
if (clr.trend == 1) {
|
||||
clr.itr ++;
|
||||
if (clr.itr < (clr.max - clr.min)) {
|
||||
clr.val += clr.step;
|
||||
} else {
|
||||
clr.val -= clr.step;
|
||||
clr.trend = 0;
|
||||
}
|
||||
} else {
|
||||
clr.itr --;
|
||||
if (clr.itr > 0) {
|
||||
clr.val -= clr.step;
|
||||
} else {
|
||||
clr.val += clr.step;
|
||||
clr.trend = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function random_colorize_job () {
|
||||
var item = document.getElementById ("osc_txt");
|
||||
|
||||
advance_color (rd);
|
||||
advance_color (gr);
|
||||
advance_color (bl);
|
||||
|
||||
item.style.color = "rgb("+rd.val+","+gr.val+","+bl.val+")";
|
||||
if (color_display == 'rgb') {
|
||||
color_str = item.style.color;
|
||||
} else if (color_display == 'dot') {
|
||||
color_str = "• • • •";
|
||||
} else {
|
||||
color_str = "#" + rd.val.toString(16) + gr.val.toString(16) + bl.val.toString(16);
|
||||
}
|
||||
|
||||
col_update_timer--;
|
||||
|
||||
if (col_update_timer == 0) {
|
||||
col_update_timer = 50;
|
||||
document.getElementById ("col_5").innerHTML = document.getElementById ("col_4").innerHTML;
|
||||
document.getElementById ("col_5").style.color = document.getElementById ("col_4").style.color;
|
||||
document.getElementById ("col_4").innerHTML = document.getElementById ("col_3").innerHTML;
|
||||
document.getElementById ("col_4").style.color = document.getElementById ("col_3").style.color;
|
||||
document.getElementById ("col_3").innerHTML = document.getElementById ("col_2").innerHTML;
|
||||
document.getElementById ("col_3").style.color = document.getElementById ("col_2").style.color;
|
||||
document.getElementById ("col_2").innerHTML = document.getElementById ("col_1").innerHTML;
|
||||
document.getElementById ("col_2").style.color = document.getElementById ("col_1").style.color;
|
||||
// document.getElementById ("col_1").innerHTML = item.style.color;
|
||||
document.getElementById ("col_1").innerHTML = color_str;
|
||||
document.getElementById ("col_1").style.color = item.style.color;
|
||||
}
|
||||
}
|
||||
|
||||
function random_colorize() {
|
||||
if (player_state == 'play') {
|
||||
random_colorize_job();
|
||||
}
|
||||
tmot = setTimeout("random_colorize()",20);
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
change_display(color_display);
|
||||
|
||||
random_colorize();
|
||||
}
|
||||
|
||||
function change_display (elem) {
|
||||
color_display = elem;
|
||||
if (color_display == 'rgb') {
|
||||
document.getElementById('rgb_ln').style.fontWeight = 'bold';
|
||||
document.getElementById('hex_ln').style.fontWeight = 'normal';
|
||||
document.getElementById('dot_ln').style.fontWeight = 'normal';
|
||||
} else if (color_display == 'dot') {
|
||||
document.getElementById('rgb_ln').style.fontWeight = 'normal';
|
||||
document.getElementById('hex_ln').style.fontWeight = 'normal';
|
||||
document.getElementById('dot_ln').style.fontWeight = 'bold';
|
||||
} else {
|
||||
document.getElementById('rgb_ln').style.fontWeight = 'normal';
|
||||
document.getElementById('hex_ln').style.fontWeight = 'bold';
|
||||
document.getElementById('dot_ln').style.fontWeight = 'normal';
|
||||
}
|
||||
}
|
||||
|
||||
function toggle_play () {
|
||||
if (player_state == 'play') {
|
||||
player_state = 'pause';
|
||||
document.getElementById('pp_button').innerHTML = 'Play';
|
||||
} else {
|
||||
player_state = 'play';
|
||||
document.getElementById('pp_button').innerHTML = 'Pause';
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
</head><body onload="initialize()">
|
||||
<div id="nav_strip">
|
||||
<a href="${website.url}" title="Home">Home</a>
|
||||
</div>
|
||||
<div id="osc_txt">
|
||||
${website.name}
|
||||
</div>
|
||||
<div id="col_1"></div>
|
||||
<div id="col_2"></div>
|
||||
<div id="col_3"></div>
|
||||
<div id="col_4"></div>
|
||||
<div id="col_5"></div>
|
||||
<div id="foot">
|
||||
<div id="control">
|
||||
<a href="javascript:toggle_play()" title="Toggle Play" id="pp_button">Pause</a>
|
||||
</div>
|
||||
<div id="setlist">
|
||||
<a href="javascript:change_display('rgb')" title="Display colors in RGB values" id="rgb_ln"> RGB</a> •
|
||||
<a href="javascript:change_display('hex')" title="Display colors in Hex values" id="hex_ln"> Hex</a> •
|
||||
<a href="javascript:change_display('dot')" title="Display colored dots" id="dot_ln"> Dots</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${ga_tracking_stub}
|
||||
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
const server = http.createServer((req, res) => {
|
||||
res.statusCode = 200;
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.write(getPage(req));
|
||||
res.end();
|
||||
console.log(`Serviced request ${req}`);
|
||||
}).listen(port, hostname, () => {
|
||||
console.log(`Server running at http://${hostname}:${port}/`);
|
||||
});
|
Loading…
Reference in New Issue
Block a user