|
{% extends "base.html" %}
|
|
{% from "_macros.html" import modal %}
|
|
{% block extra_head %}
|
|
<link rel="stylesheet" href="{{ static_url('/static/css/containers.css') }}">
|
|
{% endblock %}
|
|
{% block content %}
|
|
<h1 class="sr-only">Container manager</h1>
|
|
<div class="cm-page" id="container-manager"
|
|
data-slug="{{ project['slug'] or project['uid'] }}"
|
|
data-title="{{ project['title'] }}">
|
|
<div class="cm-header">
|
|
<a href="/projects/{{ project['slug'] or project['uid'] }}" class="back-link">← {{ render_title(project['title']) }}</a>
|
|
<a href="/admin/containers" class="cm-header-link">All containers →</a>
|
|
</div>
|
|
|
|
<div class="cm-body">
|
|
<section class="card cm-col cm-instances">
|
|
<div class="cm-col-head">
|
|
<h2>Instances</h2>
|
|
<button type="button" class="btn btn-primary" data-modal="cm-new-instance-modal">New</button>
|
|
</div>
|
|
<p class="cm-hint">Every instance runs the shared <code>ppy</code> image with this project's files mounted at <code>/app</code>.</p>
|
|
<ul class="cm-list" id="cm-instance-list"></ul>
|
|
</section>
|
|
</div>
|
|
|
|
<script type="application/json" id="cm-data">{{ {"instances": instances} | tojson }}</script>
|
|
</div>
|
|
|
|
{% call modal('cm-new-instance-modal', 'New instance') %}
|
|
<form id="cm-new-instance-form" class="cm-modal-form">
|
|
<div class="auth-field auth-field-gap">
|
|
<label for="cm-inst-new-name">Name</label>
|
|
<input type="text" id="cm-inst-new-name" name="name" required maxlength="64" placeholder="my-service">
|
|
</div>
|
|
<div class="auth-field auth-field-gap">
|
|
<label for="cm-inst-new-boot">Boot command</label>
|
|
<input type="text" id="cm-inst-new-boot" name="boot_command" placeholder="Optional, e.g. python app.py">
|
|
</div>
|
|
<div class="grid-2col">
|
|
<div class="auth-field">
|
|
<label for="cm-inst-new-policy">Restart policy</label>
|
|
<select id="cm-inst-new-policy" name="restart_policy">
|
|
<option value="never">never</option>
|
|
<option value="on-failure">on-failure</option>
|
|
<option value="always">always</option>
|
|
<option value="unless-stopped">unless-stopped</option>
|
|
</select>
|
|
</div>
|
|
<div class="auth-field">
|
|
<label for="cm-inst-new-ports">Ports</label>
|
|
<input type="text" id="cm-inst-new-ports" name="ports" placeholder="8080 or 8080:80">
|
|
</div>
|
|
</div>
|
|
<div class="grid-2col">
|
|
<div class="auth-field">
|
|
<label for="cm-inst-new-ingress">Ingress slug</label>
|
|
<input type="text" id="cm-inst-new-ingress" name="ingress_slug" placeholder="Optional, /p/<slug>">
|
|
</div>
|
|
<div class="auth-field">
|
|
<label for="cm-inst-new-ingress-port">Ingress port</label>
|
|
<input type="number" id="cm-inst-new-ingress-port" name="ingress_port" min="1" placeholder="container port">
|
|
</div>
|
|
</div>
|
|
<div class="auth-field auth-field-gap">
|
|
<label class="topic-label">
|
|
<input type="checkbox" id="cm-inst-new-autostart" name="autostart" value="true" checked> Start immediately
|
|
</label>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="modal-close btn btn-secondary">Cancel</button>
|
|
<button type="submit" class="btn btn-primary">Create</button>
|
|
</div>
|
|
</form>
|
|
{% endcall %}
|
|
{% endblock %}
|
|
{% block extra_js %}
|
|
<script type="module">
|
|
import { ContainerManager } from "{{ static_url('/static/js/ContainerManager.js') }}";
|
|
const root = document.getElementById("container-manager");
|
|
if (root) {
|
|
const manager = new ContainerManager(root);
|
|
manager.init();
|
|
window.app.containers = manager;
|
|
}
|
|
</script>
|
|
{% endblock %}
|