Enable gh-pages style static site deployment. (#97)

* Enable gh-pages style static site deployment.

As per #42 this PR allows the user to do static site deployments using
Piku which work very similarly to gh-pages. In the Procfile the user
defines a worker called 'static' with the path to the root of the files
to be served. An example app can be found here:
https://github.com/chr15m/piku-static-site

* Documentation.
pull/98/head^2
Chris McCormick 2019-08-30 18:07:55 +08:00 zatwierdzone przez Rui Carmo
rodzic 89413a6f81
commit c00e130b87
3 zmienionych plików z 35 dodań i 11 usunięć

Wyświetl plik

@ -22,6 +22,7 @@ The tiniest Heroku/CloudFoundry-like PaaS you've ever seen.
* You can optionally also specify a `release` worker which is run once when the app is deployed.
* You can then remotely change application settings (`config:set`) or scale up/down worker processes (`ps:scale`).
* You can also bake application settings into a file called [`ENV` which is documented here](./docs/ENV.md).
* A `static` worker type, with the root path as the argument, can be used to deploy a gh-pages style static site.
## Install

Wyświetl plik

@ -20,7 +20,8 @@ An app is simply a `git` repository with some additional files on the top level,
* `wsgi` workers, in the format `dotted.module:entry_point` (Python-only)
* `web` workers, which can be anything that honors the `PORT` environment variable
* `worker` prcesses, which are standalone workers and can have arbitrary names
* `static` workers, which simply mount the first argument as the root static path
* `worker` processes, which are standalone workers and can have arbitrary names
So a Python application could have a `Procfile` like such:

42
piku.py
Wyświetl plik

@ -123,6 +123,10 @@ NGINX_COMMON_FRAGMENT = """
$INTERNAL_NGINX_BLOCK_GIT
$INTERNAL_NGINX_PORTMAP
"""
NGINX_PORTMAP_FRAGMENT = """
location / {
$INTERNAL_NGINX_UWSGI_SETTINGS
proxy_http_version 1.1;
@ -134,7 +138,7 @@ NGINX_COMMON_FRAGMENT = """
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
$NGINX_ACL
}
}
"""
NGINX_ACME_FIRSTRUN_TEMPLATE = """
@ -338,6 +342,9 @@ def do_deploy(app, deltas={}, newrev=None):
elif (exists(join(app_path, 'Godeps')) or len(glob(join(app_path,'*.go')))) and check_requirements(['go']):
echo("-----> Go app detected.", fg='green')
settings.update(deploy_go(app, deltas))
elif 'static' in workers:
echo("-----> Static app detected.", fg='green')
settings.update(deploy_identity(app, deltas))
else:
echo("-----> Could not detect runtime!", fg='red')
# TODO: detect other runtimes
@ -532,6 +539,11 @@ def deploy_python(app, deltas={}):
call('pip install -r {}'.format(requirements), cwd=virtualenv_path, shell=True)
return spawn_app(app, deltas)
def deploy_identity(app, deltas={}):
env_path = join(ENV_ROOT, app)
if not exists(env_path):
makedirs(env_path)
return spawn_app(app, deltas)
def spawn_app(app, deltas={}):
"""Create all workers for an app"""
@ -586,7 +598,7 @@ def spawn_app(app, deltas={}):
if exists(settings):
env.update(parse_settings(settings, env))
if 'web' in workers or 'wsgi' in workers or 'jwsgi' in workers:
if 'web' in workers or 'wsgi' in workers or 'jwsgi' in workers or 'static' in workers:
# Pick a port if none defined
if 'PORT' not in env:
env['PORT'] = str(get_free_port())
@ -678,9 +690,13 @@ def spawn_app(app, deltas={}):
env['INTERNAL_NGINX_BLOCK_GIT'] = "" if env.get('NGINX_ALLOW_GIT_FOLDERS') else "location ~ /\.git { deny all; }"
env['INTERNAL_NGINX_STATIC_MAPPINGS'] = ''
# Get a mapping of /url:path1,/url2:path2
static_paths = env.get('NGINX_STATIC_PATHS','')
# prepend static worker path if present
if 'static' in workers:
stripped = workers['static'].strip("/").rstrip("/")
static_paths = "/:" + (stripped if stripped else ".") + "/" + ("," if static_paths else "") + static_paths
if len(static_paths):
try:
items = static_paths.split(',')
@ -694,6 +710,9 @@ def spawn_app(app, deltas={}):
env['INTERNAL_NGINX_STATIC_MAPPINGS'] = ''
env['INTERNAL_NGINX_CUSTOM_CLAUSES'] = expandvars(open(join(app_path, env["NGINX_INCLUDE_FILE"])).read(), env) if env.get("NGINX_INCLUDE_FILE") else ""
env['INTERNAL_NGINX_PORTMAP'] = ""
if 'web' in workers or 'uwsgi' in workers or 'jwsgi' in workers:
env['INTERNAL_NGINX_PORTMAP'] = expandvars(NGINX_PORTMAP_FRAGMENT, env)
env['INTERNAL_NGINX_COMMON'] = expandvars(NGINX_COMMON_FRAGMENT, env)
echo("-----> nginx will map app '{}' to hostname '{}'".format(app, env['NGINX_SERVER_NAME']))
@ -847,10 +866,12 @@ def spawn_worker(app, kind, command, env, ordinal=1):
elif kind == 'web':
echo("-----> nginx will talk to the 'web' process via {BIND_ADDRESS:s}:{PORT:s}".format(**env), fg='yellow')
settings.append(('attach-daemon', command))
elif kind == 'static':
echo("-----> nginx serving static files only".format(**env), fg='yellow')
else:
settings.append(('attach-daemon', command))
if kind in ['wsgi','web']:
if kind in ['wsgi', 'web']:
settings.append(('log-format','%%(addr) - %%(user) [%%(ltime)] "%%(method) %%(uri) %%(proto)" %%(status) %%(size) "%%(referer)" "%%(uagent)" %%(msecs)ms'))
# remove unnecessary variables from the env in nginx.ini
@ -864,12 +885,13 @@ def spawn_worker(app, kind, command, env, ordinal=1):
for k, v in env.items():
settings.append(('env', '{k:s}={v}'.format(**locals())))
with open(available, 'w') as h:
h.write('[uwsgi]\n')
for k, v in settings:
h.write("{k:s} = {v}\n".format(**locals()))
copyfile(available, enabled)
if kind != 'static':
with open(available, 'w') as h:
h.write('[uwsgi]\n')
for k, v in settings:
h.write("{k:s} = {v}\n".format(**locals()))
copyfile(available, enabled)
def do_restart(app):
config = glob(join(UWSGI_ENABLED, '{}*.ini'.format(app)))