Skip to main content
Version: Next 🚧

Hauler Store Serve Registry

Overview​

hauler store serve registry runs an OCI-compliant container registry backed by the content store, making every image (and chart) it contains pullable over the network.

This is how you put collected images to work inside the airgap without depending on an external registry. Point your cluster, container runtime, or docker pull at the address Hauler is serving and pull as you normally would. It's ideal for bootstrapping a cluster or standing up a lightweight, self-contained registry on the airgapped side. The registry runs read-only by default; pass --readonly=false if clients need to push into it. For anything beyond the basics, supply a full distribution config with --config (it overrides all other flags), and enable TLS with --tls-cert/--tls-key.

Tip: If you only need to seed an existing registry rather than serve one via Hauler, use hauler store copy registry://... instead. This is the recommended practice for long-running registry needs.

Note: If the store contains no artifacts, the registry still starts with an empty catalog and logs a warning to add some with hauler store add or hauler store sync.

An example with available flags...

hauler store serve registry --port <port> --readonly=false --tls-cert <cert> --tls-key <key>

Command Overview​

Usage:
hauler store serve registry [flags]

Flags:
--basic-auth string (EXPERIMENTAL) (Optional) Location of the htpasswd file to use for basic authentication
--basic-auth-realm string (EXPERIMENTAL) (Optional) Realm to use for basic authentication (default "hauler-registry")
-c, --config string (Optional) Location of the registry config file (overrides all flags)
--directory string (Optional) Directory to use for backend. (defaults to $PWD/registry) (default "registry")
-h, --help help for registry
-p, --port int (Optional) Set the port to use for incoming connections (default 5000)
--readonly (Optional) Run the registry as readonly (default true)
--tls-cert string (Optional) Location of the TLS Certificate to use for server authentication
--tls-key string (Optional) Location of the TLS Key to use for server authentication

Global Flags:
--audit-level string Set the audit logging level (none, standard, verbose) (defaults standard)
--blob-concurrency int (Optional) Override the maximum number of concurrent blob writes (0 auto-derives from --concurrency where set, otherwise defaults to 16)
-d, --haulerdir string Set the location of the hauler directory (default $HOME/.hauler)
--ignore-errors Warn and continue instead of failing on errors, including storing images that failed verification (defaults false)
-l, --log-level string Set the logging level (i.e. info, debug, warn) (defaults info)
-r, --retries int Set the number of retries for operations (0 uses HAULER_RETRIES, otherwise defaults to 3)
-s, --store string Set the directory to use for the content store
-t, --tempdir string (Optional) Override the default temporary directory determined by the OS
-w, --work-dir string (Optional) Set the directory for output that commands would otherwise write to the current directory (default: current directory)

Basic Authentication​

The --basic-auth flag points at an htpasswd file to require HTTP basic authentication for the registry and --basic-auth-realm overrides the realm sent in the WWW-Authenticate challenge (defaults to hauler-registry).

This feature is experimental and is a shortcut for the auth.htpasswd block in a full --config file below.

Below is an example to generate the htpasswd file with the standard htpasswd utility, using bcrypt hashed passwords...

htpasswd -cB /path/to/htpasswd <username>

Then point the registry at it:

# serve registry with basic authentication
hauler store serve registry --basic-auth /path/to/htpasswd

# serve registry with basic authentication and a custom realm
hauler store serve registry --basic-auth /path/to/htpasswd --basic-auth-realm my-realm

Example Commands for the Hauler Registry​

# serve registry
hauler store serve registry

# serve registry on specific port
hauler store serve registry --port <port>

# serve registry on specific port with custom config
hauler store serve registry --port <port> --config <path-to-config>

# serve registry in writeable mode
hauler store serve registry --readonly=false

Example Config for the Hauler Registry​

These are all configuration options for the registry. Some options in the list are mutually exclusive. Read the detailed reference information about each option before finalizing your configuration.

You can learn more here --> https://distribution.github.io/distribution/about/configuration

