🏡 index : ~doyle/chartered.git

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Server Installation - Chartered</title>
        <!-- Custom HTML head -->
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../favicon.svg">
        <link rel="shortcut icon" href="../favicon.png">
        <link rel="stylesheet" href="../css/variables.css">
        <link rel="stylesheet" href="../css/general.css">
        <link rel="stylesheet" href="../css/chrome.css">
        <link rel="stylesheet" href="../css/print.css" media="print">
        <!-- Fonts -->
        <link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../fonts/fonts.css">
        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../highlight.css">
        <link rel="stylesheet" href="../tomorrow-night.css">
        <link rel="stylesheet" href="../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
    </head>
    <body>
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="chapter-item expanded "><a href="../getting-started/index.html"><strong aria-hidden="true">1.</strong> Getting Started</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../getting-started/installation.html" class="active"><strong aria-hidden="true">1.1.</strong> Server Installation</a></li><li class="chapter-item expanded "><a href="../getting-started/user-guide.html"><strong aria-hidden="true">1.2.</strong> User Guide</a></li></ol></li><li class="chapter-item expanded "><a href="../guide/index.html"><strong aria-hidden="true">2.</strong> Chartered Guide</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../guide/config-reference.html"><strong aria-hidden="true">2.1.</strong> Configuration Reference</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Chartered</h1>

                    <div class="right-buttons">
                        <a href="../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>
                        <a href="https://github.com/w4/chartered/tree/main/book" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>
                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>
                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="server-installation"><a class="header" href="#server-installation">Server Installation</a></h1>
<p>Chartered's server comes in 3 parts:</p>
<ul>
<li><strong>chartered-git</strong>: hosts the git server which clients grab the crate index from, along with
their credentials to grab the crates from the next service,</li>
<li><strong>chartered-web</strong>: hosts the API portion of chartered, which serves the crates themselves
(or a redirect to them, depending on which storage backend you're using) and hosts the &quot;web
API&quot; which is consumed by our final service,</li>
<li><strong>chartered-frontend</strong>: a React-based <a href="https://crates.io/">crates.io</a>-like web UI for viewing
crates, managing organisations and viewing AAA data.</li>
</ul>
<p>Each of these services are hosted separately from one another, and could technically be swapped
out for other implementations - the only shared layer between the three of them is database
storage for crate lookups and authentication credential vending. All of the services have the
ability to be clustered with no extra configuration.</p>
<h3 id="backend-services"><a class="header" href="#backend-services">Backend Services</a></h3>
<p><code>chartered-git</code> and <code>chartered-web</code>'s setups are similar, first they need a database set up -
either SQLite or PostgreSQL, PostgreSQL is recommended anywhere outside of development/local
use for obvious reasons.</p>
<p>Both the aformentioned services have sane defaults for development and can be ran simply by
running the binary, the services will bind to <code>127.0.0.1:8899</code> and <code>127.0.0.1:8080</code> respectively
and store crate files in <code>/tmp/chartered</code>, configuration away from these defaults is simple.</p>
<p>Using the recommended setup, S3 &amp; PostgreSQL:</p>
<pre><code class="language-toml">bind_address = &quot;127.0.0.1:8080&quot; # hint: use a different port for each service
database_uri = &quot;postgres://user:password@localhost/chartered&quot;

# the below configuration options should only be set for chartered-web
storage_uri  = &quot;s3://s3-eu-west-1.amazonaws.com/my-cool-crate-store/&quot;
frontend_url = &quot;https://my.instance.chart.rs&quot; # this is used for CORS
                                              # if unset defaults to *

# openid connect provider
[auth.gitlab]
enabled = true
discovery_uri = &quot;https://gitlab.com/&quot;
client_id = &quot;[client-id]&quot;
client_secret = &quot;[client-secret]&quot;
</code></pre>
<p>Or, using the defaults of <code>chartered-web</code> as an example:</p>
<pre><code class="language-toml">bind_address = &quot;127.0.0.1:8899&quot;
database_uri = &quot;sqlite://chartered.db&quot;

storage_uri  = &quot;file:///tmp/chartered&quot;
</code></pre>
<p>These configuration files can be passed into each binary using the <code>-c</code> CLI argument.</p>
<p>Alternative crate stores will be considered, please consider contributing or
<a href="https://github.com/w4/chartered/issues">create an issue on GitHub</a>. <span style="color: transparent;">MySQL support, however, is a no-go.</span></p>
<p><code>chartered-web</code> &amp; <code>chartered-git</code> can be built from source easily or ran using the
Dockerfile:</p>
<pre><code>$ docker build https://github.com/w4/chartered.git#main \
    --target chartered-web \
    -t chartered-web:master
$ docker build https://github.com/w4/chartered.git#main \
    --target chartered-git \
    -t chartered-git:master
$ docker run -d chartered-web
$ docker run -d chartered-git
</code></pre>
<h3 id="frontend"><a class="header" href="#frontend">Frontend</a></h3>
<p>The frontend only needs to be configured to point to the <code>chartered-web</code> service. This can be
done by changing the bundled <code>config.json</code>. This can then be hosted in S3/minio/your preferred
static hosting platform, a Dockerfile can also be built which uses <a href="https://github.com/joseluisq/static-web-server"><code>static-web-server</code></a>
to run on your own server without another way of hosting static content:</p>
<pre><code class="language-sh"># buildkit doesn't yet support subdirectories for git repositories
$ DOCKER_BUILDKIT=0 docker build \
    https://github.com/w4/chartered.git#main:chartered-frontend \
    --build-arg BASE_URL=https://api.my.instance.chart.rs \
    -t chartered-frontend:master
$ docker run -d -p 8080:80 chartered-frontend:master
$ curl http://127.0.0.1:8080
&lt;!DOCTYPE html&gt;&lt;html lang=&quot;en&quot;&gt;&lt;head&gt;&lt;meta charset=&quot;UTF-8&quot;&gt;...
</code></pre>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../getting-started/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>
                            <a rel="next" href="../getting-started/user-guide.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>
                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../getting-started/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>
                    <a rel="next" href="../getting-started/user-guide.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>

        <script type="text/javascript">
            window.playground_copyable = true;
        </script>
        <script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
        <script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->
    </body>
</html>