A feature to allow a pelican site to be deployed inside of a container.

- A new fabric target is introduced 'docker-rebuild'. This will rebuild a
  production version of the users site and deploy this by copying the
  pelican/output directory into the container image.

- The fabric target takes care of container management, cleaning up previous containers
  and instantiating new ones whenever the 'fab docker rebuild' command is issued.

- Unlike other solutions where pelican runs inside the container, this solution
  decouples pelican from the deployment of the blog, it's more in keeping with
  the existing fabric build targets e.g. cf_upload.

- The default container based web server is nginx, this can be changed when
  running the pelican_quickstart

- The docker-rebuild target is only created if the user requests container
  deployment during the quickstart process.

- The docker-rebuild target works transparently with docker-machine if
  desired, to allow for very fast rebuild and update of pelican sites running
  within remote containers.

- Docker must be preinstalled on the host machine for this to work
This commit is contained in:
Robert Rennison 2016-06-01 09:37:16 -04:00
commit 7d07e228bf
3 changed files with 67 additions and 1 deletions

View file

@ -43,7 +43,10 @@ CONF = {
'default_pagination': 10,
'siteurl': '',
'lang': 'en',
'timezone': 'Europe/Paris'
'timezone': 'Europe/Paris',
'docker_base_image': 'nginx',
'docker_target_dir': '/usr/share/nginx/html',
'docker_container_name': 'pelican_site_container'
}
# url for list of valid timezones
@ -310,6 +313,22 @@ needed by Pelican.
CONF['github_pages_branch'] = \
_GITHUB_PAGES_BRANCHES['project']
docker = ask('Do you want to run your website using '
'a Docker container?', answer=bool, default=False)
if docker:
CONF['docker_container_name'] = ask('What would you like to name '
'your container?', str_compat,
CONF['docker_container_name'])
CONF['docker_base_image'] = ask('What webserver image would you '
'like to base your container '
'on?', str_compat,
CONF['docker_base_image'])
CONF['docker_target_dir'] = ask('Where do you want to put your '
'web site on that server?',
str_compat,
CONF['docker_target_dir'])
try:
os.makedirs(os.path.join(CONF['basedir'], 'content'))
except OSError as e:
@ -397,6 +416,20 @@ needed by Pelican.
except OSError as e:
print('Error: {0}'.format(e))
if docker:
try:
with codecs.open(os.path.join(CONF['basedir'], 'Dockerfile'),
'w', 'utf-8') as fd:
conf_docker = dict()
for key, value in CONF.items():
conf_docker[key] = repr(value)
for line in get_template('Dockerfile'):
template = string.Template(line)
fd.write(template.safe_substitute(conf_docker))
fd.close()
except OSError as e:
print('Error: {0}'.format(e))
print('Done. Your new project is available at %s' % CONF['basedir'])
if __name__ == "__main__":

View file

@ -0,0 +1,2 @@
FROM nginx
COPY output /usr/share/nginx/html

View file

@ -23,6 +23,11 @@ env.cloudfiles_container = '$cloudfiles_container'
# Github Pages configuration
env.github_pages_branch = "$github_pages_branch"
# Docker configuration
env.docker_blog_image = '$docker_base_image-blog'
env.docker_target_dir = '$docker_target_dir'
env.docker_container_name = '$docker_container_name'
# Port for `serve`
PORT = 8000
@ -91,3 +96,29 @@ def gh_pages():
"""Publish to GitHub Pages"""
rebuild()
local("ghp-import -b {github_pages_branch} {deploy_path} -p".format(**env))
def docker_rebuild():
"""Rebuild the pelican site for production and install in a docker image :
- Kill and remove any existing pelican_site container.
- Copy the site into the webserver base image, build a new pelican_site
container.
- Run our new container.
"""
clean()
preview() # Builds the production version of the site
if local("docker ps -a | grep %s; exit 0" %
env.docker_container_name, capture=True) != "":
local("docker rm -f {docker_container_name}".format(**env))
# Remove the existing blog docker image
if local("docker images | grep %s; exit 0" %
env.docker_blog_image, capture=True) != "" :
local("docker rmi {docker_blog_image}".format(**env))
# Now build and run the new image
local("docker build -t {docker_blog_image} .".format(**env))
local("docker run -d -p 80:80 --name {docker_container_name} \
{docker_blog_image} ".format(**env))