Adds syntax highlighting to docker-compose files
This commit is contained in:
34
package-lock.json
generated
34
package-lock.json
generated
@@ -15,6 +15,7 @@
|
|||||||
"snarkdown": "^2.0.0",
|
"snarkdown": "^2.0.0",
|
||||||
"svelte": "^3.54.0",
|
"svelte": "^3.54.0",
|
||||||
"svelte-check": "^3.0.1",
|
"svelte-check": "^3.0.1",
|
||||||
|
"svelte-highlight": "^7.2.1",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^4.2.0"
|
"vite": "^4.2.0"
|
||||||
@@ -864,6 +865,15 @@
|
|||||||
"node": ">= 0.4.0"
|
"node": ">= 0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/highlight.js": {
|
||||||
|
"version": "11.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
|
||||||
|
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/immutable": {
|
"node_modules/immutable": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||||
@@ -1482,6 +1492,15 @@
|
|||||||
"svelte": "^3.55.0"
|
"svelte": "^3.55.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svelte-highlight": {
|
||||||
|
"version": "7.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-highlight/-/svelte-highlight-7.2.1.tgz",
|
||||||
|
"integrity": "sha512-Qyxd4CFbvufKo661AmtIFLFh7bW8BZ6G5vUGYdRlyhaoWEOCyCgKimdKW8/8aJ4/kKidSFbgY/2/fyzwYDEjWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"highlight.js": "11.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/svelte-hmr": {
|
"node_modules/svelte-hmr": {
|
||||||
"version": "0.15.1",
|
"version": "0.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
||||||
@@ -2238,6 +2257,12 @@
|
|||||||
"function-bind": "^1.1.1"
|
"function-bind": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"highlight.js": {
|
||||||
|
"version": "11.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
|
||||||
|
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"immutable": {
|
"immutable": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||||
@@ -2655,6 +2680,15 @@
|
|||||||
"typescript": "^5.0.3"
|
"typescript": "^5.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"svelte-highlight": {
|
||||||
|
"version": "7.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-highlight/-/svelte-highlight-7.2.1.tgz",
|
||||||
|
"integrity": "sha512-Qyxd4CFbvufKo661AmtIFLFh7bW8BZ6G5vUGYdRlyhaoWEOCyCgKimdKW8/8aJ4/kKidSFbgY/2/fyzwYDEjWg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"highlight.js": "11.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"svelte-hmr": {
|
"svelte-hmr": {
|
||||||
"version": "0.15.1",
|
"version": "0.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"snarkdown": "^2.0.0",
|
"snarkdown": "^2.0.0",
|
||||||
"svelte": "^3.54.0",
|
"svelte": "^3.54.0",
|
||||||
"svelte-check": "^3.0.1",
|
"svelte-check": "^3.0.1",
|
||||||
|
"svelte-highlight": "^7.2.1",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^4.2.0"
|
"vite": "^4.2.0"
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import Highlight from "svelte-highlight";
|
||||||
|
import yamlHighlight from "svelte-highlight/languages/yaml";
|
||||||
|
import shellHighlight from "svelte-highlight/languages/shell";
|
||||||
|
import codeHighlighting from "svelte-highlight/styles/dracula";
|
||||||
|
|
||||||
|
import {
|
||||||
|
generateDockerRunCommand,
|
||||||
|
generateDockerRunCommands,
|
||||||
|
convertToDockerCompose,
|
||||||
|
convertPortainerStackToDockerCompose,
|
||||||
|
} from '$src/utils/template-to-docker-parser';
|
||||||
import { templatesUrl, gitHubRepo } from '$src/constants';
|
import { templatesUrl, gitHubRepo } from '$src/constants';
|
||||||
import type { Template, Volume, Service } from '$src/Types';
|
import type { Template, Volume, Service, DockerCompose } from '$src/Types';
|
||||||
|
|
||||||
export let portainerTemplate: Template | null = null;
|
export let portainerTemplate: Template | null = null;
|
||||||
export let portainerServices: Service[] | null = null;
|
export let portainerServices: Service[] | null = null;
|
||||||
@@ -10,66 +20,20 @@
|
|||||||
navigator.clipboard.writeText(content);
|
navigator.clipboard.writeText(content);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateDockerRunCommand = (template: Template) => {
|
const dockerRunCommand = portainerTemplate?.image ?
|
||||||
let command = `docker run -d \\ \n`;
|
generateDockerRunCommand(portainerTemplate) : null;
|
||||||
if (template.ports) {
|
const dockerRunCommands = portainerServices && !dockerRunCommand ?
|
||||||
template.ports.forEach((port) => {
|
generateDockerRunCommands(portainerServices) : null;
|
||||||
command += ` -p ${port} \\\n`;
|
const dockerComposeFile = portainerTemplate?.image ?
|
||||||
});
|
convertToDockerCompose(portainerTemplate) :
|
||||||
}
|
(portainerServices ? convertPortainerStackToDockerCompose(portainerServices) : null);
|
||||||
if (template.env) {
|
|
||||||
template.env.forEach((env) => {
|
|
||||||
command += ` -e ${env.name}=\${${env.name}} \\\n`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (template.volumes) {
|
|
||||||
template.volumes.forEach((volume: Volume) => {
|
|
||||||
const readOnly = volume.readonly ? ":ro" : "";
|
|
||||||
command += ` -v ${volume.bind}:${volume.container}${readOnly} \\\n`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (template.restart_policy) {
|
|
||||||
command += ` --restart=${template.restart_policy} \\\n`;
|
|
||||||
}
|
|
||||||
command += ` ${template.image}`;
|
|
||||||
return command;
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateDockerRunCommands = (stack: Service[]) => {
|
|
||||||
const commands = stack.map((service) => {
|
|
||||||
let cmd = `docker run --name ${service.name} -d \\\n`;
|
|
||||||
if (service.command) {
|
|
||||||
cmd += ` ${service.command} \\\n`;
|
|
||||||
}
|
|
||||||
if (service.env) {
|
|
||||||
service.env.forEach((envVar) => {
|
|
||||||
cmd += ` -e "${envVar.value}" \\\n`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (service.ports) {
|
|
||||||
service.ports.forEach((port) => {
|
|
||||||
cmd += ` -p ${port} \\\n`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (service.volumes) {
|
|
||||||
service.volumes.forEach((volume) => {
|
|
||||||
cmd += ` -v ${volume.bind}:${volume.container} \\\n`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (service.restart_policy) {
|
|
||||||
cmd += ` --restart=${service.restart_policy} \\\n`;
|
|
||||||
}
|
|
||||||
cmd += ` ${service.image}`;
|
|
||||||
return cmd;
|
|
||||||
});
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dockerRunCommand = portainerTemplate?.image ? generateDockerRunCommand(portainerTemplate) : null;
|
|
||||||
const dockerRunCommands = portainerServices && !dockerRunCommand ? generateDockerRunCommands(portainerServices) : null;
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
{@html codeHighlighting}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>Installation</h2>
|
<h2>Installation</h2>
|
||||||
|
|
||||||
@@ -87,7 +51,7 @@
|
|||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h4>Template Import URL</h4>
|
<h4>Template Import URL</h4>
|
||||||
<pre>{templatesUrl}</pre>
|
<pre class="template-url">{templatesUrl}</pre>
|
||||||
<button on:click={() => copyToClipboard(templatesUrl)}>Copy</button>
|
<button on:click={() => copyToClipboard(templatesUrl)}>Copy</button>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -100,22 +64,34 @@
|
|||||||
<h3>Via Docker Run</h3>
|
<h3>Via Docker Run</h3>
|
||||||
<div class="docker-run-command">
|
<div class="docker-run-command">
|
||||||
<button class="docker-command-copy" on:click={() => copyToClipboard(dockerRunCommand)}>Copy</button>
|
<button class="docker-command-copy" on:click={() => copyToClipboard(dockerRunCommand)}>Copy</button>
|
||||||
<pre>{dockerRunCommand}</pre>
|
<Highlight language={shellHighlight} code={dockerRunCommand} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if dockerRunCommands}
|
{#if dockerRunCommands}
|
||||||
<hr />
|
<hr />
|
||||||
<h3>Via Docker Run</h3>
|
<h3>Via Docker Run</h3>
|
||||||
|
|
||||||
{#each dockerRunCommands as command, index}
|
{#each dockerRunCommands as command, index}
|
||||||
<h4>Service #{index + 1} - {portainerServices[index].name}</h4>
|
<h4>Service #{index + 1} - {portainerServices[index].name}</h4>
|
||||||
<div class="docker-run-command">
|
<div class="docker-run-command">
|
||||||
<button class="docker-command-copy" on:click={() => copyToClipboard(command)}>Copy</button>
|
<button class="docker-command-copy" on:click={() => copyToClipboard(command)}>Copy</button>
|
||||||
<pre>{command}</pre>
|
<Highlight language={shellHighlight} code={command} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if dockerComposeFile}
|
||||||
|
<hr />
|
||||||
|
<h3>Via Docker Compose</h3>
|
||||||
|
<p class="instructions">
|
||||||
|
Save this file as <code>docker-compose.yml</code> and run <code>docker-compose up -d</code>
|
||||||
|
<br>
|
||||||
|
Use this only as a guide.
|
||||||
|
</p>
|
||||||
|
<div class="docker-compose-file">
|
||||||
|
<button class="docker-command-copy" on:click={() => copyToClipboard(JSON.stringify(dockerComposeFile, null, 2))}>Copy</button>
|
||||||
|
<Highlight language={yamlHighlight} code={dockerComposeFile} />
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -178,6 +154,9 @@
|
|||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
display: inline;
|
display: inline;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
&.template-url {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
@@ -212,7 +191,7 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
max-width: 50rem;
|
max-width: 50rem;
|
||||||
}
|
}
|
||||||
.docker-run-command {
|
.docker-run-command, .docker-compose-file {
|
||||||
background: var(--card-2);
|
background: var(--card-2);
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
@@ -225,5 +204,19 @@
|
|||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.instructions {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
code {
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0 0.25rem;
|
||||||
|
background: var(--card-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:global(.hljs) {
|
||||||
|
background: var(--card-2);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user