diff --git a/.dockerignore b/.dockerignore index fb38043ca..7cab72b98 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,6 +7,8 @@ build docs tests !build/package/* +!docs/_build/entrypoint +!docs/_build/requirements.txt !tests/dhparam.pem !contrib/bash-completion !contrib/docker diff --git a/Makefile b/Makefile index cd792b016..e4da07db5 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ include common.mk .PHONY: all apt-update install version copyfiles copyplugin man-db plugins dependencies docker-image-labeler lambda-builder netrc sshcommand procfile-util plugn docker aufs stack count vagrant-acl-add vagrant-dokku go-build +include docs.mk include tests.mk include package.mk include deb.mk diff --git a/contrib/build-docs b/contrib/build-docs new file mode 100755 index 000000000..8bbbfc7f5 --- /dev/null +++ b/contrib/build-docs @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -eo pipefail + +readonly ROOT_DIR="$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")" && pwd)" + +main() { + pushd "$ROOT_DIR" >/dev/null || return 1 + rm -rf docs-main tmp/docs-source tmp/docs-build/docs # tmp/docs-build + mkdir -p tmp/docs-build + cp -r docs docs-main + + echo "====> Processing version: latest" + git clone -q https://github.com/dokku/dokku.git tmp/docs-source + + rm -rf docs/assets + mkdir -p docs/assets + cp -r docs-main/assets/extra.css docs/assets/extra.css + cp -r docs-main/assets/favicons docs/assets/favicons + cp -r docs-main/assets/dokku-logo.svg docs/assets/dokku-logo.svg + + rm -rf tmp/docs-build/assets + cp -r docs-main/assets tmp/docs-build/assets + cp docs-main/_build/app-nginx.conf.sigil tmp/docs-build/app-nginx.conf.sigil + mkdir -p tmp/docs-build/nginx.conf.d + touch tmp/docs-build/.static + echo "[]" >tmp/docs-build/versions.json + + sed -i.bak "s/outdated/outdated_hidden/g" docs/_overrides/main.html && rm docs/_overrides/main.html.bak + echo "----> Generating docs" + make docs-build + rm -rf site/_build + mv site tmp/docs-build/docs + mv docs/home.html tmp/docs-build/index.html + sed -i.bak "s/{{NAME}}~{{REF}}/docs/g" tmp/docs-build/index.html && rm tmp/docs-build/index.html.bak + sed -i.bak "s/{{NAME}}/docs/g" tmp/docs-build/index.html && rm tmp/docs-build/index.html.bak + sed -i.bak 's/="\/docs\/"/="\/"/g' tmp/docs-build/index.html && rm tmp/docs-build/index.html.bak + + jq -C -r '.["max-versions"][]' docs-main/assets/versions.json | while read -r current_version; do + major="$(echo "$current_version" | cut -d'.' -f1)" + minor="$(echo "$current_version" | cut -d'.' -f2)" + patch="$(echo "$current_version" | cut -d'.' -f3)" + while true; do + if [[ "$patch" -lt 0 ]]; then + break + fi + version="${major}.${minor}.${patch}" + echo "====> Processing version: ${major}.${minor}.${patch}" + + if [[ "$major" -lt 1 ]]; then + if [[ "$current_version" != "$version" ]]; then + echo " Writing rewrite rule" + echo "rewrite ^/docs~v$version/(.*)$ /docs~v$current_version/\$1 redirect;" >"tmp/docs-build/nginx.conf.d/$version.conf" + echo " Removing old docs" + rm -rf "tmp/docs-build/docs~v${version}" + patch=$((patch - 1)) + continue + fi + fi + + jq --arg title "v$version" --arg version "docs~v$version" '. += [{"title": $title, "version": $version, "aliases": []}]' tmp/docs-build/versions.json >tmp/docs-build/versions.json.bak + mv tmp/docs-build/versions.json.bak tmp/docs-build/versions.json + if [[ -d "tmp/docs-build/docs~v${version}" ]]; then + echo " ! Docs exist, skipping regeneration" + rm -rf "tmp/docs-build/docs~v${version}/assets/favicons" + cp -r docs-main/assets/favicons "tmp/docs-build/docs~v${version}/assets/favicons" + cp -r docs-main/assets/dokku-logo.svg "tmp/docs-build/docs~v${version}/assets/dokku-logo.svg" + cp -r docs-main/assets/extra.css "tmp/docs-build/docs~v${version}/assets/extra.css" + patch=$((patch - 1)) + continue + fi + + git -C tmp/docs-source checkout -q -- . + git -C tmp/docs-source checkout -q "tags/v${version}" -b "v${version}-branch" + rm -rf docs + mv tmp/docs-source/docs docs + + rm -rf docs/assets + mkdir -p docs/assets + cp -r docs-main/assets/favicons docs/assets/favicons + cp -r docs-main/assets/dokku-logo.svg docs/assets/dokku-logo.svg + cp -r docs-main/assets/extra.css docs/assets/extra.css + + cp -r docs-main/_build docs/_build + cp -r docs-main/_overrides docs/_overrides + git checkout -q -- mkdocs.yml + sed -i.bak "s/site_dir: site/site_dir: docs~v$version/g" mkdocs.yml && rm mkdocs.yml.bak + if [[ ! -f docs/template.html ]]; then + if [[ "$patch" -eq 0 ]]; then + break + fi + + continue + fi + + echo "----> Generating docs" + if ! make docs-build; then + continue + fi + + if [[ -d "docs~v${version}" ]]; then + rm -rf "docs~v${version}/_build" + mv "docs~v${version}" "tmp/docs-build/docs~v${version}" + fi + + if [[ "$patch" -eq 0 ]]; then + break + fi + patch=$((patch - 1)) + done + done + + python contrib/sort-mkdocs-versions + rm -rf docs + mv docs-main docs + git checkout -- mkdocs.yml docs +} + +main "$@" diff --git a/contrib/sort-mkdocs-versions b/contrib/sort-mkdocs-versions new file mode 100644 index 000000000..21ef20020 --- /dev/null +++ b/contrib/sort-mkdocs-versions @@ -0,0 +1,38 @@ +#!/usr/bin/env python +import json + + +def main(): + version_file = "tmp/docs-build/versions.json" + data = [] + with open(version_file) as f: + data = json.load(f) + + versions = [] + for info in data: + if info["title"] == "latest": + continue + versions.append(info["title"].removeprefix("v")) + + versions.sort(key=lambda x: list(map(int, x.split('.'))), reverse=True) + data = [ + { + "aliases": ["latest"], + "title": "latest", + "version": "docs", + } + ] + + for version in versions: + data.append({ + "aliases": [], + "title": f"v{version}", + "version": f"docs~v{version}", + }) + + with open(version_file, "w") as f: + json.dump(data, f, indent=4) + + +if __name__ == "__main__": + main() diff --git a/contrib/write-mkdocs b/contrib/write-mkdocs new file mode 100644 index 000000000..71e70b430 --- /dev/null +++ b/contrib/write-mkdocs @@ -0,0 +1,343 @@ +#!/usr/bin/env python +from bs4 import BeautifulSoup +import os +import pathlib +import shutil +import sys +import yaml + + +def get_nav_from_selector(soup, selector, docs_dir): + navigation = [] + header_name = "" + for anchor in soup.select(selector): + classes = anchor.get("class", []) + if classes is None: + continue + + if "disabled" in classes: + header_name = anchor.text + navigation.append({header_name: []}) + + href = anchor.get("href", "") + if href is None: + continue + + href = str(href) + if href == "#": + continue + + url = href.replace("{{NAME}}", "") + filename = url.replace("http://progrium.viewdocs.io/dokku/", "") + filename = filename.replace("http://dokku.viewdocs.io/dokku/", "") + filename = filename.strip("/") + ".md" + filename = filename.removeprefix("dokku/") + + ignore_errors_for = [ + "getting-started/installation.md", + "getting-started/upgrading.md", + ] + if not os.path.exists(docs_dir + "/" + filename): + if filename not in ignore_errors_for: + print("error fetching markdown file:", filename) + continue + + for nav in navigation: + if header_name in nav: + if filename == "getting-started/installation.md": + child_dir = "getting-started/install/" + children = os.listdir(docs_dir + "/" + child_dir) + children = [child_dir + c for c in children] + children.insert( + 0, "getting-started/advanced-installation.md") + if os.path.exists(docs_dir + "/" + filename): + children.insert(0, filename) + else: + children.insert( + 0, "getting-started/installation/index.md") + nav[header_name].append({ + "Getting Started with Dokku": children, + }) + continue + elif filename == "getting-started/upgrading.md": + child_dir = "appendices/" + children = os.listdir(docs_dir + "/" + child_dir) + + children.sort(key=lambda x: list( + map(int, x.split("-")[0].split('.'))), + reverse=True) + children = [child_dir + c for c in children] + if os.path.exists(docs_dir + "/" + filename): + children.insert(0, filename) + else: + children.insert( + 0, "getting-started/upgrading/index.md") + nav[header_name].append({ + "Upgrading": children, + }) + continue + else: + nav[header_name].append(filename) + return navigation + + +def generate_nav(src, dest): + navigation = [] + repo_dir = pathlib.Path(__file__).parent.parent.resolve() + docs_dir = str(repo_dir) + "/docs" + with open(docs_dir + "/template.html") as response: + soup = BeautifulSoup(response, "html.parser") + selectors = [ + ".container .row .list-group a", + ".container-fluid .row .list-group a", + ] + for selector in selectors: + navigation = get_nav_from_selector(soup, selector, docs_dir) + if len(navigation) > 0: + break + + if len(navigation) == 0: + print("No navigation found") + sys.exit(1) + + with open(src) as f: + data = yaml.unsafe_load(f) + data["nav"] = [ + {"Docs": navigation}, + {"Pro": "https://pro.dokku.com/docs/getting-started/"}, + {"Blog": "https://dokku.github.io/"}, + {"Purchase Dokku Pro": "https://dokku.dpdcart.com/cart/add?product_id=217344&method_id=236878"}, + ] + + with open(dest, mode="wt", encoding="utf-8") as f: + yaml.dump(data, f) + + +def modify_content_noop(lines, _): + modified = False + updated_lines = [] + for line in lines: + updated_lines.append(line) + return updated_lines, modified + + +def modify_content_links(lines, filename): + filename = filename.replace("/usr/src/source/docs/", "") + parts = filename.split("/") + parts.pop() + replacement = "](" + '/'.join([".." for _ in parts]) + "/" + modified = False + updated_lines = [] + for line in lines: + if "](/docs/" in line: + line = line.replace("](/docs/", replacement) + modified = True + + updated_lines.append(line) + return updated_lines, modified + + +def modify_content_stripspace(lines, _): + modified = False + updated_lines = [] + for line in lines: + line = line.rstrip() + updated_lines.append(line) + return updated_lines, modified + + +def modify_content_inject_newlines(lines, _): + modified = False + updated_lines = [] + for line in lines: + updated_lines.append(line.rstrip() + "\n") + return updated_lines, modified + + +def is_info(line): + return line.startswith("> ") + + +def is_new(line): + return line.startswith("> ") and "new as of" in line.lower() + + +def is_note(line): + return line.startswith("> Note:") + + +def is_warning(line): + return line.startswith("> Warning:") + + +def modify_content_admonition(lines, _): + modified = False + updated_lines = [] + admonition_lines = [] + is_admonition = False + for line in lines: + if is_info(line) or is_new(line) or is_note(line) or is_warning(line): + if is_new(line): + line = line.replace("> ", "!!! tip \"New\"\n\n ") + line = line.replace("New as of", "Introduced in") + line = line.replace("new as of", "introduced in") + if is_note(line): + line = line.replace( + "> Note: ", "!!! note \"Note\"\n\n ") + elif is_warning(line): + line = line.replace( + "> Warning: ", "!!! warning \"Warning\"\n\n ") + elif is_info(line): + if not is_admonition: + line = line.replace("> ", "!!! info \"Info\"\n\n ") + elif line in [">", "> "]: + line = "" + else: + line = " " + line.removeprefix("> ") + + is_admonition = True + admonition_lines.append(line) + elif is_admonition and line in [">", "> "]: + line = "" + admonition_lines.append(line) + elif is_admonition and line.startswith("> "): + line = " " + line.removeprefix("> ") + admonition_lines.append(line) + elif line == "": + is_admonition = False + if len(admonition_lines) > 0: + updated_lines.extend(admonition_lines) + admonition_lines = [] + updated_lines.append("") + else: + updated_lines.append(line) + return updated_lines, modified + + +def is_shell_codeblock_start(line): + return line == "```shell" + + +def modify_content_terminal_example(lines, _): + modified = False + updated_lines = [] + command_block = [] + example_block = [] + in_command_block = False + in_example_block = False + previous_block = "" + next_line_must_be = None + for line in lines: + if is_shell_codeblock_start(line): + command_block.append(line) + modified = True + in_command_block = True + continue + elif in_command_block: + command_block.append(line) + if line == "```": + in_command_block = False + previous_block = "command_block" + next_line_must_be = "" + continue + elif line == "```": + if previous_block == "": + updated_lines.append(line) + continue + elif previous_block == "command_block": + example_block.append(line) + + if in_example_block: + previous_block = "" + in_example_block = False + updated_lines.append("=== \"Shell\"") + updated_lines.append("") + for command_line in command_block: + updated_lines.append(f" {command_line}") + command_block = [] + + updated_lines.append("") + updated_lines.append("=== \"Output\"") + updated_lines.append("") + for example_line in example_block: + updated_lines.append(f" {example_line}") + example_block = [] + else: + in_example_block = True + continue + elif previous_block == "command_block": + if next_line_must_be is None: + if in_example_block: + example_block.append(line) + else: + updated_lines.extend(command_block) + updated_lines.append("") + updated_lines.append(line) + command_block = [] + previous_block = "" + continue + elif next_line_must_be == "": + if line == "": + next_line_must_be = None + continue + + updated_lines.append(line) + + if len(command_block) > 0: + updated_lines.extend(command_block) + + return updated_lines, modified + + +def update_markdown(src): + markdown_files = [] + allowed_extensions = [".md"] + for subdir, _, files in os.walk(src): + for file in files: + ext = os.path.splitext(file)[-1].lower() + file_path = os.path.join(subdir, file) + if ext in allowed_extensions: + markdown_files.append(file_path) + + modifiers = [ + modify_content_noop, + modify_content_links, + modify_content_stripspace, + modify_content_admonition, + modify_content_terminal_example, + modify_content_inject_newlines, + ] + + for file in markdown_files: + modified = False + lines = [] + with open(file, 'r') as f: + lines = f.readlines() + for modifier in modifiers: + lines, m = modifier(lines, file) + if m: + modified = True + + if modified: + with open(file, 'w') as fp: + fp.writelines(lines) + + +def main(): + print("----> Copying mkdocs.yml") + print(" Generating navigation") + generate_nav("/usr/src/source/mkdocs.yml", "/usr/src/app/mkdocs.yml") + + print("----> Copying docs folder") + update_markdown("/usr/src/source/docs",) + + if os.path.exists("/usr/src/app/docs"): + print(" Removing old docs folder") + shutil.rmtree("/usr/src/app/docs") + + print(" Performing copy") + shutil.copytree("/usr/src/source/docs", "/usr/src/app/docs") + + +if __name__ == "__main__": + main() diff --git a/docs.mk b/docs.mk new file mode 100644 index 000000000..911eef17d --- /dev/null +++ b/docs.mk @@ -0,0 +1,19 @@ +.PHONY: docs-build-image +docs-build-image: + docker build -f docs/_build/Dockerfile --progress plain -t app/mkdocs . + +.PHONY: docs-build +docs-build: + @docker run --rm -p 3487:3487 -v "$(PWD):/usr/src/source" --name docs-serve app/mkdocs build + +.PHONY: docs-serve +docs-serve: + docker run --rm -p 3487:3487 -v "$(PWD):/usr/src/source" --name docs-serve app/mkdocs serve + +.PHONY: docs-deps +docs-deps: + @docker run --rm -p 3487:3487 -v "$(PWD):/usr/src/app" app/mkdocs deps + +.PHONY: docs-enter +docs-enter: + docker exec -it docs-serve bash diff --git a/docs/_build/Dockerfile b/docs/_build/Dockerfile new file mode 100644 index 000000000..4c233db37 --- /dev/null +++ b/docs/_build/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.10-alpine + +WORKDIR /usr/src/app + +COPY docs/_build/requirements.txt . + +RUN apk add --no-cache bash yaml && \ + pip install --no-cache-dir -r requirements.txt + +COPY docs/_build/entrypoint /bin/entrypoint + +ENTRYPOINT [ "/bin/entrypoint" ] diff --git a/docs/_build/app-nginx.conf.sigil b/docs/_build/app-nginx.conf.sigil new file mode 100644 index 000000000..4870d426e --- /dev/null +++ b/docs/_build/app-nginx.conf.sigil @@ -0,0 +1,30 @@ +worker_processes 1; +error_log stderr; +pid nginx.pid; +daemon off; + +events { + worker_connections 768; +} + +http { + types_hash_max_size 2048; + include mime.types; + charset UTF-8; + server { + listen {{ $.PORT }}; + server_name _; + root /app/www; + index index.html; + port_in_redirect off; + + include /app/www/nginx.conf.d/*.conf; + location ^~ /nginx.conf.d/ { + return 404; + } + + location / { + try_files $uri $uri/ =404; + } + } +} diff --git a/docs/_build/entrypoint b/docs/_build/entrypoint new file mode 100755 index 000000000..891f76432 --- /dev/null +++ b/docs/_build/entrypoint @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -eo pipefail + +write-mkdocs() { + if [[ -f /usr/src/source/contrib/write-mkdocs ]]; then + if ! python /usr/src/source/contrib/write-mkdocs; then + exit 0 + fi + fi +} + +main() { + declare CMD="$1" ARGS=("${@:2}") + + if [[ "$CMD" == "build" ]]; then + write-mkdocs + echo "----> Executing mkdocs build" + mkdocs build + site_dir="$(grep site_dir mkdocs.yml | awk '{print $2}')" + cp -r "/usr/src/app/${site_dir}" "/usr/src/source/${site_dir}" + + return $? + fi + + if [[ "$CMD" == "deps" ]]; then + pip freeze + return $? + fi + + if [[ "$CMD" == "serve" ]]; then + write-mkdocs + mkdocs serve -a 0.0.0.0:3487 + return $? + fi + + "$CMD" "${ARGS[@]}" +} + +main "$@" diff --git a/docs/_build/requirements.txt b/docs/_build/requirements.txt new file mode 100644 index 000000000..4cdb3037d --- /dev/null +++ b/docs/_build/requirements.txt @@ -0,0 +1,23 @@ +beautifulsoup4==4.11.1 +click==8.1.3 +ghp-import==2.1.0 +importlib-metadata==4.12.0 +Jinja2==3.1.2 +Markdown==3.3.7 +MarkupSafe==2.1.1 +mergedeep==1.3.4 +mkdocs==1.3.1 +mkdocs-exclude==1.0.2 +mkdocs-material==8.4.2 +mkdocs-material-extensions==1.0.3 +packaging==21.3 +Pygments==2.13.0 +pymdown-extensions==9.5 +pyparsing==3.0.9 +python-dateutil==2.8.2 +PyYAML==6.0 +pyyaml_env_tag==0.1 +six==1.16.0 +soupsieve==2.3.2.post1 +watchdog==2.1.9 +zipp==3.8.1 diff --git a/docs/_overrides/main.html b/docs/_overrides/main.html new file mode 100644 index 000000000..8233afc3b --- /dev/null +++ b/docs/_overrides/main.html @@ -0,0 +1,56 @@ + + +{% extends "base.html" %} + + +{% block extrahead %} + + + +{% endblock %} + + +{% block announce %} + + For updates follow @dokku on + + {% include ".icons/fontawesome/brands/twitter.svg" %} + + Twitter + +{% endblock %} + + +{% block scripts %} + {{ super() }} + + + +{% endblock %} + +{% block outdated %} + You're not viewing the latest version. + + Click here to go to latest. + +{% endblock %} diff --git a/docs/advanced-usage/persistent-storage.md b/docs/advanced-usage/persistent-storage.md index 1edc4d404..fa288c49b 100644 --- a/docs/advanced-usage/persistent-storage.md +++ b/docs/advanced-usage/persistent-storage.md @@ -175,4 +175,4 @@ By default, Dokku will execute your buildpack app processes as the `herokuishuse > NOTE: this user must exist in your herokuish image. -Additionally, the default `docker-local` scheduler that comes with Dokku will ensure your storage mounts are owned by either `herokuishuser` or the overridden value you have set in `DOKKU_APP_USER`. See the [docker-local scheduler documentation](/docs/advanced-usage/schedulers/docker-local.md#disabling-chown-of-persistent-storage) docs for more information. +Additionally, the default `docker-local` scheduler that comes with Dokku will ensure your storage mounts are owned by either `herokuishuser` or the overridden value you have set in `DOKKU_APP_USER`. See the [docker-local scheduler documentation](/docs/deployment/schedulers/docker-local.md#disabling-chown-of-persistent-storage) docs for more information. diff --git a/docs/advanced-usage/resource-management.md b/docs/advanced-usage/resource-management.md index 24ebaf735..bcbe07a91 100644 --- a/docs/advanced-usage/resource-management.md +++ b/docs/advanced-usage/resource-management.md @@ -28,7 +28,7 @@ Valid resource options include: - `--network-egress` - `--nvidia-gpu` -See the [Supported Resource Management Properties](/docs/advanced-usage/schedulers/docker-local.md#supported-resource-management-properties) section of the docker local scheduler documentation for more information on how each resource limit maps to Docker. +See the [Supported Resource Management Properties](/docs/deployment/schedulers/docker-local.md#supported-resource-management-properties) section of the docker local scheduler documentation for more information on how each resource limit maps to Docker. Resource limits and reservations are applied only during the `run` and `deploy` phases of an application, and will not impact the `build` phase of an application. diff --git a/docs/appendices/0.25.0-migration-guide.md b/docs/appendices/0.25.0-migration-guide.md index 95c74490a..1ff9ab5b8 100644 --- a/docs/appendices/0.25.0-migration-guide.md +++ b/docs/appendices/0.25.0-migration-guide.md @@ -7,7 +7,7 @@ The [dokku-registry](https://github.com/dokku/dokku-registry) plugin is now buil - Builder plugins should call `post-release-builder` at the end of the build. - The `push` and `pull` command are not implemented. Users wishing to deploy a remote image should use `git:from-image`. Image pushing is not available at this time. - At this time, remote docker repositories are not automatically created for AWS, and users must create those repositories for their applications as necessary. This may be implemented in the future. -- Docker images are only pushed when configured to do so. See the [registry management documentation](/docs/deployment/registry-management.md) for more details. +- Docker images are only pushed when configured to do so. See the [registry management documentation](/docs/advanced-usage/registry-management.md) for more details. Before upgrading, uninstall the registry plugin via `dokku plugin:uninstall registry`. Not doing so will cause issues with Dokku. diff --git a/docs/assets/extra.css b/docs/assets/extra.css new file mode 100644 index 000000000..d52a3ca82 --- /dev/null +++ b/docs/assets/extra.css @@ -0,0 +1,5 @@ +:root > * { + --md-primary-fg-color: #2A8FBD; + --md-primary-fg-color--light: #ECB7B7; + --md-primary-fg-color--dark: #90030C; +} diff --git a/docs/deployment/application-deployment.md b/docs/deployment/application-deployment.md index 3b1427169..07ce90825 100644 --- a/docs/deployment/application-deployment.md +++ b/docs/deployment/application-deployment.md @@ -1,4 +1,4 @@ -# Deploying to Dokku +# Deploying an Application > Note: This walkthrough uses the hostname `dokku.me` in commands. When deploying to your own server, you should substitute the domain `dokku.me` for the domain name or IP address associated with your server. Users of the Vagrant VM included with Dokku can use `dokku.me` which points to the IP of the VM. @@ -105,7 +105,7 @@ Dokku supports deploying applications in a few ways: - [Heroku buildpacks](https://devcenter.heroku.com/articles/buildpacks) via [Herokuish](https://github.com/gliderlabs/herokuish#buildpacks): See the [herokuish buildpacks documentation](/docs/deployment/builders/herokuish-buildpacks.md) to learn about the different ways to specify a buildpack. - This is the default method used by Dokku. - [Dockerfile](https://docs.docker.com/reference/builder/): See the [dockerfile documentation](/docs/deployment/builders/dockerfiles.md) to learn about the different ways to configure Dockerfile-based deploys. -- [Docker Image](https://docs.docker.com/get-started/overview/#docker-objects): See the [docker image documentation](/docs/deployment/methods/images.md) to learn about how to deploy a Docker Image. +- [Docker Image](https://docs.docker.com/get-started/overview/#docker-objects): See the [docker image documentation](/docs/deployment/methods/git.md#initializing-an-app-repository-from-a-docker-image) to learn about how to deploy a Docker Image. ### Setting up SSL @@ -242,7 +242,7 @@ See the [Dockerfile documentation](/docs/deployment/builders/dockerfiles.md) for ## Image tagging -See the [image tagging documentation](/docs/deployment/methods/images.md) for more information on how Docker images can be tagged and deployed for a given application. +See the [image tagging documentation](/docs/deployment/methods/git.md#initializing-an-app-repository-from-a-docker-image) for more information on how Docker images can be tagged and deployed for a given application. ## Specifying a custom buildpack diff --git a/docs/deployment/builders/cloud-native-buildpacks.md b/docs/deployment/builders/cloud-native-buildpacks.md index ebbb15768..edf63236e 100644 --- a/docs/deployment/builders/cloud-native-buildpacks.md +++ b/docs/deployment/builders/cloud-native-buildpacks.md @@ -1,4 +1,4 @@ -# Cloud Native Buildpacks (Experimental) +# Cloud Native Buildpacks > New as of 0.22.0 diff --git a/docs/deployment/builders/herokuish-buildpacks.md b/docs/deployment/builders/herokuish-buildpacks.md index 0f863085f..179e6c321 100644 --- a/docs/deployment/builders/herokuish-buildpacks.md +++ b/docs/deployment/builders/herokuish-buildpacks.md @@ -1,4 +1,4 @@ -# Herokuish Buildpack Deployment +# Herokuish Buildpacks > Subcommands new as of 0.15.0 diff --git a/docs/deployment/logs.md b/docs/deployment/logs.md index 820e5ebd5..62cba312b 100644 --- a/docs/deployment/logs.md +++ b/docs/deployment/logs.md @@ -43,7 +43,7 @@ The above command will show logs continually from the web process. ### Failed deploy logs -> Warning: The default [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md) will "store" these until the next deploy or until the old containers are garbage collected - whichever runs first. If you require the logs beyond this point in time, please ship the logs to a centralized log server. +> Warning: The default [docker-local scheduler](/docs/deployment/schedulers/docker-local.md) will "store" these until the next deploy or until the old containers are garbage collected - whichever runs first. If you require the logs beyond this point in time, please ship the logs to a centralized log server. In some cases, it may be useful to retrieve the logs from a previously failed deploy. diff --git a/docs/deployment/schedulers/scheduler-management.md b/docs/deployment/schedulers/scheduler-management.md index 132720ed7..f41ca0390 100644 --- a/docs/deployment/schedulers/scheduler-management.md +++ b/docs/deployment/schedulers/scheduler-management.md @@ -18,8 +18,6 @@ Dokku supports the following built-in schedulers: - `scheduler-docker-local`: Schedules apps against the local docker socket and runs containers directly on the Dokku host. See the [docker-local scheduler documentation](/docs/deployment/schedulers/docker-local.md) for more information on how this scheduler functions. - `scheduler-null`: Does nothing during the scheduler phase. See the [null scheduler documentation](/docs/deployment/schedulers/null.md) for more information on how this scheduler functions. -See the [alternate schedulers documentation](/docs/deployment/schedulers/alternate-schedulers.md) for more information on other scheduler plugins. - ### Overriding the auto-selected scheduler If desired, the scheduler can be specified via the `scheduler:set` command by speifying a value for `selected`. The selected scheduler will always be used. diff --git a/docs/deployment/zero-downtime-deploys.md b/docs/deployment/zero-downtime-deploys.md index 93c315568..b68734ae2 100644 --- a/docs/deployment/zero-downtime-deploys.md +++ b/docs/deployment/zero-downtime-deploys.md @@ -1,4 +1,4 @@ -# Zero Downtime Deploys +# Zero Downtime Deploy Checks > New as of 0.5.0 diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation/index.md similarity index 100% rename from docs/getting-started/installation.md rename to docs/getting-started/installation/index.md diff --git a/docs/getting-started/upgrading.md b/docs/getting-started/upgrading/index.md similarity index 99% rename from docs/getting-started/upgrading.md rename to docs/getting-started/upgrading/index.md index b82d540cc..e45026086 100644 --- a/docs/getting-started/upgrading.md +++ b/docs/getting-started/upgrading/index.md @@ -1,6 +1,6 @@ # Upgrading -If your version of Dokku is pre 0.3.0 (check with `dokku version`), we recommend [a fresh install](/docs/getting-started/installation.md) on a new server. +If your version of Dokku is pre 0.3.0 (check with `dokku version`), we recommend [a fresh install](/docs/getting-started/installation/index.md) on a new server. ## Security Updates diff --git a/docs/home.html b/docs/home.html index d77e00122..042e7bb12 100644 --- a/docs/home.html +++ b/docs/home.html @@ -98,7 +98,7 @@
-
Latest release v0.27.1
+
Latest release v0.28.1

An open source PAAS alternative to Heroku.

Dokku helps you build and manage the lifecycle of applications from building to scaling.

diff --git a/docs/networking/dns.md b/docs/networking/dns.md index e675783d6..80c5975b2 100644 --- a/docs/networking/dns.md +++ b/docs/networking/dns.md @@ -65,7 +65,7 @@ If everything is working correctly, you should also be able to query for any oth If they all return your IP address, you have set DNS up properly for dokku. You should also be able to `ssh root@myserver.example.tld` and access your server. -Proceed with the setup instructions in the [installation documentation](/docs/getting-started/installation.md) +Proceed with the setup instructions in the [installation documentation](/docs/getting-started/installation/index.md) ### Using the root of your domain (node-js-app.example.tld) diff --git a/docs/networking/network.md b/docs/networking/network.md index 237e0e0fe..95089cbc7 100644 --- a/docs/networking/network.md +++ b/docs/networking/network.md @@ -161,7 +161,7 @@ Only a single `$IP:$PORT` combination can be routed to for a given app, and that > New as of 0.20.0, Requires Docker 1.21+ -Apps will default to being associated with the default `bridge` network or a network specified by the `initial-network` network property. Additionally, an app can be attached to `attachable` networks by changing the `attach-post-create` or `attach-post-deploy` network properties when using the [docker-local scheduler](/docs/advanced-usage/schedulers/docker-local.md). A change in these values will require an app deploy or rebuild. +Apps will default to being associated with the default `bridge` network or a network specified by the `initial-network` network property. Additionally, an app can be attached to `attachable` networks by changing the `attach-post-create` or `attach-post-deploy` network properties when using the [docker-local scheduler](/docs/deployment/schedulers/docker-local.md). A change in these values will require an app deploy or rebuild. ```shell # associates the network after a container is created but before it is started diff --git a/docs/template.html b/docs/template.html index 9c3803916..dbff9cbda 100644 --- a/docs/template.html +++ b/docs/template.html @@ -198,7 +198,6 @@ Kubernetes Nomad Null Scheduler - Alternate Schedulers Development diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..1aa6d0681 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,91 @@ +--- +# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json + +markdown_extensions: + - admonition + - attr_list + - footnotes + - md_in_html + - pymdownx.details + - pymdownx.emoji: + emoji_generator: !!python/name:materialx.emoji.to_svg + emoji_index: !!python/name:materialx.emoji.twemoji + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - tables + +repo_url: https://github.com/dokku/dokku + +site_dir: site +site_name: Dokku Documentation +site_url: https://dokku.com/docs/ + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/dokku/dokku + - icon: fontawesome/solid/bug + link: https://github.com/dokku/dokku/issues + - icon: fontawesome/brands/discord + link: https://discord.gg/YQjANGMZvu + - icon: fontawesome/brands/slack + link: https://slack.dokku.com/ + - icon: fontawesome/solid/hashtag + link: https://webchat.libera.chat/?channels=dokku + - icon: fontawesome/brands/twitter + link: https://twitter.com/dokku + - icon: fontawesome/solid/comments + link: https://github.com/dokku/dokku/discussions + - icon: fontawesome/solid/cart-shopping + link: https://dokku.dpdcart.com/cart/add?product_id=217344&method_id=236878 + version: + provider: mike + +theme: + custom_dir: docs/_overrides + favicon: assets/favicons/favicon-96x96.png + features: + - navigation.indexes + - navigation.instant + - navigation.sections + - navigation.tabs + - navigation.top + - search.highlight + homepage: https://dokku.com + icon: + admonition: + tip: fontawesome/solid/wand-magic-sparkles + logo: assets/dokku-logo.svg + name: material + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/toggle-switch + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/toggle-switch-off-outline + name: Switch to light mode + +plugins: + - search + - exclude: + glob: + - _build/Dockerfile + - _build/entrypoint + - _build/requirements.txt + - home.html + - template.html + +extra_css: + - assets/extra.css