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

Commit

Permalink
added docker based env (#863)
Browse files Browse the repository at this point in the history
Co-Authored-By: Donald Morton <[email protected]>
  • Loading branch information
jalogisch and Donald Morton authored May 5, 2020
1 parent 1c26083 commit dfc2a7b
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 1 deletion.
13 changes: 13 additions & 0 deletions .sphinx-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Set autobuild to false if you do not want to enable compilation when a file changes.
# This will enable http authentication if credentials section is filled.
autobuild: true

# Add files and folders you want autobuild watcher to ignore on changes.
ignore:
- .git

# Add a username and a password if you want to enable http authentication.
# This will not work if autobuild is enabled.
credentials:
username: ~
password: ~
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3-alpine

MAINTAINER Jan Doberstein <[email protected]>

COPY ./requirements.txt requirements.txt

RUN apk add --no-cache --virtual --update py3-pip make wget ca-certificates ttf-dejavu \
&& pip install --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt

COPY ./server.py /opt/sphinx-server/
COPY ./.sphinx-server.yml /opt/sphinx-server/

WORKDIR /web

EXPOSE 8000 35729

CMD ["python", "/opt/sphinx-server/server.py"]
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# The Graylog documentation
[![Build Status](https://travis-ci.org/Graylog2/documentation.svg?branch=2.2)](https://travis-ci.org/Graylog2/documentation)
[![Build Status](https://travis-ci.org/Graylog2/documentation.svg?branch=3.2)](https://travis-ci.org/Graylog2/documentation)

Table of Contents
=================

* [Architecture](#architecture)
* [Build](#building-locally)
* [Mac & Linus](#or-using-pathogen)
* [Windows](#or-using-vundle)
* [Docker](#docker)
* [docker-compose](#docker-compose)
* [Daily usage](#daily-usage)

## Architecture

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

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.

#### Docker

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.


docker build -t graylog/documentation -f Dockerfile .
docker run -it -d --rm -v .:/web -u $(id -u):$(id -g) -p 8000:8000 --name graylog/documentation graylog-documentation

##### docker_run.sh (helper)

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.

If unsure how to operate the docker image - use this script.

##### docker-compose

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.

docker-compose up

To rebuild the image, for example to include the new pip requirements the `build` command is needed.

docker-compose build


### daily usage

Expand Down
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: '3'
services:
graylog-documentation:
build: .
image: graylog/documentation
container_name: graylog-documentation
ports:
- "8000:8000"
volumes:
- .:/web

76 changes: 76 additions & 0 deletions docker_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash

THIS_DIR=$(cd `dirname $0`; pwd -P)
DOCKER_IMAGE_NAME="graylog/documentation"
DOCKER_CONTAINER_NAME="graylog-documentation"

function exit_error {
message="${1}"
echo -e "\n\033[31mERROR: $message\033[0m" >/dev/stderr
exit 1
}

# check if Docker is installed
which docker >/dev/null
if [[ $? != 0 ]] ; then
exit_error "Docker does not seem to be installed (or resides in an unusual path). Please fix that first."
fi

# if the image is running ask to stop
docker ps | grep -qw ${DOCKER_CONTAINER_NAME}
if [[ $? == 0 ]] ; then
read -p "Graylog documentation Docker container running, Stop? (y/n)" -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]] ; then

# stop
docker stop ${DOCKER_CONTAINER_NAME}

if [[ $? == 0 ]] ; then
read -p "remove the Graylog documentation Docker image? (y/n)" -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]] ; then
docker rmi ${DOCKER_IMAGE_NAME}
exit 0
fi
fi

exit 0
fi

echo "no action needed."
echo "connect to the Graylog Docker container"
echo "defaults to http://127.0.0.1:8000"
exit 0
fi

# check if Docker image is present, otherwise build it
docker images | grep -qw ${DOCKER_IMAGE_NAME}
if [[ $? != 0 ]] ; then
echo "Docker image not found, will build it now"
docker build -t ${DOCKER_IMAGE_NAME} -f ${THIS_DIR}/Dockerfile . && echo "Done"
fi

# read additional environment variables from .env, if present
[[ -e ${THIS_DIR}/.env ]] && source ${THIS_DIR}/.env

# check if Docker container is present, otherwise make the first start with all arguments
docker ps -a | grep -qw ${DOCKER_CONTAINER_NAME}
if [[ $? != 0 ]] ; then
echo "Docker starting:"
docker run -it -d --rm -v "${THIS_DIR}":/web -u $(id -u):$(id -g) -p 8000:8000 --name ${DOCKER_CONTAINER_NAME} ${DOCKER_IMAGE_NAME}

echo "Graylog documentation Docker container created,"
echo "defaults to http://127.0.0.1:8000"
exit 0
fi

# now the normal start should be possible, but we will check
docker images | grep -qw ${DOCKER_CONTAINER_NAME}
if [[ $? == 0 ]] ; then
echo "Starting the Docker container, will be serving on http://127.0.0.1:8000 by default"
docker start graylog-documentation
exit 0
fi

exit_error "we should never reach this point!"
109 changes: 109 additions & 0 deletions server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import sphinx_autobuild
import os
import sys
from contextlib import contextmanager
import base64
from livereload import Server
import http.server
import http.server
import socketserver
import yaml


class AuthHandler(http.server.SimpleHTTPRequestHandler):
"""
Authentication handler used to support HTTP authentication
"""
def do_HEAD(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()

def do_AUTHHEAD(self):
self.send_response(401)
self.send_header('WWW-Authenticate', 'Basic realm=\"Restricted area\"')
self.send_header('Content-type', 'text/html')
self.end_headers()

def do_GET(self):
global key
if self.headers.get('Authorization') is None:
self.do_AUTHHEAD()
self.wfile.write('Credentials required.'.encode('utf-8'))
pass
elif self.headers.get('Authorization') == 'Basic ' + key.decode('utf-8'):
http.server.SimpleHTTPRequestHandler.do_GET(self)
pass
else:
self.do_AUTHHEAD()
self.wfile.write('Credentials required.'.encode('utf-8'))
pass

'''
This function is used to simulate the manipulation of the stack (like pushd and popd in BASH)
and change the folder with the usage of the context manager
'''
@contextmanager
def pushd(new_dir):
previous_dir = os.getcwd()
os.chdir(new_dir)
yield
os.chdir(previous_dir)


if __name__ == '__main__':

key = ''
config_file = '.sphinx-server.yml'
install_folder = '/opt/sphinx-server/'
build_folder = os.path.realpath('_build/html')
source_folder = os.path.realpath('.')
configuration = None

with open(install_folder + config_file, 'r') as config_stream:
configuration = yaml.safe_load(config_stream)

if os.path.isfile(source_folder + '/' + config_file):
with open(source_folder + '/' + config_file, "r") as custom_stream:
configuration.update(yaml.safe_load(custom_stream))

if not os.path.exists(build_folder):
os.makedirs(build_folder)

if configuration.get('autobuild'):

ignored_files = []
for path in configuration.get('ignore'):
ignored_files.append(os.path.realpath(path))

builder = sphinx_autobuild.SphinxBuilder(
outdir=build_folder,
args=['-b', 'html', source_folder, build_folder]+sys.argv[1:],
ignored=ignored_files
)

server = Server(watcher=sphinx_autobuild.LivereloadWatchdogWatcher())
server.watch(source_folder, builder)
server.watch(build_folder)

builder.build()

server.serve(port=8000, host='0.0.0.0', root=build_folder)
else:
# Building once when server starts
builder = sphinx_autobuild.SphinxBuilder(outdir=build_folder, args=['-b', 'html', source_folder, build_folder]+sys.argv[1:])
builder.build()

sys.argv = ['nouser', '8000']

if configuration.get('credentials')['username'] is not None:
auth = configuration.get('credentials')['username'] + ':' + configuration.get('credentials')['password']
key = base64.b64encode(auth.encode('utf-8'))

with pushd(build_folder):
http.server.test(AuthHandler, http.server.HTTPServer)
else:
with pushd(build_folder):
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(('', 8000), Handler)
httpd.serve_forever()

0 comments on commit dfc2a7b

Please sign in to comment.