luet/docs/concepts/overview/build_packages/index.html

645 lines
50 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.91.2" />
<meta name="robots" content="index, follow">
<link rel="shortcut icon" href="/favicons/favicon.ico" >
<link rel="apple-touch-icon" href="/favicons/apple-touch-icon-180x180.png" sizes="180x180">
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicons/android-36x36.png" sizes="36x36">
<link rel="icon" type="image/png" href="/favicons/android-48x48.png" sizes="48x48">
<link rel="icon" type="image/png" href="/favicons/android-72x72.png" sizes="72x72">
<link rel="icon" type="image/png" href="/favicons/android-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/favicons/android-144x144.png" sizes="144x144">
<link rel="icon" type="image/png" href="/favicons/android-192x192.png" sizes="192x192">
<title>Building packages | Luet</title>
<meta name="description" content="How to build packages with Luet
">
<meta property="og:title" content="Building packages" />
<meta property="og:description" content="How to build packages with Luet
" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://luet.io/docs/concepts/overview/build_packages/" /><meta property="article:section" content="docs" />
<meta property="article:published_time" content="2017-01-05T00:00:00+00:00" />
<meta property="article:modified_time" content="2024-06-24T16:07:25+02:00" /><meta property="og:site_name" content="Luet" />
<meta itemprop="name" content="Building packages">
<meta itemprop="description" content="How to build packages with Luet
"><meta itemprop="datePublished" content="2017-01-05T00:00:00+00:00" />
<meta itemprop="dateModified" content="2024-06-24T16:07:25+02:00" />
<meta itemprop="wordCount" content="1412">
<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Building packages"/>
<meta name="twitter:description" content="How to build packages with Luet
"/>
<link rel="preload" href="/scss/main.min.f944e6adf1b7822650022e3aa7789905c53fc9e2e8a936de4e5294f297b5677c.css" as="style">
<link href="/scss/main.min.f944e6adf1b7822650022e3aa7789905c53fc9e2e8a936de4e5294f297b5677c.css" rel="stylesheet" integrity="">
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK"
crossorigin="anonymous"></script>
<script
src="https://unpkg.com/lunr@2.3.9/lunr.min.js"
integrity="sha384-203J0SNzyqHby3iU6hzvzltrWi/M41wOP5Gu+BiJMz5nwKykbkUx8Kp7iti0Lpli"
crossorigin="anonymous"></script>
<script type="application/javascript">
var doNotTrack = false;
if (!doNotTrack) {
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-00000000-0', 'auto');
ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
</head>
<body class="td-page">
<header>
<nav class="js-navbar-scroll navbar navbar-expand navbar-dark flex-column flex-md-row td-navbar">
<a class="navbar-brand" href="/">
<span class="navbar-logo"><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" style="enable-background:new 0 0 500 500"><g><path style="fill:#fff" d="M116.8525 421.9722c-5.7041.0-10.3442-4.3127-10.3442-9.6129V88.183c0-5.3002 4.6401-9.6117 10.3442-9.6117H320.858c3.0347.0 9.3959.5498 11.7506 2.6302l.3545.3442 58.905 63.2912c2.3101 2.491 2.9202 8.4928 2.9202 11.3184v256.2039c0 5.3002-4.6407 9.6129-10.3436 9.6129H116.8525z"/><g><g><g><path style="fill:#767676" d="M384.4445 423.2066H116.852c-6.3839.0-11.5786-4.8658-11.5786-10.8474V88.1831c0-5.9804 5.1947-10.8461 11.5786-10.8461h204.0062c.377.0 9.2786.0329 12.568 2.9389l.3947.3833 58.9508 63.337c3.2135 3.4652 3.2514 11.7924 3.2514 12.1593v256.2036C396.0231 418.3408 390.8284 423.2066 384.4445 423.2066zM116.5079 411.9189c.0848.0278.1999.0531.3441.0531h267.5925c.1442.0.2581-.0253.3441-.0531V156.1556c-.0076-.9033-.3593-3.7347-.7034-5.0037l-57.6527-61.9416c-1.4651-.3176-4.4533-.6389-5.5742-.6389H116.852c-.143.0-.2594.024-.3441.0531V411.9189zm267.4533-261.149zM327.0321 89.371v.0013V89.371z"/></g></g></g><g><g><path style="fill:#5b7fc0" d="M189.0874 210.1754l.0012-.0012c7.7751.0012 15.0295 4.1862 18.932 10.9234 1.9177 3.3159 2.9305 7.1011 2.9293 10.9378.0 5.8394-2.2733 11.3304-6.4032 15.4604-4.1288 4.1288-9.6186 6.4032-15.458 6.4032s-11.328-2.2733-15.458-6.4032-6.4032-9.6186-6.4056-15.4628c.0012-6.025 2.454-11.4897 6.4116-15.4473C177.5953 212.627 183.0601 210.1742 189.0874 210.1754zm7.993 21.8576c.0012-1.4042-.3687-2.7868-1.063-3.9887-1.4293-2.4684-4.0833-3.9995-6.9299-4.0019-4.4077.0024-7.993 3.5877-7.993 7.993.0 2.1356.832 4.1431 2.3427 5.6539 1.5083 1.5083 3.5159 2.3403 5.6503 2.3415 2.1356.0 4.1443-.8308 5.6539-2.3403S197.0816 234.1722 197.0804 232.033z"/><path style="opacity:.3;fill:#fff" d="M189.0898 210.176c7.7763.0 15.0283 4.1826 18.926 10.9151 1.9201 3.3136 2.9377 7.0988 2.9353 10.9462.0024 12.0643-9.8065 21.8636-21.8613 21.8613-12.0547.0024-21.8636-9.8066-21.8612-21.8613.0-6.0285 2.4516-11.4921 6.4116-15.452C177.5977 212.6276 183.0612 210.176 189.0898 210.176zm7.9941 21.8612c0-1.4078-.3711-2.7892-1.0702-3.9959-1.4269-2.466-4.0797-3.9983-6.924-3.9983-4.4005-.0048-7.9918 3.5817-7.9942 7.9942.0024 4.4077 3.5865 7.9918 7.9942 7.9942 2.2027.0 4.2018-.8978 5.6479-2.3439C196.1861 236.239 197.0839 234.2399 197.0839 232.0372z"/><g><defs><path id="SVGID_1_" d="M194.7376 237.6875c-1.4461 1.4461-3.4452 2.3439-5.6479 2.3439-4.4077-.0024-7.9918-3.5865-7.9942-7.9942.0024-4.4125 3.5937-7.999 7.9942-7.9942 2.8443.0 5.497 1.5323 6.924 3.9983.6991 1.2067 1.0702 2.5881 1.0702 3.9959C197.0839 234.2399 196.1861 236.239 194.7376 237.6875z"/></defs><clipPath id="SVGID_2_"><use xlink:href="#SVGID_1_" style="overflow:visible"/></clipPath><path style="clip-path:url(#SVGID_2_);fill:#fff" d="M190.0704 225.0237c-4.4005-.0048-7.9918 3.5817-7.9942 7.9942.0011 1.9546.7088 3.7452 1.8782 5.1354-1.7447-1.4674-2.8575-3.663-2.8588-6.116.0024-4.4125 3.5936-7.999 7.9942-7.9942 2.3802-1e-4 4.616 1.0833 6.1218 2.8788C193.7885 225.7247 191.9774 225.0237 190.0704 225.0237z"/><path style="opacity:.13;clip-path:url(#SVGID_2_);fill:#020202" d="M190.0704 225.0237c-4.4005-.0048-7.9918 3.5817-7.9942 7.9942.0011 1.9546.7088 3.7452 1.8782 5.1354-1.7447-1.4674-2.8575-3.663-2.8588-6.116.0024-4.4125 3.5936-7.999 7.9942-7.9942 2.3802-1e-4 4.616 1.0833 6.1218 2.8788C193.7885 225.7247 191.9774 225.0237 190.0704 225.0237z"/></g><g><defs><path id="SVGID_3_" d="M189.0898 210.176c7.7763.0 15.0283 4.1826 18.926 10.9151 1.9201 3.3136 2.9377 7.0988 2.9353 10.9462.0024 12.0643-9.8065 21.8636-21.8613 21.8613-12.0547.0024-21.8636-9.8066-21.8612-21.8613.0-6.0285 2.4516-11.4921 6.4116-15.452C177.5977 212.6276 183.0612 210.176 189.0898 210.176zm7.9941 21.8612c0-1.4078-.3711-2.7892-1.0702-3.9959-1.4269-2.466-4.0797-3.9983-6.924-3.9983-4.4005-.0048-7.9918 3.5817-7.9942 7.9942.0024 4.4077 3.5865 7.9918 7.9942 7.9942 2.2027.0 4.2018-.8978 5.6479-2.3439C196.1861 236.239 197.0839 234.2399 197.0839 232.0372z"/></defs><clipPath id="SVGID_4_"><use xlink:href="#SVGID_3_" style="overflo
</a>
<div class="td-navbar-nav-scroll ml-md-auto" id="main_navbar">
<ul class="navbar-nav mt-2 mt-lg-0">
<li class="nav-item mr-4 mb-2 mb-lg-0">
<a class="nav-link" href="/about/" ><span>About</span></a>
</li>
<li class="nav-item mr-4 mb-2 mb-lg-0">
<a class="nav-link active" href="/docs/" ><span class="active">Documentation</span></a>
</li>
<li class="nav-item mr-4 mb-2 mb-lg-0">
<a class="nav-link" href="/blog/" ><span>Blog</span></a>
</li>
<li class="nav-item mr-4 mb-2 mb-lg-0">
<a class="nav-link" href="/community/" ><span>Community</span></a>
</li>
<li class="nav-item mr-4 mb-2 mb-lg-0">
<a class="nav-link" href="https://github.com/mudler/luet/contribute" target="_blank" ><i class='fab fa-github'></i><span>Contribution guidelines</span></a>
</li>
</ul>
</div>
<div class="navbar-nav d-none d-lg-block"><input
type="search"
class="form-control td-search-input"
placeholder="&#xf002; Search this site…"
aria-label="Search this site…"
autocomplete="off"
data-offline-search-index-json-src="/offline-search-index.4fe7714e302eef4501ae919bdbad5ce4.json"
data-offline-search-base-href="/"
data-offline-search-max-results="10"
>
</div>
</nav>
</header>
<div class="container-fluid td-outer">
<div class="td-main">
<div class="row flex-xl-nowrap">
<aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none">
<div id="td-sidebar-menu" class="td-sidebar__inner">
<form class="td-sidebar__search d-flex align-items-center">
<input
type="search"
class="form-control td-search-input"
placeholder="&#xf002; Search this site…"
aria-label="Search this site…"
autocomplete="off"
data-offline-search-index-json-src="/offline-search-index.4fe7714e302eef4501ae919bdbad5ce4.json"
data-offline-search-base-href="/"
data-offline-search-max-results="10"
>
<button class="btn btn-link td-sidebar__toggle d-md-none p-0 ml-3 fas fa-bars" type="button" data-toggle="collapse" data-target="#td-section-nav" aria-controls="td-docs-nav" aria-expanded="false" aria-label="Toggle section navigation">
</button>
</form>
<nav class="collapse td-sidebar-nav" id="td-section-nav">
<ul class="td-sidebar-nav__section pr-md-3 ul-0">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id="m-docs-li">
<a href="/docs/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section tree-root" id="m-docs"><span class="">Documentation</span></a>
<ul class="ul-1">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsgetting-started-li">
<a href="/docs/getting-started/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docsgetting-started"><span class="">Getting Started</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id="m-docsconcepts-li">
<a href="/docs/concepts/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docsconcepts"><span class="">Concepts</span></a>
<ul class="ul-2 foldable">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id="m-docsconceptsoverview-li">
<a href="/docs/concepts/overview/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docsconceptsoverview"><span class="">Overview</span></a>
<ul class="ul-3 foldable">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child active-path" id="m-docsconceptsoverviewbuild_packages-li">
<a href="/docs/concepts/overview/build_packages/" class="align-left pl-0 active td-sidebar-link td-sidebar-link__page" id="m-docsconceptsoverviewbuild_packages"><span class="td-sidebar-nav-active-item">Building packages</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptsoverviewrepositories-li">
<a href="/docs/concepts/overview/repositories/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptsoverviewrepositories"><span class="">Creating Luet repositories</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptsoverviewusage-li">
<a href="/docs/concepts/overview/usage/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptsoverviewusage"><span class="">CLI usage</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptsoverviewconstraints-li">
<a href="/docs/concepts/overview/constraints/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptsoverviewconstraints"><span class="">CSP, SAT &amp;&amp; RL</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptsoverviewconfiguration-li">
<a href="/docs/concepts/overview/configuration/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptsoverviewconfiguration"><span class=""></span></a>
</li>
</ul>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id="m-docsconceptspackages-li">
<a href="/docs/concepts/packages/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docsconceptspackages"><span class="">Packages</span></a>
<ul class="ul-3 foldable">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptspackagesspecfile-li">
<a href="/docs/concepts/packages/specfile/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptspackagesspecfile"><span class="">Specfile</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptspackagestemplates-li">
<a href="/docs/concepts/packages/templates/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptspackagestemplates"><span class="">Templated packages</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptspackagescollections-li">
<a href="/docs/concepts/packages/collections/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsconceptspackagescollections"><span class="">Collections</span></a>
</li>
</ul>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsconceptsplugins-and-extensions-li">
<a href="/docs/concepts/plugins-and-extensions/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docsconceptsplugins-and-extensions"><span class="">Plugins and Extensions</span></a>
</li>
</ul>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id="m-docstutorials-li">
<a href="/docs/tutorials/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docstutorials"><span class="">Tutorials</span></a>
<ul class="ul-2 foldable">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docstutorialshello_world-li">
<a href="/docs/tutorials/hello_world/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docstutorialshello_world"><span class="">Hello world!</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docstutorialsbuild_package-li">
<a href="/docs/tutorials/build_package/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docstutorialsbuild_package"><span class="">Build a package</span></a>
</li>
</ul>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id="m-docsresources-li">
<a href="/docs/resources/" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id="m-docsresources"><span class="">Resources</span></a>
<ul class="ul-2 foldable">
<li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsresourcesarm-li">
<a href="/docs/resources/arm/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsresourcesarm"><span class="">ARM images</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsresourcesbuilding-li">
<a href="/docs/resources/building/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsresourcesbuilding"><span class="">Building</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsresourcesfaq-li">
<a href="/docs/resources/faq/" title="Frequently Asked Questions" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsresourcesfaq"><span class="">FAQ</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsresourcesscratch-li">
<a href="/docs/resources/scratch/" title="Images from scratch" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsresourcesscratch"><span class="">ScratchImages</span></a>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docsresourcesreferences-li">
<a href="/docs/resources/references/" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docsresourcesreferences"><span class="">References</span></a>
</li>
</ul>
</li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id="m-docscontribution-guidelines-li">
<a href="/docs/contribution-guidelines/" title="Contributing" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id="m-docscontribution-guidelines"><span class="">Contribution guidelines</span></a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</aside>
<aside class="d-none d-xl-block col-xl-2 td-sidebar-toc d-print-none">
<div class="td-page-meta ml-2 pb-1 pt-2 mb-0">
<a href="https://github.com/mudler/luet/tree/master/docs/content/en/docs/Concepts/Overview/build_packages.md" class="td-page-meta--view" target="_blank" rel="noopener"><i class="fa fa-file-alt fa-fw"></i> View page source</a>
<a href="https://github.com/mudler/luet/edit/master/docs/content/en/docs/Concepts/Overview/build_packages.md" class="td-page-meta--edit" target="_blank" rel="noopener"><i class="fa fa-edit fa-fw"></i> Edit this page</a>
<a href="https://github.com/mudler/luet/new/master/docs/content/en/docs/Concepts/Overview/build_packages.md?filename=change-me.md&amp;value=---%0Atitle%3A&#43;%22Long&#43;Page&#43;Title%22%0AlinkTitle%3A&#43;%22Short&#43;Nav&#43;Title%22%0Aweight%3A&#43;100%0Adescription%3A&#43;%3E-%0A&#43;&#43;&#43;&#43;&#43;Page&#43;description&#43;for&#43;heading&#43;and&#43;indexes.%0A---%0A%0A%23%23&#43;Heading%0A%0AEdit&#43;this&#43;template&#43;to&#43;create&#43;your&#43;new&#43;page.%0A%0A%2A&#43;Give&#43;it&#43;a&#43;good&#43;name%2C&#43;ending&#43;in&#43;%60.md%60&#43;-&#43;e.g.&#43;%60getting-started.md%60%0A%2A&#43;Edit&#43;the&#43;%22front&#43;matter%22&#43;section&#43;at&#43;the&#43;top&#43;of&#43;the&#43;page&#43;%28weight&#43;controls&#43;how&#43;its&#43;ordered&#43;amongst&#43;other&#43;pages&#43;in&#43;the&#43;same&#43;directory%3B&#43;lowest&#43;number&#43;first%29.%0A%2A&#43;Add&#43;a&#43;good&#43;commit&#43;message&#43;at&#43;the&#43;bottom&#43;of&#43;the&#43;page&#43;%28%3C80&#43;characters%3B&#43;use&#43;the&#43;extended&#43;description&#43;field&#43;for&#43;more&#43;detail%29.%0A%2A&#43;Create&#43;a&#43;new&#43;branch&#43;so&#43;you&#43;can&#43;preview&#43;your&#43;new&#43;file&#43;and&#43;request&#43;a&#43;review&#43;via&#43;Pull&#43;Request.%0A" class="td-page-meta--child" target="_blank" rel="noopener"><i class="fa fa-edit fa-fw"></i> Create child page</a>
<a href="https://github.com/mudler/luet/issues/new?title=Building%20packages" class="td-page-meta--issue" target="_blank" rel="noopener"><i class="fab fa-github fa-fw"></i> Create documentation issue</a>
<a href="https://github.com/mudler/luet/issues/new" class="td-page-meta--project-issue" target="_blank" rel="noopener"><i class="fas fa-tasks fa-fw"></i> Create project issue</a>
</div>
<div class="td-toc"><nav id="TableOfContents">
<ul>
<li><a href="#prerequisistes">Prerequisistes</a>
<ul>
<li><a href="#docker">Docker</a></li>
<li><a href="#img">Img</a></li>
<li><a href="#building-packages-on-kubernetes">Building packages on Kubernetes</a></li>
</ul>
</li>
<li><a href="#building-packages">Building packages</a></li>
<li><a href="#reproducible-builds">Reproducible builds</a></li>
<li><a href="#environmental-variables">Environmental variables</a></li>
<li><a href="#supported-compression-format">Supported compression format</a></li>
<li><a href="#example">Example</a>
<ul>
<li><a href="#the-extended-syntax">The extended syntax</a></li>
</ul>
</li>
<li><a href="#nesting-dependencies">Nesting dependencies</a>
<ul>
<li><a href="#example-1">Example</a></li>
</ul>
</li>
<li><a href="#caching-docker-images">Caching docker images</a>
<ul>
<li><a href="#build-faster">Build faster</a></li>
</ul>
</li>
<li><a href="#building-for-a-different-platform">Building for a different platform</a></li>
<li><a href="#notes">Notes</a></li>
</ul>
</nav></div>
</aside>
<main class="col-12 col-md-9 col-xl-8 pl-md-5" role="main">
<div class="td-content">
<h1>Building packages</h1>
<div class="lead">How to build packages with Luet</div>
<header class="article-meta">
</header>
<h2 id="prerequisistes">Prerequisistes</h2>
<p>Luet currently supports <a href="https://www.docker.com/">Docker</a> and <a href="https://github.com/genuinetools/img">Img</a> as backends to build packages. Both of them can be used and switched in runtime with the <code>--backend</code> option, so either one of them must be present in the host system.</p>
<h3 id="docker">Docker</h3>
<p>Docker is the (less) experimental Luet engine supported. Be sure to have Docker installed and the daemon running. The user running <code>luet</code> commands needs the corresponding permissions to run the <code>docker</code> executable, and to connect to a <code>docker</code> daemon. The only feature needed by the daemon is the ability to build images, so it fully supports remote daemon as well (this can be specified with the <code>DOCKER_HOST</code> environment variable, that is respected by <code>luet</code>)</p>
<h3 id="img">Img</h3>
<p>Luet supports <a href="https://github.com/genuinetools/img">Img</a>. To use it, simply install it in your system, and while running <code>luet build</code>, you can switch the backend by providing it as a parameter: <code>luet build --backend img</code>. For small packages it is particularly powerful, as it doesn&rsquo;t require any docker daemon running in the host.</p>
<h3 id="building-packages-on-kubernetes">Building packages on Kubernetes</h3>
<p>Luet and img can be used together to orchestrate package builds also on kubernetes. There is available an experimental <a href="https://github.com/mudler/luet-k8s">Kubernetes CRD for Luet</a> which allows to build packages seamelessly in Kubernetes and push package artifacts to an S3 Compatible object storage (e.g. Minio).</p>
<h2 id="building-packages">Building packages</h2>
<p><img src="/docs/tree.jpg" alt="Build packages"></p>
<p>Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.</p>
<p>To resolve the dependency tree Luet uses a SAT solver and no database. It is responsible for calculating the dependencies of a package and to prevent conflicts. The Luet core is still young, but it has a comprehensive test suite that we use to validate any future changes.</p>
<p>Building a package with Luet requires only a <a href="/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="/docs/concepts/packages/collections">collections</a>. Luet also supports building packages from standard <code>Dockerfile</code> directly.</p>
<p>Run <code>luet build --help</code> to get more help for each parameter.</p>
<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p>
<h2 id="reproducible-builds">Reproducible builds</h2>
<p>Pinning a container build is not easy - there are always so many moving pieces, and sometimes just set <code>FROM</code> an image tag might not be enough.</p>
<p>Luet while building a package generates intermediate images that are stored and can be optionally pushed in a registry. Those images can be re-used by Luet if building again the same tree to guarantuee highly reproducible builds.</p>
<h2 id="environmental-variables">Environmental variables</h2>
<p>Luet builds passes its environment variable at the engine which is called during build, so for example the environment variable <code>DOCKER_HOST</code> or <code>DOCKER_BUILDKIT</code> can be setted.</p>
<p>Every argument from the CLI can be setted via environment variable too with a <code>LUET_</code> prefix, for instance the flag <code>--clean</code>, can be setted via environment with <code>LUET_CLEAN</code>, <code>--privileged</code> can be enabled with <code>LUET_PRIVILEGED</code> and so on.</p>
<h2 id="supported-compression-format">Supported compression format</h2>
<p>At the moment, <code>luet</code> can compress packages and tree with <code>zstd</code> and <code>gzip</code>. For example:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet build --compression zstd ...
</code></pre></div><p>Will output package compressed in the zstd format.</p>
<p>See the <code>--help</code> of <code>create-repo</code> and <code>build</code> to learn all the available options.</p>
<h2 id="example">Example</h2>
<p>Luet can seamlessly build packages also from Dockerfiles (<em>since luet&gt;=0.32.0</em>), consider the following example, that will generate a <code>curl</code> package from an <code>alpine</code> image:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; <span style="color:#8f5902;font-style:italic"># put yourself in some workdir</span>
$~/workdir&gt; mkdir curl
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; curl/Dockerfile
</span><span style="color:#4e9a06">FROM alpine
</span><span style="color:#4e9a06">apk add curl
</span><span style="color:#4e9a06">EOF</span>
$~/workdir&gt; luet build --all
</code></pre></div><p>However, <code>luet</code> supports an extended syntax that allows to define packages with a more fine-grained control, templating support, and several other features that makes creation batch images much faster.</p>
<h3 id="the-extended-syntax">The extended syntax</h3>
<p>A <a href="/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p>
<p>In the following example, we are creating a dummy package (<code>bar/foo</code>). Which ships one file only, <code>/foo</code></p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; <span style="color:#8f5902;font-style:italic"># put yourself in some workdir</span>
$~/workdir&gt; mkdir package
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package/build.yaml
</span><span style="color:#4e9a06">image: busybox
</span><span style="color:#4e9a06">steps:
</span><span style="color:#4e9a06">- echo &#34;foo=bar&#34; &gt; /foo
</span><span style="color:#4e9a06">EOF</span>
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package/definition.yaml
</span><span style="color:#4e9a06">name: &#34;foo&#34;
</span><span style="color:#4e9a06">version: &#34;0.1&#34;
</span><span style="color:#4e9a06">category: &#34;bar&#34;
</span><span style="color:#4e9a06">EOF</span>
</code></pre></div><p>To build it, simply run <code>luet build bar/foo</code> or <code>luet build --all</code> to build all the packages in the current directory:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet build --all
📦 Selecting foo 0.1
📦 Compiling foo version 0.1 .... ☕
🐋 Downloading image luet/cache-foo-bar-0.1-builder
🐋 Downloading image luet/cache-foo-bar-0.1
📦 foo Generating 🐋 definition <span style="color:#204a87;font-weight:bold">for</span> builder image from busybox
🐋 Building image luet/cache-foo-bar-0.1-builder
🐋 Building image luet/cache-foo-bar-0.1-builder <span style="color:#204a87;font-weight:bold">done</span>
Sending build context to Docker daemon 4.096kB
...
</code></pre></div><p>Luet &ldquo;trees&rdquo; are just a group of specfiles, in the above example, our tree was the current directory. You can also specify a directory with the <code>--tree</code> option. Luet doesn&rsquo;t enforce any tree layout, so they can be nested at any level. The only rule of thumb is that a <code>build.yaml</code> file needs to have either a <code>definition.yaml</code> or a <code>collection.yaml</code> file next to it.</p>
<h2 id="nesting-dependencies">Nesting dependencies</h2>
<p>In the example above we have created a package from a <code>delta</code>. Luet by default creates packages by analyzing the differences between the generated containers, and extracts the differences as archive, the resulting files then are compressed and can be consumed later on by <code>luet install</code>.</p>
<p>Luet can create packages from different <a href="/docs/docs/concepts/packages/specfile/#building-strategies">building strategies</a>: by delta, by taking a whole container content, or by considering a single directory in the build container.</p>
<p>Besides that, <a href="/docs/docs/concepts/packages/specfile/#build-time-dependencies">a package can reference a strict dependency on others</a>.</p>
<h3 id="example-1">Example</h3>
<p>Let&rsquo;s extend the above example with two packages which depends on it during the build phase.</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">
$~/workdir&gt; mkdir package2
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package2/build.yaml
</span><span style="color:#4e9a06">requires:
</span><span style="color:#4e9a06">- name: &#34;foo&#34;
</span><span style="color:#4e9a06"> category: &#34;bar&#34;
</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34;
</span><span style="color:#4e9a06">
</span><span style="color:#4e9a06">steps:
</span><span style="color:#4e9a06">- source /foo &amp;&amp; echo &#34;$foo&#34; &gt; /bar
</span><span style="color:#4e9a06">EOF</span>
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package2/definition.yaml
</span><span style="color:#4e9a06">name: &#34;ineedfoo&#34;
</span><span style="color:#4e9a06">version: &#34;0.1&#34;
</span><span style="color:#4e9a06">category: &#34;bar&#34;
</span><span style="color:#4e9a06">EOF</span>
$~/workdir&gt; mkdir package3
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package3/build.yaml
</span><span style="color:#4e9a06">requires:
</span><span style="color:#4e9a06">- name: &#34;foo&#34;
</span><span style="color:#4e9a06"> category: &#34;bar&#34;
</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34;
</span><span style="color:#4e9a06">- name: &#34;ineedfoo&#34;
</span><span style="color:#4e9a06"> category: &#34;bar&#34;
</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34;
</span><span style="color:#4e9a06">
</span><span style="color:#4e9a06">steps:
</span><span style="color:#4e9a06">- source /foo &amp;&amp; echo &#34;$foo&#34; &gt; /ineedboth
</span><span style="color:#4e9a06">- cat /bar &gt; /bar
</span><span style="color:#4e9a06">
</span><span style="color:#4e9a06">EOF</span>
$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package3/definition.yaml
</span><span style="color:#4e9a06">name: &#34;ineedfooandbar&#34;
</span><span style="color:#4e9a06">version: &#34;0.1&#34;
</span><span style="color:#4e9a06">category: &#34;bar&#34;
</span><span style="color:#4e9a06">EOF</span>
</code></pre></div><p>To build, run again:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet build --all
</code></pre></div><p>As we can see, now Luet generated 3 packages, <code>bar/foo</code>, <code>bar/ineedfoo</code> and <code>bar/ineedfooandbar</code>. They aren&rsquo;t doing anything special than just shipping text files, this is an illustrative example on how build requirements can be combined to form new packages:</p>
<p><code>bar/ineedfooandbar</code> depends on both <code>bar/ineedfoo</code> and <code>bar/foo</code> during build-time, while <code>bar/foo</code> uses a docker image as a build base.</p>
<p>See the <a href="/docs/docs/concepts/packages/specfile/#building-strategies">package definition documentation page</a> for more details on how to instruct the Luet compiler to build packages with different strategies.</p>
<h2 id="caching-docker-images">Caching docker images</h2>
<p>Luet can push and pull the docker images that are being generated during the build process. A tree is represented by a single docker image, and each package can have one or more tags attached to it.</p>
<p>To push automatically docker images that are built, use the <code>--push</code> option, to pull, use the <code>--pull</code> option. An image repository can be specified with <code>--image-repository</code> flag, and can include also the remote registries where the images are pushed to.</p>
<p>Luet doesn&rsquo;t handle login to registries, so that has to be handled separately with <code>docker login</code> or <code>img login</code> before the build process starts.</p>
<h3 id="build-faster">Build faster</h3>
<p>When packages are cached, for iterating locally it&rsquo;s particularly useful to jump straight to the image that you want to build. You can use <code>--only-target-package</code> to jump directly to the image you are interested in. Luet will take care of checking if the images are present in the remote registry, and would build them if any of those are missing.</p>
<h2 id="building-for-a-different-platform">Building for a different platform</h2>
<p>Sometimes you need to build a package for a different platform than the one running on your host machine. For example, you may want to build an arm64 package, but your machine is x86. To do this, all you need to do is pass the following arguments:</p>
<pre tabindex="0"><code>luet --backend-args --load --backend-args --platform --backend-args linux/arm64 build PACKAGE_NAME
</code></pre><h2 id="notes">Notes</h2>
<ul>
<li>All the files which are next to a <code>build.yaml</code> are copied in the container which is running your build, so they are always accessible during build time.</li>
<li>If you notice errors about disk space, mind to set the <code>TMPDIR</code> env variable to a different folder. By default luet respects the O.S. default (which in the majority of system is <code>/tmp</code>).</li>
</ul>
<style>
.feedback--answer {
display: inline-block;
}
.feedback--answer-no {
margin-left: 1em;
}
.feedback--response {
display: none;
margin-top: 1em;
}
.feedback--response__visible {
display: block;
}
</style>
<div class="d-print-none">
<h2 class="feedback--title">Feedback</h2>
<p class="feedback--question">Was this page helpful?</p>
<button class="btn btn-primary mb-4 feedback--answer feedback--answer-yes">Yes</button>
<button class="btn btn-primary mb-4 feedback--answer feedback--answer-no">No</button>
<p class="feedback--response feedback--response-yes">
Glad to hear it! Please <a href="https://github.com/Luet-lab/docs/issues/new">tell us how we can improve</a>.
</p>
<p class="feedback--response feedback--response-no">
Sorry to hear that. Please <a href="https://github.com/Luet-lab/docs/issues/new">tell us how we can improve</a>.
</p>
</div>
<script>
const yesButton = document.querySelector('.feedback--answer-yes');
const noButton = document.querySelector('.feedback--answer-no');
const yesResponse = document.querySelector('.feedback--response-yes');
const noResponse = document.querySelector('.feedback--response-no');
const disableButtons = () => {
yesButton.disabled = true;
noButton.disabled = true;
};
const sendFeedback = (value) => {
if (typeof ga !== 'function') return;
const args = {
command: 'send',
hitType: 'event',
category: 'Helpful',
action: 'click',
label: window.location.pathname,
value: value
};
ga(args.command, args.hitType, args.category, args.action, args.label, args.value);
};
yesButton.addEventListener('click', () => {
yesResponse.classList.add('feedback--response__visible');
disableButtons();
sendFeedback(1);
});
noButton.addEventListener('click', () => {
noResponse.classList.add('feedback--response__visible');
disableButtons();
sendFeedback(0);
});
</script>
<br />
<div class="text-muted mt-5 pt-3 border-top">
Last modified June 24, 2024: <a href="https://github.com/mudler/luet/commit/1712988ecc04f1a80ee256d68b25e64abbf41d04">Update goreleaser command (1712988)</a>
</div>
</div>
</main>
</div>
</div>
<footer class="bg-dark py-5 row d-print-none">
<div class="container-fluid mx-sm-5">
<div class="row">
<div class="col-6 col-sm-4 text-xs-center order-sm-2">
</div>
<div class="col-6 col-sm-4 text-right text-xs-center order-sm-3">
<ul class="list-inline mb-0">
<li class="list-inline-item mx-2 h3" data-toggle="tooltip" data-placement="top" title="GitHub" aria-label="GitHub">
<a class="text-white" target="_blank" rel="noopener" href="https://github.com/mudler/luet" aria-label="GitHub">
<i class="fab fa-github"></i>
</a>
</li>
<li class="list-inline-item mx-2 h3" data-toggle="tooltip" data-placement="top" title="Slack" aria-label="Slack">
<a class="text-white" target="_blank" rel="noopener" href="https://join.slack.com/t/luet/shared_invite/enQtOTQxMjcyNDQ0MDUxLWQ5ODVlNTI1MTYzNDRkYzkyYmM1YWE5YjM0NTliNDEzNmQwMTkxNDRhNDIzM2Y5NDBlOTZjZTYxYWQyNDE4YzY" aria-label="Slack">
<i class="fab fa-slack"></i>
</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 text-center py-2 order-sm-2">
<small class="text-white">&copy; 2024 Ettore Di Giacinto All Rights Reserved</small>
<small class="ml-1"><a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a></small>
<p class="mt-2"><a href="/about/">About Luet</a></p>
</div>
</div>
</div>
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"
integrity="sha512-UR25UO94eTnCVwjbXozyeVd6ZqpaAE9naiEUBK/A+QDbfSTQFhPGj5lOR6d8tsgbBk84Ggb5A3EkjsOgPRPcKA=="
crossorigin="anonymous"></script>
<script src='/js/tabpane-persist.js'></script>
<script src="/js/main.min.8ab8f81ff7e1454d30024cd6f956d4d341c3a97e2a673f988065f2ee4e147922.js" integrity="sha256-irj4H/fhRU0wAkzW&#43;VbU00HDqX4qZz&#43;YgGXy7k4UeSI=" crossorigin="anonymous"></script>
</body>
</html>