push
This commit is contained in:
commit
3669643452
23
Dockerfile
Normal file
23
Dockerfile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
gnupg \
|
||||||
|
dpkg-dev \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
|
|
||||||
|
COPY app/. .
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir gunicorn flask
|
||||||
|
|
||||||
|
RUN chmod +x entrypoint.sh
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["./entrypoint.sh"]
|
||||||
88
README.md
Normal file
88
README.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# APT DEPOT
|
||||||
|
|
||||||
|
Créer un dépôt Debian sécurisé via clé GPG pour héberger des paquets
|
||||||
|
|
||||||
|
## CONFIGURATION
|
||||||
|
|
||||||
|
- Editer le fichier `app/entrypoint.sh`
|
||||||
|
```sh
|
||||||
|
GPG_KEY_NAME="example"
|
||||||
|
...
|
||||||
|
EMAIL="test@exemple.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
- Changer le port `- 8000:` dans le `compose.yml` si besoin
|
||||||
|
|
||||||
|
- Metre les paquets dans le dossier `depot/`
|
||||||
|
|
||||||
|
## UTILISATION
|
||||||
|
|
||||||
|
- Démarrer le conteneur
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: La première fois, il génère les clés GPG
|
||||||
|
|
||||||
|
:bulb: **A chaque ajout de paquet, redémarrer le conteneur pour qu'il resigne les paquets avec la clé GPG**
|
||||||
|
|
||||||
|
#### Utiliser le dépôt pour installer des paquets
|
||||||
|
|
||||||
|
- Ajouter la clé du dépôt ainsi que l'adresse dans les sources:
|
||||||
|
```bash
|
||||||
|
sudo wget -O /etc/apt/trusted.gpg.d/gn-depot.asc https://deb.legaragenumerique.fr/pgp-key.public
|
||||||
|
|
||||||
|
echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/gn-depot.asc] https://deb.legaragenumerique.fr stable main' \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/gn-depot.list
|
||||||
|
```
|
||||||
|
|
||||||
|
- Mettre à jour les dépôts:
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
```
|
||||||
|
|
||||||
|
- Installer un paquet:
|
||||||
|
```bash
|
||||||
|
sudo apt install geo -y
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Création d'un paquet
|
||||||
|
|
||||||
|
- Structure d'un paquet Debian:
|
||||||
|
```
|
||||||
|
paquet/
|
||||||
|
├── DEBIAN
|
||||||
|
│ ├── control -> description du paquet
|
||||||
|
│ ├── postinst -> script s'éxécutant après l'installation du paquet
|
||||||
|
│ └── prerm -> script s'éxécutant avant la désinstallation du paquet
|
||||||
|
└── usr
|
||||||
|
├── bin
|
||||||
|
│ └── mon-binaire
|
||||||
|
└── share
|
||||||
|
└── applications
|
||||||
|
└── application.desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
- Builder le paquet:
|
||||||
|
```bash
|
||||||
|
dpkg-deb --build paquet
|
||||||
|
```
|
||||||
|
|
||||||
|
> Output: paquet.deb
|
||||||
|
|
||||||
|
#### Ajout d'un paquet au dépôt
|
||||||
|
|
||||||
|
- Renommer le paquet:
|
||||||
|
```bash
|
||||||
|
mv geo.deb geo_amd64.deb
|
||||||
|
```
|
||||||
|
|
||||||
|
- Placer le paquet dans le dossier `depot/`:
|
||||||
|
```bash
|
||||||
|
mv geo_amd64.deb depot/
|
||||||
|
```
|
||||||
|
|
||||||
|
- Redémarrer le conteneur:
|
||||||
|
```bash
|
||||||
|
docker compose down -v && docker compose up -d
|
||||||
|
```
|
||||||
68
app/entrypoint.sh
Normal file
68
app/entrypoint.sh
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
GPG_KEY_NAME="example"
|
||||||
|
KEY_PUBLIC="/workspace/apt-repo/pgp-key.public"
|
||||||
|
KEY_PRIVATE="/workspace/secret/pgp-key.private"
|
||||||
|
EMAIL="test@exemple.com"
|
||||||
|
|
||||||
|
echo "📦 Création du dépôt APT"
|
||||||
|
mkdir -p ./apt-repo/pool/main/binary-amd64
|
||||||
|
mkdir -p ./apt-repo/dists/stable/main/binary-amd64
|
||||||
|
|
||||||
|
# Génération des clés seulement si elles n'existent pas
|
||||||
|
make_keys() {
|
||||||
|
echo "🔐 Génération des clés GPG"
|
||||||
|
cat > example-pgp-key.batch <<EOF
|
||||||
|
Key-Type: RSA
|
||||||
|
Key-Length: 4096
|
||||||
|
Name-Real: $GPG_KEY_NAME
|
||||||
|
Name-Email: $EMAIL
|
||||||
|
Expire-Date: 0
|
||||||
|
%no-ask-passphrase
|
||||||
|
%no-protection
|
||||||
|
%commit
|
||||||
|
EOF
|
||||||
|
|
||||||
|
gpg --batch --gen-key example-pgp-key.batch
|
||||||
|
gpg --armor --export "$GPG_KEY_NAME" > "$KEY_PUBLIC"
|
||||||
|
gpg --armor --export-secret-keys "$GPG_KEY_NAME" > "$KEY_PRIVATE"
|
||||||
|
chmod 600 $KEY_PRIVATE
|
||||||
|
cp "$KEY_PUBLIC" ./apt-repo/pgp-key.public
|
||||||
|
}
|
||||||
|
|
||||||
|
sign_packages() {
|
||||||
|
cd ./apt-repo
|
||||||
|
dpkg-scanpackages --arch amd64 pool/ > dists/stable/main/binary-amd64/Packages
|
||||||
|
gzip -9 < dists/stable/main/binary-amd64/Packages > dists/stable/main/binary-amd64/Packages.gz
|
||||||
|
|
||||||
|
cd dists/stable
|
||||||
|
gpg --import /workspace/secret/pgp-key.private
|
||||||
|
|
||||||
|
echo "⚙️ Génération de Release"
|
||||||
|
/workspace/generate-release.sh > Release
|
||||||
|
|
||||||
|
echo "🔏 Signature du Release"
|
||||||
|
gpg --default-key "$GPG_KEY_NAME" -abs < Release > Release.gpg
|
||||||
|
gpg --default-key "$GPG_KEY_NAME" --clearsign < Release > InRelease
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ ! -f "$KEY_PUBLIC" ]; then
|
||||||
|
make_keys
|
||||||
|
else
|
||||||
|
echo "✅ Clés GPG déjà présentes, génération ignorée"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🚚 Copie des paquets"
|
||||||
|
cp ./depot/* ./apt-repo/pool/main/binary-amd64/ || true
|
||||||
|
|
||||||
|
sign_packages
|
||||||
|
|
||||||
|
# Lancement serveur
|
||||||
|
echo "🚀 Lancement du serveur Gunicorn"
|
||||||
|
cd /workspace
|
||||||
|
cp index.html logo.png apt-repo/
|
||||||
|
gunicorn -b 0.0.0.0:8000 server:app
|
||||||
|
echo "📡 Dépôt APT disponible sur https://votre-domaine.tld"
|
||||||
|
echo "🔑 Clé publique disponible sur https://votre-domaine.tld/pgp-key.public"
|
||||||
31
app/generate-release.sh
Executable file
31
app/generate-release.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
do_hash() {
|
||||||
|
HASH_NAME=$1
|
||||||
|
HASH_CMD=$2
|
||||||
|
echo "${HASH_NAME}:"
|
||||||
|
for f in $(find -type f); do
|
||||||
|
f=$(echo $f | cut -c3-) # remove ./ prefix
|
||||||
|
if [ "$f" = "Release" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo " $(${HASH_CMD} ${f} | cut -d" " -f1) $(wc -c $f)"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cat << EOF
|
||||||
|
Origin: Example Repository
|
||||||
|
Label: Example
|
||||||
|
Suite: stable
|
||||||
|
Codename: stable
|
||||||
|
Version: 1.0
|
||||||
|
Architectures: amd64 arm64 arm7
|
||||||
|
Components: main
|
||||||
|
Description: An example software repository
|
||||||
|
Date: $(date -Ru)
|
||||||
|
EOF
|
||||||
|
do_hash "MD5Sum" "md5sum"
|
||||||
|
do_hash "SHA1" "sha1sum"
|
||||||
|
do_hash "SHA256" "sha256sum"
|
||||||
|
|
||||||
63
app/index.html
Normal file
63
app/index.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Dépôt APT - Le Garage Numérique</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
color: #333;
|
||||||
|
margin: 2em;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: auto;
|
||||||
|
background: #fff;
|
||||||
|
padding: 2em;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
img.logo {
|
||||||
|
max-width: 200px;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto 2em;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background: #f4f4f4;
|
||||||
|
padding: 1em;
|
||||||
|
border-left: 5px solid #007acc;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
h1, h2 {
|
||||||
|
color: #007acc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<img src="logo.png" alt="Le Garage Numérique" class="logo" />
|
||||||
|
|
||||||
|
<h1>Bienvenue sur le dépôt APT du Garage Numérique</h1>
|
||||||
|
<p>Ce dépôt vous permet d’installer facilement les paquets maintenus par <strong>Le Garage Numérique</strong> sur les distributions basées sur Debian.</p>
|
||||||
|
|
||||||
|
<h2>Instructions d'utilisation :</h2>
|
||||||
|
<p>1. Ajouter la clé publique du dépôt :</p>
|
||||||
|
<pre><code>sudo wget -O /etc/apt/trusted.gpg.d/gn-depot.asc https://deb.legaragenumerique.fr/pgp-key.public</code></pre>
|
||||||
|
|
||||||
|
<p>2. Ajouter la source du dépôt :</p>
|
||||||
|
<pre><code>echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/gn-depot.asc] https://deb.legaragenumerique.fr stable main' \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/gn-depot.list</code></pre>
|
||||||
|
|
||||||
|
<p>3. Mettre à jour les paquets :</p>
|
||||||
|
<pre><code>sudo apt update</code></pre>
|
||||||
|
|
||||||
|
<p>4. Installer le paquet souhaité (ex. <code>geo</code>) :</p>
|
||||||
|
<pre><code>sudo apt install geo</code></pre>
|
||||||
|
|
||||||
|
<p>Et voilà 🎉 Vous êtes prêt à utiliser notre dépôt !</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
app/logo.png
Normal file
BIN
app/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
17
app/server.py
Normal file
17
app/server.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from flask import Flask, send_from_directory
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
REPO_DIR = "/workspace/apt-repo"
|
||||||
|
|
||||||
|
@app.route('/<path:path>')
|
||||||
|
def serve_file(path):
|
||||||
|
return send_from_directory(REPO_DIR, path)
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return send_from_directory(REPO_DIR, 'index.html') if os.path.exists(os.path.join(REPO_DIR, 'index.html')) else 'APT Repo server is running!'
|
||||||
|
|
||||||
|
@app.route('/pgp-key.public')
|
||||||
|
def serve_public_key():
|
||||||
|
return send_from_directory('/workspace/depot', 'pgp-key.public')
|
||||||
10
compose.yml
Normal file
10
compose.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
depot-apt:
|
||||||
|
container_name: depot-apt
|
||||||
|
build: .
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./depot:/workspace/depot
|
||||||
|
- ./secret:/workspace/secret
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
Loading…
x
Reference in New Issue
Block a user