version: 0.1
log:
accesslog:
disabled: true
level: debug
formatter: text
fields:
service: registry
environment: staging
hooks:
- type: mail
disabled: true
levels:
- panic
options:
smtp:
addr: mail.example.com:25
username: mailuser
password: password
insecure: true
from: sender@example.com
to:
- errors@example.com
loglevel: debug # deprecated: use "log"
storage:
filesystem:
rootdirectory: /var/lib/registry
maxthreads: 100
azure:
accountname: accountname
accountkey: base64encodedaccountkey
container: containername
rootdirectory: /az/object/name/prefix
credentials:
type: client_secret
clientid: client_id_string
tenantid: tenant_id_string
secret: secret_string
copy_status_poll_max_retry: 10
copy_status_poll_delay: 100ms
gcs:
bucket: bucketname
keyfile: /path/to/keyfile
credentials:
type: service_account
project_id: project_id_string
private_key_id: private_key_id_string
private_key: private_key_string
client_email: client@example.com
client_id: client_id_string
auth_uri: http://example.com/auth_uri
token_uri: http://example.com/token_uri
auth_provider_x509_cert_url: http://example.com/provider_cert_url
client_x509_cert_url: http://example.com/client_cert_url
rootdirectory: /gcs/object/name/prefix
chunksize: 5242880
s3:
accesskey: awsaccesskey
secretkey: awssecretkey
region: us-west-1
regionendpoint: http://myobjects.local
forcepathstyle: true
accelerate: false
bucket: bucketname
encrypt: true
keyid: mykeyid
secure: true
v4auth: true
chunksize: 5242880
multipartcopychunksize: 33554432
multipartcopymaxconcurrency: 100
multipartcopythresholdsize: 33554432
rootdirectory: /s3/object/name/prefix
usedualstack: false
loglevel: debug
inmemory: # This driver takes no parameters
tag:
concurrencylimit: 8
delete:
enabled: false
redirect:
disable: false
cache:
blobdescriptor: redis
blobdescriptorsize: 10000
maintenance:
uploadpurging:
enabled: true
age: 168h
interval: 24h
dryrun: false
readonly:
enabled: false
auth:
silly:
realm: silly-realm
service: silly-service
token:
autoredirect: true
realm: token-realm
service: token-service
issuer: registry-token-issuer
rootcertbundle: /root/certs/bundle
htpasswd:
realm: basic-realm
path: /path/to/htpasswd
middleware:
registry:
- name: ARegistryMiddleware
options:
foo: bar
repository:
- name: ARepositoryMiddleware
options:
foo: bar
storage:
- name: cloudfront
options:
baseurl: https://my.cloudfronted.domain.com/
privatekey: /path/to/pem
keypairid: cloudfrontkeypairid
duration: 3000s
ipfilteredby: awsregion
awsregion: us-east-1, use-east-2
updatefrequency: 12h
iprangesurl: https://ip-ranges.amazonaws.com/ip-ranges.json
storage:
- name: redirect
options:
baseurl: https://example.com/
http:
addr: localhost:5000
prefix: /my/nested/registry/
host: https://myregistryaddress.org:5000
secret: asecretforlocaldevelopment
relativeurls: false
draintimeout: 60s
tls:
certificate: /path/to/x509/public
key: /path/to/x509/private
clientcas:
- /path/to/ca.pem
- /path/to/another/ca.pem
letsencrypt:
cachefile: /path/to/cache-file
email: emailused@letsencrypt.com
hosts: [myregistryaddress.org]
directoryurl: https://acme-v02.api.letsencrypt.org/directory
debug:
addr: localhost:5001
prometheus:
enabled: true
path: /metrics
headers:
X-Content-Type-Options: [nosniff]
http2:
disabled: false
h2c:
enabled: false
notifications:
events:
includereferences: true
endpoints:
- name: alistener
disabled: false
url: https://my.listener.com/event
headers: <http.Header>
timeout: 1s
threshold: 10
backoff: 1s
ignoredmediatypes:
- application/octet-stream
ignore:
mediatypes:
- application/octet-stream
actions:
- pull
redis:
addr: localhost:6379
password: asecret
db: 0
dialtimeout: 10ms
readtimeout: 10ms
writetimeout: 10ms
pool:
maxidle: 16
maxactive: 64
idletimeout: 300s
tls:
enabled: false
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
file:
- file: /path/to/checked/file
interval: 10s
http:
- uri: http://server.to.check/must/return/200
headers:
Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==]
statuscode: 200
timeout: 3s
interval: 10s
threshold: 3
tcp:
- addr: redis-server.domain.com:6379
timeout: 3s
interval: 10s
threshold: 3
proxy:
remoteurl: https://registry-1.docker.io
username: [username]
password: [password]
ttl: 168h
validation:
manifests:
urls:
allow:
- ^https?://([^/]+\.)*example\.com/
deny:
- ^https?://www\.example\.com/