Public Access
Initial implementation: aptly container image, Compose stacks, Helm chart, and Gitea Actions pipelines
Provides a self-contained, containerized aptly (Debian repo manager) stack with independently releasable image and Helm chart versions. - images/: aptly-server (aptly built from source, cross-compiled) and aptly-deb-builder (nfpm + dpkg-buildpackage) container images - rootfs/: shared aptly-init/aptly-reconcile/aptly-push/aptly-pack scripts consumed identically by Compose and the Helm chart, driven by one declarative state.yaml contract - compose/: test (ephemeral, open) and production docker-compose stacks with an nginx read/auth sidecar - charts/aptly/: aptly-native Helm chart covering every security posture from fully open to authenticated read+write, Ingress and Gateway API support (usable in parallel for migration scenarios), metrics, and declarative repo/mirror/publish reconciliation via a Helm hook - .gitea/workflows/: CI (lint, template, kubeconform, E2E smoke test) plus separately tagged image (image/v*) and chart (chart/v*) releases, weekly rebuilds, and a preflight workflow validating the runner's Docker/Helm-OCI capabilities - pubkeys/: RSA chart-signing key for Helm --sign / Artifact Hub's signKey annotation (Helm can't verify Ed25519 keys) - docs/, README.md, charts/aptly/README.md: usage, security, and versioning documentation
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Source aptly config, rendered by aptly-init into /run/aptly/aptly.yaml.
|
||||
# ${VAR}-style placeholders are resolved against the aptly container's
|
||||
# environment at startup — see .env.example for what to set.
|
||||
#
|
||||
# This one file is shared by both docker-compose.test.yaml and
|
||||
# docker-compose.yaml (production); the security posture (auth, network
|
||||
# exposure) is entirely an nginx concern (see nginx.test.conf / nginx.prod.conf),
|
||||
# not an aptly config concern — aptly itself never changes between the two.
|
||||
root_dir: /var/lib/aptly
|
||||
log_level: info
|
||||
gpg_provider: internal
|
||||
serve_in_api_mode: false
|
||||
filesystem_publish_endpoints:
|
||||
public:
|
||||
root_dir: /var/lib/aptly/public
|
||||
link_method: hardlink
|
||||
@@ -0,0 +1,48 @@
|
||||
# Production topology: security.preset "publicRead" equivalent — reading the
|
||||
# repo (apt clients) needs no credentials, writing (the API under /api/) does.
|
||||
# Health-check paths stay exempt so container/orchestrator probes never need
|
||||
# credentials in any mode.
|
||||
#
|
||||
# Mounted at /etc/nginx/conf.d/default.conf, which the base image's own
|
||||
# nginx.conf already `include`s from inside its own http{} block — so this
|
||||
# file must contain ONLY a server{} block (or other http-context directives),
|
||||
# never its own http{}/events{}/worker_processes wrapper.
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
client_max_body_size 0;
|
||||
absolute_redirect off;
|
||||
|
||||
location = /healthz { access_log off; return 200 "ok\n"; }
|
||||
|
||||
location = /api/ready { access_log off; proxy_pass http://aptly:8080; }
|
||||
location = /api/healthy { access_log off; proxy_pass http://aptly:8080; }
|
||||
|
||||
location /api/ {
|
||||
auth_basic "aptly";
|
||||
auth_basic_user_file /run/aptly/htpasswd;
|
||||
|
||||
proxy_pass http://aptly:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_request_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
|
||||
location = /signing-key.asc {
|
||||
alias /run/aptly/pub/signing-key.asc;
|
||||
default_type text/plain;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /var/lib/aptly/public;
|
||||
autoindex on;
|
||||
autoindex_exact_size off;
|
||||
|
||||
location ~* /(InRelease|Release|Release\.gpg|Packages(\.[a-z0-9]+)?|Sources(\.[a-z0-9]+)?)$ {
|
||||
root /var/lib/aptly/public;
|
||||
add_header Cache-Control "no-cache" always;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Test topology: everything open (security.preset "open" equivalent) — no
|
||||
# auth on read OR write. This is what "komplett unabgesichert" looks like.
|
||||
# Do not reuse this file for docker-compose.yaml (production).
|
||||
#
|
||||
# Mounted at /etc/nginx/conf.d/default.conf, which the base image's own
|
||||
# nginx.conf already `include`s from inside its own http{} block — so this
|
||||
# file must contain ONLY a server{} block (or other http-context directives),
|
||||
# never its own http{}/events{}/worker_processes wrapper.
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
client_max_body_size 0;
|
||||
absolute_redirect off;
|
||||
|
||||
location = /healthz { access_log off; return 200 "ok\n"; }
|
||||
|
||||
location = /api/ready { access_log off; proxy_pass http://aptly:8080; }
|
||||
location = /api/healthy { access_log off; proxy_pass http://aptly:8080; }
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://aptly:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_request_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
|
||||
location = /signing-key.asc {
|
||||
alias /run/aptly/pub/signing-key.asc;
|
||||
default_type text/plain;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /var/lib/aptly/public;
|
||||
autoindex on;
|
||||
autoindex_exact_size off;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
# Demo state for docker-compose.test.yaml: one local repo, published at the
|
||||
# repo root, completely open and unsigned. Not meant for production — see
|
||||
# compose/config/state.yaml for the starter template used there.
|
||||
localRepos:
|
||||
- name: demo
|
||||
comment: "docker-compose.test.yaml demo repo"
|
||||
defaultDistribution: stable
|
||||
defaultComponent: main
|
||||
|
||||
publish:
|
||||
- name: demo-root
|
||||
prefix: ""
|
||||
distribution: stable
|
||||
sourceKind: local
|
||||
sources:
|
||||
- { name: demo, component: main }
|
||||
architectures: [amd64, arm64]
|
||||
acquireByHash: true
|
||||
@@ -0,0 +1,31 @@
|
||||
# Declarative aptly state for docker-compose.yaml (production). Consumed by
|
||||
# aptly-reconcile on every start of the `reconcile` service — safe to edit and
|
||||
# restart that service as often as you like, it only converges towards
|
||||
# whatever is described here (see docs/packaging.md).
|
||||
#
|
||||
# Uncomment and adjust the example below to get your first repo + publish
|
||||
# target, or add your own. See rootfs/usr/local/bin/aptly-reconcile for the
|
||||
# full field reference.
|
||||
|
||||
localRepos: []
|
||||
# - name: stable
|
||||
# comment: "Production package repository"
|
||||
# defaultDistribution: stable
|
||||
# defaultComponent: main
|
||||
|
||||
mirrors: []
|
||||
# - name: debian-security
|
||||
# archiveURL: http://security.debian.org/debian-security
|
||||
# distribution: trixie-security
|
||||
# components: [main]
|
||||
# architectures: [amd64, arm64]
|
||||
|
||||
publish: []
|
||||
# - name: stable-root
|
||||
# prefix: ""
|
||||
# distribution: stable
|
||||
# sourceKind: local
|
||||
# sources:
|
||||
# - { name: stable, component: main }
|
||||
# architectures: [amd64, arm64]
|
||||
# acquireByHash: true
|
||||
@@ -0,0 +1,7 @@
|
||||
# Plaintext "user:password" lines, one per line — hashed into htpasswd by
|
||||
# aptly-init at container start (never store a bcrypt/apr1 hash here yourself;
|
||||
# see rootfs/usr/local/bin/aptly-init for why). Copy this file to
|
||||
# compose/config/users (gitignored) and edit it before starting
|
||||
# docker-compose.yaml (production). Blank lines and anything without a colon
|
||||
# are ignored.
|
||||
ci:change-me-please
|
||||
Reference in New Issue
Block a user