{"id":8950,"date":"2019-04-03T00:03:04","date_gmt":"2019-04-02T22:03:04","guid":{"rendered":"https:\/\/pi3g.com\/?p=8950"},"modified":"2019-04-03T00:03:04","modified_gmt":"2019-04-02T22:03:04","slug":"creating-a-raspbian-repository","status":"publish","type":"post","link":"https:\/\/pi3g.com\/de\/creating-a-raspbian-repository\/","title":{"rendered":"Erstellen eines Raspbian-Repositorys"},"content":{"rendered":"<p>If you want to host your own Raspbian repository, this article is for you.<\/p>\n<p>A Raspbian repository consists of a special directory structure on a webserver. The files, including the packages, are all static \u2013 therefore this repository could also simply be hosted on an Amazon S3 instance, for example.<\/p>\n<h1>The sources.list entry in Raspbian<\/h1>\n<p><strong>\/etc\/apt\/sources.list<\/strong><\/p>\n<blockquote>\n<p>deb <a href=\"http:\/\/raspbian.raspberrypi.org\/raspbian\/\">http:\/\/raspbian.raspberrypi.org\/raspbian\/<\/a> stretch main contrib non-free rpi<\/p>\n<\/blockquote>\n<p><strong>\/etc\/apt\/sources.list.d\/raspi.list<\/strong><\/p>\n<blockquote>\n<p>deb <a href=\"http:\/\/archive.raspberrypi.org\/debian\/\">http:\/\/archive.raspberrypi.org\/debian\/<\/a> stretch main ui<\/p>\n<\/blockquote>\n<p><\/p>\n<p>These are the default entries for the package repositories on Raspbian.<\/p>\n<p>The structure is as follows:<\/p>\n<ul>\n<li>deb : source for binary packages<\/li>\n<li><a href=\"http:\/\/raspbian.raspberrypi.org\/raspbian\/\">http:\/\/raspbian.raspberrypi.org\/raspbian\/<\/a> : URL of the repository<\/li>\n<li>stretch : the \u201cdistribution\u201d \/ release \/ codename (in some cases also possible to specify subdirectories nested deeper, e.g. stretch\/updates)<\/li>\n<li>main contrib non-free rpi : the components you are interested in from this repository, separated by a space<\/li>\n<\/ul>\n<p>NB: apt starting from Debian \/ Raspbian Stretch includes support for https by default. Otherwise you would have to install the apt-transport-https package;<\/p>\n<p><a href=\"https:\/\/whydoesaptnotusehttps.com\/\" target=\"_blank\">Here\u2019s a webpage explaining why https is not necessary required for package installation<\/a>.<\/p>\n<p><\/p>\n<p><\/p>\n<h1>A repository directory structure<\/h1>\n<p>Have a look at the <a href=\"http:\/\/raspbian.raspberrypi.org\/\">http:\/\/raspbian.raspberrypi.org\/<\/a> repository directory structure:<\/p>\n<p><a href=\"http:\/\/raspbian.raspberrypi.org\/raspbian\/\">http:\/\/raspbian.raspberrypi.org\/<\/a><\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"635\" height=\"567\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb.png\" border=\"0\"><\/a><\/p>\n<p>This main directory contains several subdirectories, and notably the <strong>raspbian.public.key <\/strong><\/p>\n<p>Some of the subdirectories are for miscellaneous purposes, e.g. images \u2013 not necessary for a normal Debian \/ Raspbian Raspberry Pi repository.<\/p>\n<p>Of interest here are the <\/p>\n<ul>\n<li>mate<\/li>\n<li>raspbian<\/li>\n<\/ul>\n<p>subdirectories, and the already mentioned <strong>raspbian.public.key<\/strong>. <\/p>\n<p>The key is a text file, generated by GnuPG. Here\u2019s how it looks like:<\/p>\n<p><\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"571\" height=\"304\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-1.png\" border=\"0\"><\/a><\/p>\n<p>etc.<\/p>\n<p>This key is required to verify that you are indeed communicating with the right repository, which it claims to be. If you trust the repository, you add the key to your apt keyring (see for instructions how to add your own key and install packages from your own new repository below).<\/p>\n<p>Then it can be used by apt<strong> to verify the signatures of the APT repository metadata<\/strong>. The packages themselves are usually not GPG signed \/ not being verified. <a href=\"https:\/\/blog.packagecloud.io\/eng\/2014\/10\/28\/howto-gpg-sign-verify-deb-packages-apt-repositories\/\" target=\"_blank\">Refer to the packagecloud article for details<\/a>.<\/p>\n<h2>Repositories as subfolders<\/h2>\n<p>mate and raspbian are two different repositories (for the Raspberry Pi in this case). <\/p>\n<p>Please note: aptly \u2013 the tool to publish your own repository explained below &#8211; will default to the webroot, and will show the dists folder in the webroot, but you can also specify a path to publish under.<\/p>\n<p>We\u2019ll look at the raspbian folder, which for our purposes is one such repository:<\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"251\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-2.png\" border=\"0\"><\/a><\/p>\n<p><\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"588\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-3.png\" border=\"0\"><\/a><\/p>\n<p>The dists folder contains the releases \/ distributions of Raspbian \u2013 codenamed in sync with the Debian releases. The current stable \u2013 as of 2.4.2019 \u2013 being <strong>Stretch<\/strong>.<\/p>\n<p>They are named after Toy Story characters.&nbsp; The upcoming release is Buster.<\/p>\n<p>\u201c<strong>stable<\/strong>\u201d is identical to \u201cstretch\u201d (currently). It will point to the most recent stable release. <\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"532\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-4.png\" border=\"0\"><\/a><\/p>\n<p>This directory contains several files required for the functioning of apt tools. Notably the InRelease, Release and Release.gpg files.<\/p>\n<ul>\n<li>InRelease: signed in-line<\/li>\n<li>Release \u2013 goes along with Release.gpg (signature)<\/li>\n<\/ul>\n<p>these files list the index files for the distribution and their hashes. <\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-5.png\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"393\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-5.png\" border=\"0\"><\/a><\/p>\n<p>\u2026<\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"652\" height=\"228\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-6.png\" border=\"0\"><\/a><\/p>\n<p><em>an example InRelease file, with the inline signature at the bottom.<\/em><\/p>\n<p>It is like a kind of map for apt \u2013 where the Package listing files can be found, and in which formats ( .gz and .xz being compressed formats) they can be downloaded.<\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-7.png\"><img loading=\"lazy\" decoding=\"async\" width=\"655\" height=\"240\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-7.png\" border=\"0\"><\/a><\/p>\n<p>Here lives the metadata for the packages. The file Packages is human-readable (but very long).<\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"654\" height=\"329\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-8.png\" border=\"0\"><\/a><\/p>\n<p>notably this file contains a link to the \u201cpool\u201d, for the actual package. <\/p>\n<pre>Filename: pool\/rpi\/g\/gst-omx1.0\/gstreamer1.0-omx_1.0.0.1-0+rpi12+jessiepmg_armhf.deb<\/pre>\n<pre><font face=\"Calibri\">rpi is the name of the component, and the packages are further split up by first letter.<\/font><\/pre>\n<pre><font face=\"Calibri\"><br><\/font><\/pre>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-9.png\"><img loading=\"lazy\" decoding=\"async\" width=\"660\" height=\"327\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-9.png\" border=\"0\"><\/a><\/p>\n<p>the <strong>pool <\/strong>directory is used to avoid duplication of packages. <\/p>\n<p>Look at <a href=\"https:\/\/wiki.debian.org\/DebianRepository\/Format\">this informative site<\/a> for more information about the Debian Repository Format: <\/p>\n<p><a href=\"https:\/\/wiki.debian.org\/DebianRepository\/Format\">https:\/\/wiki.debian.org\/DebianRepository\/Format<\/a><\/p>\n<p><\/p>\n<h1>Using aptly \u2013 publishing your own repository, with your own packages<\/h1>\n<p>Aptly is a tool for easily setting up and publishing your own .deb Repository \u2013 for Debian and it\u2019s siblings and cousins.<\/p>\n<p>This includes Ubuntu, but of course also Raspbian.<\/p>\n<p>So, if you want to publish a Raspbian repository, this is how you do it.<\/p>\n<h2>Set up a Docker container <\/h2>\n<p>I have created a Docker container, based on this git repository:<\/p>\n<p><a href=\"https:\/\/github.com\/urpylka\/docker-aptly\">https:\/\/github.com\/urpylka\/docker-aptly<\/a><\/p>\n<p>changes I have introduced:<\/p>\n<ul>\n<li>FROM ubuntu:bionic<\/li>\n<li>gnupg1<\/li>\n<li>gpgv1<\/li>\n<li>gpg command run explicitly as gpg1 (otherwise the public and private keys will be saved differently, and everything will not work as expected)<\/li>\n<\/ul>\n<p>Therefore there will be some additional explaining below. On the whole urpylka\u2019s script is a very convenient starting point, if you want to run on Docker. <\/p>\n<p>Furthermore, I strongly recommend you to use docker-compose, instead of running those long docker run commands manually. <\/p>\n<h2>Here\u2019s my dockerfile for your reference<\/h2>\n<blockquote>\n<p># Copyright 2019 Maximilian Batz<br \/>\n# Copyright 2018 Artem B. Smirnov<br \/>\n# Copyright 2018 Jon Azpiazu<br \/>\n# Copyright 2016 Bryan J. Hong<br \/>\n#<br \/>\n# Licensed under the Apache License, Version 2.0 (the &#8220;License&#8221;);<br \/>\n# you may not use this file except in compliance with the License.<br \/>\n# You may obtain a copy of the License at<br \/>\n#<br \/>\n#&nbsp;&nbsp;&nbsp;&nbsp; <a href=\"http:\/\/www.apache.org\/licenses\/LICENSE-2.0\">http:\/\/www.apache.org\/licenses\/LICENSE-2.0<\/a><br \/>\n#<br \/>\n# Unless required by applicable law or agreed to in writing, software<br \/>\n# distributed under the License is distributed on an &#8220;AS IS&#8221; BASIS,<br \/>\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br \/>\n# See the License for the specific language governing permissions and<br \/>\n# limitations under the License.<\/p>\n<p>FROM ubuntu:bionic<\/p>\n<p>LABEL maintainer=&#8221;&lt;deleted to protect from spam&gt;&#8221;<\/p>\n<p>ENV DEBIAN_FRONTEND noninteractive<\/p>\n<p>RUN apt-get -q update \\<br \/>&nbsp;&nbsp; &amp;&amp; apt-get -y install \\<br \/>&nbsp;&nbsp; gnupg1 &amp;&amp; apt-key adv &#8211;keyserver pool.sks-keyservers.net &#8211;recv-keys ED75B5A4483DA07C \\<br \/>&nbsp;&nbsp; &amp;&amp; echo &#8220;deb <a href=\"http:\/\/repo.aptly.info\/\">http:\/\/repo.aptly.info\/<\/a> squeeze main&#8221; &gt;&gt; \/etc\/apt\/sources.list<\/p>\n<p># Update APT repository &amp; install packages<br \/>\nRUN apt-get -q update \\<br \/>&nbsp;&nbsp; &amp;&amp; apt-get -y install \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; aptly=1.3.0 \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; bzip2 \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; gpgv1 \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; graphviz \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; supervisor \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; nginx \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; wget \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; xz-utils \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp; apt-utils \\<br \/>&nbsp;&nbsp; &amp;&amp; apt-get clean \\<br \/>&nbsp;&nbsp; &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*<\/p>\n<p># Install Aptly Configuration<br \/>\nCOPY assets\/aptly.conf \/etc\/aptly.conf<\/p>\n<p># Install scripts<br \/>\nCOPY assets\/*.sh \/opt\/<\/p>\n<p># Install Nginx Config<br \/>\nRUN rm \/etc\/nginx\/sites-enabled\/*<br \/>\nCOPY assets\/supervisord.nginx.conf \/etc\/supervisor\/conf.d\/nginx.conf<br \/>\nRUN echo &#8220;daemon off;&#8221; &gt;&gt; \/etc\/nginx\/nginx.conf<\/p>\n<p># Bind mount location<br \/>\nVOLUME [ &#8220;\/opt\/aptly&#8221; ]<\/p>\n<p># Execute Startup script when container starts<br \/>\nENTRYPOINT [ &#8220;\/opt\/startup.sh&#8221; ]<\/p>\n<\/blockquote>\n<p>Note, as of 2.4.2019, aptly 1.3.0 is still the most recent version.<\/p>\n<blockquote><p>\n<\/p><\/blockquote>\n<h2>Connecting to the aptly container<\/h2>\n<blockquote>\n<p>docker exec \u2013it aptly \/bin\/bash<\/p>\n<\/blockquote>\n<p>Your container being named aptly in this case, opens an interactive terminal with \/bin\/bash. All the other commands are executed inside the container.<\/p>\n<h2>Generating the GPG keys<\/h2>\n<p>The docker script mentioned above automatically creates GPG keys for you, by passing in your passphrase into a file in the container. The relevant script snippet is this:<\/p>\n<blockquote>\n<p>#! \/usr\/bin\/env bash<\/p>\n<p># Copyright 2016 Bryan J. Hong<br \/>\n# Licensed under the Apache License, Version 2.0<\/p>\n<p>cat &lt;&lt; EOF &gt; \/opt\/gpg_batch<br \/>\n%echo Generating a GPG key, might take a while<br \/>\nKey-Type: RSA<br \/>\nKey-Length: 4096<br \/>\nSubkey-Type: ELG-E<br \/>\nSubkey-Length: 1024<br \/>\nName-Real: ${FULL_NAME}<br \/>\nName-Comment: Aptly Repo Signing<br \/>\nName-Email: ${EMAIL_ADDRESS}<br \/>\nExpire-Date: 0<br \/>\nPassphrase: ${GPG_PASSWORD}<br \/>\n%pubring \/opt\/aptly\/aptly.pub<br \/>\n%secring \/opt\/aptly\/aptly.sec <br \/>\n%commit<br \/>\n%echo done<br \/>\nEOF<\/p>\n<\/blockquote>\n<p>This is run if the keys do not exist, from the entrypoint of the container:<\/p>\n<blockquote>\n<p># If the repository GPG keypair doesn&#8217;t exist, create it.<br \/>\nif [[ ! -f \/opt\/aptly\/aptly.sec ]] || [[ ! -f \/opt\/aptly\/aptly.pub ]]; then<br \/>&nbsp;&nbsp; echo &#8220;Generating new gpg keys&#8221;<br \/>&nbsp;&nbsp; cp -a \/dev\/urandom \/dev\/random<br \/>&nbsp;&nbsp; \/opt\/gpg_batch.sh<br \/>&nbsp;&nbsp; # If your system doesn&#8217;t have a lot of entropy this may, take a long time<br \/>&nbsp;&nbsp; # Google how-to create &#8220;artificial&#8221; entropy if this gets stuck<br \/>&nbsp;&nbsp; gpg1 &#8211;batch &#8211;gen-key \/opt\/gpg_batch<br \/>\nelse<br \/>&nbsp;&nbsp; echo &#8220;No need to generate new gpg keys&#8221;<br \/>\nfi<\/p>\n<p><\/p>\n<\/blockquote>\n<p>Note my \u201cimproved\u201d version (gpg1 instead of just gpg being specified) \u2013 this seems to be necessary for Ubuntu bionic beaver, as otherwise you will get gpg 2 as default.<\/p>\n<p>Note: this file will contain your passphrase! Therefore I recommend to remove it after the initial setup has been completed.<\/p>\n<p><strong>Unfortunately, gpg1 does NOT seem to support the %ask-passphrase control. <\/strong>Therefore, if you want to do batch generation of the keys, the key password needs to be in the batch file.<\/p>\n<p><\/p>\n<h2>Publish \/ export the GPG public key<\/h2>\n<blockquote>\n<p>mkdir -p \/opt\/aptly\/public<\/p>\n<p>gpg1 &#8211;export &#8211;armor &gt; \/opt\/aptly\/public\/repository.picockpit.key<\/p>\n<\/blockquote>\n<p>name the key appropriately. &#8211;armor&nbsp; is used to export the key in an ASCII format (as opposed to binary).<\/p>\n<p>note these are two dashes, I hope WordPress doesn\u2019t destroy them. Also, here gpg1 is used instead of just gpg<\/p>\n<p><\/p>\n<h2>Create a new repository<\/h2>\n<blockquote>\n<p>aptly repo create -comment=&#8221;picockpit.com Repository&#8221; -component=&#8221;main&#8221; -distribution=&#8221;stretch&#8221; pcp-repository<\/p>\n<\/blockquote>\n<p>Creates a new local repository, into which you can add packages. This repository is not published yet. <\/p>\n<p>-comment : text to describe the local repository<\/p>\n<p>-component: default component when publishing<\/p>\n<p>-distribution: default distribution (release) when publishing<\/p>\n<p>pcp-repository: this is a custom name I have given to this local repository, you can use your own here. Be sure to modify the other commands accordingly and use the name you choose here.<\/p>\n<h2>Add .deb packages to the repository<\/h2>\n<blockquote>\n<p>aptly repo add pcp-repository \/opt\/aptly\/testpackage\/<\/p>\n<\/blockquote>\n<p>Here I am adding a folder of packages to the local repository I created in the step before. aptly will acknowledge the added packages, like this:<\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1089\" height=\"81\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-10.png\" border=\"0\"><\/a><\/p>\n<p><\/p>\n<h2>Create snapshot<\/h2>\n<p>While it is possible to publish a repo directly, it is strongly recommended to create a snapshot, and publish the snapshot.<\/p>\n<blockquote>\n<p>aptly snapshot create pcp-snapshot from repo pcp-repository<\/p>\n<\/blockquote>\n<p>pcp-snapshot being a custom name, and pcp-repository the name you gave to the repository further above.<\/p>\n<p><\/p>\n<h2>Publish snapshot<\/h2>\n<blockquote>\n<p>aptly publish snapshot pcp-snapshot<\/p>\n<\/blockquote>\n<p>During the publishing of the snapshot, you will be prompted for your gpg passphrase two times:<\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-11.png\"><img loading=\"lazy\" decoding=\"async\" width=\"938\" height=\"526\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-11.png\" border=\"0\"><\/a><\/p>\n<p>aptly will publish to the directory \/opt\/aptly\/public, which Nginx or another webserver of your choice will serve from. No need for <\/p>\n<p>Also refer to this documentation:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.aptly.info\/doc\/aptly\/publish\/snapshot\/\">https:\/\/www.aptly.info\/doc\/aptly\/publish\/snapshot\/<\/a><\/li>\n<\/ul>\n<h2>Switch published repository<\/h2>\n<p>If you have made a mistake, and would like to switch out the published repository to a different snapshot, you can use aptly publish switch:<\/p>\n<blockquote>\n<p>aptly publish switch stretch raspbian pcp-snapshot<\/p>\n<\/blockquote>\n<p>This will switch the distribution stretch, under the path raspbian, with the new snapshot pcp-snapshot.<\/p>\n<ul>\n<li><a href=\"https:\/\/www.aptly.info\/doc\/aptly\/publish\/switch\/\">https:\/\/www.aptly.info\/doc\/aptly\/publish\/switch\/<\/a><\/li>\n<\/ul>\n<h1>Adding your repository to a system<\/h1>\n<h2>Import the key<\/h2>\n<blockquote>\n<p>curl -L <a href=\"http:\/\/192.168.1.2:3200\/repository.picockpit.key\">http:\/\/192.168.1.2:3200\/repository.picockpit.key<\/a> | sudo apt-key add &#8211;<\/p>\n<\/blockquote>\n<p>The command fetches the key using curl, and then pipes it into apt-key. There is also an apt-key key fetching functionality, but it depends on a package which is not installed on Raspbian by default. <\/p>\n<p>If you do not do this, apt will not be able to fetch packages from the new repository, and will throw errors!<\/p>\n<h2>Add the repository<\/h2>\n<blockquote>\n<p>echo &#8220;deb <a href=\"http:\/\/192.168.1.2:3200\/raspbian\">http:\/\/192.168.1.2:3200\/raspbian<\/a> stretch main&#8221; | sudo tee &#8211;append \/etc\/apt\/sources.list.d\/picockpit.list<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-12.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1036\" height=\"38\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-12.png\" border=\"0\"><\/a><\/p>\n<p>The subdirectory under \/etc\/apt\/sources.list.d is only writable by root. the &#8211;append ensures that the file is not overwritten, if it should exist already.<\/p>\n<p>It would also be possible to create the file manually, and e.g. using nano, add the line <\/p>\n<blockquote>\n<p>deb <a href=\"http:\/\/192.168.1.2:3200\/raspbian\">http:\/\/192.168.1.2:3200\/raspbian<\/a> stretch main<\/p>\n<\/blockquote>\n<h2>Install packages<\/h2>\n<blockquote>\n<p>sudo apt-get update<\/p>\n<p>sudo apt-get install <em>packagename<\/em><\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-13.png\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"154\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-13.png\" border=\"0\"><\/a><\/p>\n<p><em>This screenshot shows that apt is reading the new repository as well.<\/em><\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image-14.png\"><img loading=\"lazy\" decoding=\"async\" width=\"776\" height=\"294\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/04\/image_thumb-14.png\" border=\"0\"><\/a><\/p>\n<p><em>installing a sample package.<\/em> <\/p>\n<h1>Creating a package<\/h1>\n<p><a href=\"http:\/\/dbalakirev.github.io\/2015\/08\/21\/deb-pkg\/\">I refer you to this excellent article how to create a Debian package.<\/a> <\/p>\n<p>Only be sure to change Architecture to <strong>armhf <\/strong>for the Raspberry Pi platform.<\/p>\n<h1>Need professional support?<\/h1>\n<p><a href=\"http:\/\/pi3g.com\/kontakt\">We do all things Raspberry Pi for a living. Get in touch, if you need professional support with your setup.<\/a><\/p>\n<p>We currently charge a flat 1500 \u20ac daily rate (+taxes). We\u2019ll be glad to help you \ud83d\ude42<\/p>\n<h1>Further readling<\/h1>\n<ul>\n<li><a href=\"https:\/\/blog.packagecloud.io\/eng\/2014\/10\/28\/howto-gpg-sign-verify-deb-packages-apt-repositories\/\">https:\/\/blog.packagecloud.io\/eng\/2014\/10\/28\/howto-gpg-sign-verify-deb-packages-apt-repositories\/<\/a><\/li>\n<li><a href=\"https:\/\/wiki.debian.org\/DebianRepository\/Format\">https:\/\/wiki.debian.org\/DebianRepository\/Format<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/urpylka\/docker-aptly\">https:\/\/github.com\/urpylka\/docker-aptly<\/a><\/li>\n<\/ul>\n<p><strong>About packages:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/www.debian.org\/doc\/debian-policy\/ch-controlfields.html\">https:\/\/www.debian.org\/doc\/debian-policy\/ch-controlfields.html<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Wenn Sie Ihr eigenes Raspbian-Repository hosten wollen, ist dieser Artikel f\u00fcr Sie. Ein Raspbian Repository besteht aus einer speziellen Verzeichnisstruktur auf einem Webserver. Die Dateien, einschlie\u00dflich der Pakete, sind alle statisch - daher k\u00f6nnte dieses Repository auch einfach auf einer Amazon S3-Instanz gehostet werden. Der sources.list Eintrag in Raspbian...<\/p>","protected":false},"author":830,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1,452],"tags":[555,548,551,553,427,549,556,554,558,552,422,546,469,557,547,550],"class_list":["post-8950","post","type-post","status-publish","format-standard","hentry","category-raspberrypi-blog","category-tips-tricks","tag-aptly","tag-bionic","tag-buster","tag-deb","tag-debian","tag-jessie","tag-key","tag-package-repository","tag-package-sign","tag-packages","tag-raspbian","tag-repo","tag-repository","tag-signing","tag-snapper","tag-stretch"],"_links":{"self":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/8950","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/users\/830"}],"replies":[{"embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/comments?post=8950"}],"version-history":[{"count":1,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/8950\/revisions"}],"predecessor-version":[{"id":8951,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/8950\/revisions\/8951"}],"wp:attachment":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/media?parent=8950"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/categories?post=8950"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/tags?post=8950"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}