Skip to content
This repository was archived by the owner on Oct 27, 2021. It is now read-only.

Commit dfc2a7b

Browse files
jalogischDonald Morton
and
Donald Morton
authored
added docker based env (#863)
Co-Authored-By: Donald Morton <[email protected]>
1 parent 1c26083 commit dfc2a7b

File tree

6 files changed

+264
-1
lines changed

6 files changed

+264
-1
lines changed

.sphinx-server.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Set autobuild to false if you do not want to enable compilation when a file changes.
2+
# This will enable http authentication if credentials section is filled.
3+
autobuild: true
4+
5+
# Add files and folders you want autobuild watcher to ignore on changes.
6+
ignore:
7+
- .git
8+
9+
# Add a username and a password if you want to enable http authentication.
10+
# This will not work if autobuild is enabled.
11+
credentials:
12+
username: ~
13+
password: ~

Dockerfile

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM python:3-alpine
2+
3+
MAINTAINER Jan Doberstein <[email protected]>
4+
5+
COPY ./requirements.txt requirements.txt
6+
7+
RUN apk add --no-cache --virtual --update py3-pip make wget ca-certificates ttf-dejavu \
8+
&& pip install --upgrade pip \
9+
&& pip install --no-cache-dir -r requirements.txt
10+
11+
COPY ./server.py /opt/sphinx-server/
12+
COPY ./.sphinx-server.yml /opt/sphinx-server/
13+
14+
WORKDIR /web
15+
16+
EXPOSE 8000 35729
17+
18+
CMD ["python", "/opt/sphinx-server/server.py"]

README.md

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# The Graylog documentation
2-
[![Build Status](https://travis-ci.org/Graylog2/documentation.svg?branch=2.2)](https://travis-ci.org/Graylog2/documentation)
2+
[![Build Status](https://travis-ci.org/Graylog2/documentation.svg?branch=3.2)](https://travis-ci.org/Graylog2/documentation)
3+
4+
Table of Contents
5+
=================
6+
7+
* [Architecture](#architecture)
8+
* [Build](#building-locally)
9+
* [Mac & Linus](#or-using-pathogen)
10+
* [Windows](#or-using-vundle)
11+
* [Docker](#docker)
12+
* [docker-compose](#docker-compose)
13+
* [Daily usage](#daily-usage)
314

415
## Architecture
516

@@ -99,6 +110,31 @@ Use the python package manager `pip` to install `virtulenv`. Create the virtual
99110
# pip install -r requirements.txt
100111

101112
Once the above is done you are prepared to contribute to the documentation and preview the work live in your local browser. See the daily usage chapter.
113+
114+
#### Docker
115+
116+
To ease up contributions to the documentation, you can also use Docker to create a local environment for the documentation. The image is built locally and uses the current base dir of this repository for creating and serving the documentation. This way, there's no need to handle virtual environments. Just build the image and run.
117+
118+
119+
docker build -t graylog/documentation -f Dockerfile .
120+
docker run -it -d --rm -v .:/web -u $(id -u):$(id -g) -p 8000:8000 --name graylog/documentation graylog-documentation
121+
122+
##### docker_run.sh (helper)
123+
124+
If unsure how to run what command with docker, the simple script `docker_run.sh` was created. This runs on Mac and Linux (maybe Windows when bash is available). The simplification is done in a way that you just need to run the command. If necessary it will build the image, and start the docker container. If the container is up and running it will ask if the container should be stopped. In addition it will be ask if the image should be removed too.
125+
126+
If unsure how to operate the docker image - use this script.
127+
128+
##### docker-compose
129+
130+
When docker-compose is installed, you could use this too - the provided `docker-compose.yml` includes all settings and information that are needed to build and run the docker container. All well known `docker-compose` commands can be used.
131+
132+
docker-compose up
133+
134+
To rebuild the image, for example to include the new pip requirements the `build` command is needed.
135+
136+
docker-compose build
137+
102138

103139
### daily usage
104140

docker-compose.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: '3'
2+
services:
3+
graylog-documentation:
4+
build: .
5+
image: graylog/documentation
6+
container_name: graylog-documentation
7+
ports:
8+
- "8000:8000"
9+
volumes:
10+
- .:/web
11+

docker_run.sh

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env bash
2+
3+
THIS_DIR=$(cd `dirname $0`; pwd -P)
4+
DOCKER_IMAGE_NAME="graylog/documentation"
5+
DOCKER_CONTAINER_NAME="graylog-documentation"
6+
7+
function exit_error {
8+
message="${1}"
9+
echo -e "\n\033[31mERROR: $message\033[0m" >/dev/stderr
10+
exit 1
11+
}
12+
13+
# check if Docker is installed
14+
which docker >/dev/null
15+
if [[ $? != 0 ]] ; then
16+
exit_error "Docker does not seem to be installed (or resides in an unusual path). Please fix that first."
17+
fi
18+
19+
# if the image is running ask to stop
20+
docker ps | grep -qw ${DOCKER_CONTAINER_NAME}
21+
if [[ $? == 0 ]] ; then
22+
read -p "Graylog documentation Docker container running, Stop? (y/n)" -n 1 -r
23+
echo # (optional) move to a new line
24+
if [[ $REPLY =~ ^[Yy]$ ]] ; then
25+
26+
# stop
27+
docker stop ${DOCKER_CONTAINER_NAME}
28+
29+
if [[ $? == 0 ]] ; then
30+
read -p "remove the Graylog documentation Docker image? (y/n)" -n 1 -r
31+
echo # (optional) move to a new line
32+
if [[ $REPLY =~ ^[Yy]$ ]] ; then
33+
docker rmi ${DOCKER_IMAGE_NAME}
34+
exit 0
35+
fi
36+
fi
37+
38+
exit 0
39+
fi
40+
41+
echo "no action needed."
42+
echo "connect to the Graylog Docker container"
43+
echo "defaults to http://127.0.0.1:8000"
44+
exit 0
45+
fi
46+
47+
# check if Docker image is present, otherwise build it
48+
docker images | grep -qw ${DOCKER_IMAGE_NAME}
49+
if [[ $? != 0 ]] ; then
50+
echo "Docker image not found, will build it now"
51+
docker build -t ${DOCKER_IMAGE_NAME} -f ${THIS_DIR}/Dockerfile . && echo "Done"
52+
fi
53+
54+
# read additional environment variables from .env, if present
55+
[[ -e ${THIS_DIR}/.env ]] && source ${THIS_DIR}/.env
56+
57+
# check if Docker container is present, otherwise make the first start with all arguments
58+
docker ps -a | grep -qw ${DOCKER_CONTAINER_NAME}
59+
if [[ $? != 0 ]] ; then
60+
echo "Docker starting:"
61+
docker run -it -d --rm -v "${THIS_DIR}":/web -u $(id -u):$(id -g) -p 8000:8000 --name ${DOCKER_CONTAINER_NAME} ${DOCKER_IMAGE_NAME}
62+
63+
echo "Graylog documentation Docker container created,"
64+
echo "defaults to http://127.0.0.1:8000"
65+
exit 0
66+
fi
67+
68+
# now the normal start should be possible, but we will check
69+
docker images | grep -qw ${DOCKER_CONTAINER_NAME}
70+
if [[ $? == 0 ]] ; then
71+
echo "Starting the Docker container, will be serving on http://127.0.0.1:8000 by default"
72+
docker start graylog-documentation
73+
exit 0
74+
fi
75+
76+
exit_error "we should never reach this point!"

server.py

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import sphinx_autobuild
2+
import os
3+
import sys
4+
from contextlib import contextmanager
5+
import base64
6+
from livereload import Server
7+
import http.server
8+
import http.server
9+
import socketserver
10+
import yaml
11+
12+
13+
class AuthHandler(http.server.SimpleHTTPRequestHandler):
14+
"""
15+
Authentication handler used to support HTTP authentication
16+
"""
17+
def do_HEAD(self):
18+
self.send_response(200)
19+
self.send_header('Content-type', 'text/html')
20+
self.end_headers()
21+
22+
def do_AUTHHEAD(self):
23+
self.send_response(401)
24+
self.send_header('WWW-Authenticate', 'Basic realm=\"Restricted area\"')
25+
self.send_header('Content-type', 'text/html')
26+
self.end_headers()
27+
28+
def do_GET(self):
29+
global key
30+
if self.headers.get('Authorization') is None:
31+
self.do_AUTHHEAD()
32+
self.wfile.write('Credentials required.'.encode('utf-8'))
33+
pass
34+
elif self.headers.get('Authorization') == 'Basic ' + key.decode('utf-8'):
35+
http.server.SimpleHTTPRequestHandler.do_GET(self)
36+
pass
37+
else:
38+
self.do_AUTHHEAD()
39+
self.wfile.write('Credentials required.'.encode('utf-8'))
40+
pass
41+
42+
'''
43+
This function is used to simulate the manipulation of the stack (like pushd and popd in BASH)
44+
and change the folder with the usage of the context manager
45+
'''
46+
@contextmanager
47+
def pushd(new_dir):
48+
previous_dir = os.getcwd()
49+
os.chdir(new_dir)
50+
yield
51+
os.chdir(previous_dir)
52+
53+
54+
if __name__ == '__main__':
55+
56+
key = ''
57+
config_file = '.sphinx-server.yml'
58+
install_folder = '/opt/sphinx-server/'
59+
build_folder = os.path.realpath('_build/html')
60+
source_folder = os.path.realpath('.')
61+
configuration = None
62+
63+
with open(install_folder + config_file, 'r') as config_stream:
64+
configuration = yaml.safe_load(config_stream)
65+
66+
if os.path.isfile(source_folder + '/' + config_file):
67+
with open(source_folder + '/' + config_file, "r") as custom_stream:
68+
configuration.update(yaml.safe_load(custom_stream))
69+
70+
if not os.path.exists(build_folder):
71+
os.makedirs(build_folder)
72+
73+
if configuration.get('autobuild'):
74+
75+
ignored_files = []
76+
for path in configuration.get('ignore'):
77+
ignored_files.append(os.path.realpath(path))
78+
79+
builder = sphinx_autobuild.SphinxBuilder(
80+
outdir=build_folder,
81+
args=['-b', 'html', source_folder, build_folder]+sys.argv[1:],
82+
ignored=ignored_files
83+
)
84+
85+
server = Server(watcher=sphinx_autobuild.LivereloadWatchdogWatcher())
86+
server.watch(source_folder, builder)
87+
server.watch(build_folder)
88+
89+
builder.build()
90+
91+
server.serve(port=8000, host='0.0.0.0', root=build_folder)
92+
else:
93+
# Building once when server starts
94+
builder = sphinx_autobuild.SphinxBuilder(outdir=build_folder, args=['-b', 'html', source_folder, build_folder]+sys.argv[1:])
95+
builder.build()
96+
97+
sys.argv = ['nouser', '8000']
98+
99+
if configuration.get('credentials')['username'] is not None:
100+
auth = configuration.get('credentials')['username'] + ':' + configuration.get('credentials')['password']
101+
key = base64.b64encode(auth.encode('utf-8'))
102+
103+
with pushd(build_folder):
104+
http.server.test(AuthHandler, http.server.HTTPServer)
105+
else:
106+
with pushd(build_folder):
107+
Handler = http.server.SimpleHTTPRequestHandler
108+
httpd = socketserver.TCPServer(('', 8000), Handler)
109+
httpd.serve_forever()

0 commit comments

Comments
 (0)