First version
This commit is contained in:
commit
e3e32d4046
|
@ -0,0 +1,25 @@
|
|||
FROM python:3-alpine
|
||||
|
||||
RUN apk --update add git nginx && \
|
||||
rm /var/cache/apk/*
|
||||
|
||||
RUN pip install requests --no-cache-dir
|
||||
|
||||
RUN mkdir /hook
|
||||
RUN mkdir -p /var/www/html
|
||||
|
||||
# Configure nginx
|
||||
RUN mkdir /run/nginx
|
||||
RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
|
||||
COPY nginx.conf /etc/nginx/conf.d/mkdocs-server.conf
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
|
||||
COPY ./entrypoint.sh /hook
|
||||
COPY ./docker-hook /hook
|
||||
COPY ./update.sh /hook
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
ENTRYPOINT ["/hook/entrypoint.sh"]
|
||||
|
||||
EXPOSE 80
|
|
@ -0,0 +1,66 @@
|
|||
# Serveur Nginx statique auto-mis à jour via Git
|
||||
|
||||
Cette image Docker permet la mise en place d'un serveur Nginx dont les sources sont un
|
||||
site statique.
|
||||
|
||||
Cependant, cette image offre l'avantage de mettre à jour automatiquement le site dès lors
|
||||
que la branche `master` du dépôt Git est modifiée.
|
||||
|
||||
## Configuration
|
||||
|
||||
On désignera par `www.exemple.com` le site sur lequel vous souhaitez héberger votre site.
|
||||
Sur votre dépôt Git, ajoutez un nouveau webhook déclenché à chaque événement `push`
|
||||
(cela suffit normalement) vers l'adresse `https://www.exemple.com/trigger-ci.json`.
|
||||
|
||||
Il vous suffit ensuite de lancer l'image Docker en renseignant la variable d'environnement
|
||||
`MKDOCS_SERVER_GIT_URL` par l'adresse de clonage **HTTPS** du dépôt Git. Par exemple, pour
|
||||
ce dépôt, il s'agit de l'adresse `https://gitlab.com/animath/si/mkdocs-server-from-git.git`.
|
||||
|
||||
Un exemple :
|
||||
|
||||
```bash
|
||||
docker run -e NGINX_SERVER_GIT_URL=https://gitlab.com/me/mon-super-projet-nginx.git -p 8000:80 ynerant/nginx-server-from-git
|
||||
```
|
||||
|
||||
Le résultat s'observe sur `http://localhost:8000`.
|
||||
|
||||
Il est recommandé d'utiliser `docker-compose` :
|
||||
|
||||
```yaml
|
||||
nginx-static-server:
|
||||
image: ynerant/nginx-server-from-git
|
||||
ports:
|
||||
- 8000:80
|
||||
environment:
|
||||
- NGINX_SERVER_GIT_URL=https://gitlab.com/me/mon-super-projet.git
|
||||
```
|
||||
|
||||
Si vous utilisez Traefik comme reverse-proxy :
|
||||
|
||||
```yaml
|
||||
nginx-static-server:
|
||||
image: ynerant/nginx-server-from-git
|
||||
restart: always
|
||||
environment:
|
||||
- NGINX_SERVER_GIT_URL=https://gitlab.com/me/mon-super-projet.git
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.nginx-static-server.rule=Host(`www.exemple.com`)"
|
||||
- "traefik.http.routers.nginx-static-server.entrypoints=websecure"
|
||||
- "traefik.http.routers.nginx-static-server.tls.certresolver=mytlschallenge"
|
||||
```
|
||||
|
||||
À vous bien sûr d'adapter la configuration comme bon vous semble.
|
||||
|
||||
Enjoy :)
|
||||
|
||||
## Fonctionnement
|
||||
|
||||
L'image contient un serveur Nginx avec deux entrées : un serveur classique desservant
|
||||
le dossier `/var/www/html` et une entrée écoutant sur `/trigger-ci.json` écrite en Python
|
||||
afin de récupérer l'événement de `push` envoyé par le serveur Git.
|
||||
|
||||
À chaque push, le script `update.sh` est exécuté, visant simplement à effectuer un
|
||||
`git pull` afin de mettre à jour les fichiers.
|
||||
|
||||
Le dossier `.git` n'est pas desservi pour des raisons de sécurité.
|
|
@ -0,0 +1,104 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Automatic Docker Deployment via Webhooks."""
|
||||
|
||||
import json
|
||||
import os
|
||||
from subprocess import Popen
|
||||
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
||||
from http.server import HTTPServer
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
import sys
|
||||
import logging
|
||||
import requests
|
||||
|
||||
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
|
||||
level=logging.DEBUG,
|
||||
stream=sys.stdout)
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
"""A POST request handler which expects a token in its path."""
|
||||
|
||||
def do_POST(self):
|
||||
try:
|
||||
logging.info("Path: %s", self.path)
|
||||
header_length = int(self.headers.get('content-length', "0"))
|
||||
json_payload = self.rfile.read(header_length)
|
||||
env = dict(os.environ)
|
||||
json_params = {}
|
||||
if len(json_payload) > 0:
|
||||
json_params = json.loads(json_payload)
|
||||
env.update(('REPOSITORY_' + var.upper(), str(val))
|
||||
for var, val in json_params['repository'].items())
|
||||
|
||||
logging.info("Start executing '%s'" % args.cmd)
|
||||
try:
|
||||
Popen(args.cmd, env=env).wait()
|
||||
self.send_response(200, "OK")
|
||||
if 'callback_url' in json_params:
|
||||
# Make a callback to Docker Hub
|
||||
data = {'state': 'success'}
|
||||
headers = {'Content-type': 'application/json',
|
||||
'Accept': 'text/plain'}
|
||||
requests.post(json_params['callback_url'],
|
||||
data=json.dumps(data),
|
||||
headers=headers)
|
||||
except OSError as err:
|
||||
self.send_response(500, "OSError")
|
||||
logging.error("You probably didn't use 'sh ./script.sh'.")
|
||||
logging.error(err)
|
||||
if 'callback_url' in json_params:
|
||||
# Make a callback to Docker Hub
|
||||
data = {'state': 'failure',
|
||||
'description': str(err)}
|
||||
headers = {'Content-type': 'application/json',
|
||||
'Accept': 'text/plain'}
|
||||
requests.post(json_params['callback_url'],
|
||||
data=json.dumps(data),
|
||||
headers=headers)
|
||||
self.end_headers()
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
|
||||
|
||||
def get_parser():
|
||||
"""Get a command line parser for docker-hook."""
|
||||
parser = ArgumentParser(description=__doc__,
|
||||
formatter_class=ArgumentDefaultsHelpFormatter)
|
||||
|
||||
parser.add_argument("-t", "--token",
|
||||
dest="token",
|
||||
required=False,
|
||||
help=("Secure auth token (can be choosen "
|
||||
"arbitrarily)"))
|
||||
parser.add_argument("-c", "--cmd",
|
||||
dest="cmd",
|
||||
required=True,
|
||||
nargs="*",
|
||||
help="Command to execute when triggered")
|
||||
parser.add_argument("--addr",
|
||||
dest="addr",
|
||||
default="0.0.0.0",
|
||||
help="address where it listens")
|
||||
parser.add_argument("--port",
|
||||
dest="port",
|
||||
type=int,
|
||||
default=8555,
|
||||
metavar="PORT",
|
||||
help="port where it listens")
|
||||
return parser
|
||||
|
||||
|
||||
def main(addr, port):
|
||||
"""Start a HTTPServer which waits for requests."""
|
||||
httpd = HTTPServer((addr, port), RequestHandler)
|
||||
httpd.serve_forever()
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = get_parser()
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
args = parser.parse_args()
|
||||
main(args.addr, args.port)
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd /var/www/html
|
||||
[ -d .git ] || git clone ${NGINX_SERVER_GIT_URL} .
|
||||
|
||||
git pull
|
||||
nginx&
|
||||
python /hook/docker-hook -c sh /hook/update.sh
|
|
@ -0,0 +1,25 @@
|
|||
upstream trigger-ci {
|
||||
server 127.0.0.1:8555;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name static-server;
|
||||
root /var/www/html;
|
||||
error_page 404 /404.html;
|
||||
|
||||
location /trigger-ci.json {
|
||||
proxy_pass http://trigger-ci;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location /.git* {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location /README* {
|
||||
return 404;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue