provision and use a docker registry repository
This commit is contained in:
parent
457cb7f752
commit
54e3872442
|
|
@ -27,7 +27,9 @@ Vagrant.configure(2) do |config|
|
|||
config.vm.synced_folder '.', '/vagrant', type: 'nfs'
|
||||
end
|
||||
config.vm.provision :shell, path: 'provision/provision-base.sh'
|
||||
config.vm.provision :shell, path: 'provision/provision-docker.sh'
|
||||
config.vm.provision :shell, path: 'provision/provision-nexus.sh'
|
||||
config.vm.provision :shell, path: 'provision/use-docker-repository.sh'
|
||||
config.vm.provision :shell, path: 'provision/use-raw-repository.sh'
|
||||
config.vm.provision :shell, path: 'provision/use-maven-repository-from-mvn.sh'
|
||||
config.vm.provision :shell, path: 'provision/use-maven-repository-from-gradle.sh'
|
||||
|
|
|
|||
|
|
@ -129,6 +129,96 @@ server {
|
|||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
}
|
||||
|
||||
# docker-group repository.
|
||||
server {
|
||||
listen 5001 ssl http2;
|
||||
server_name $config_fqdn;
|
||||
access_log /var/log/nginx/$config_fqdn-docker-group.access.log;
|
||||
|
||||
ssl_certificate /etc/ssl/private/$config_fqdn-crt.pem;
|
||||
ssl_certificate_key /etc/ssl/private/$config_fqdn-keypair.pem;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
# see https://github.com/cloudflare/sslconfig/blob/master/conf
|
||||
# see https://blog.cloudflare.com/it-takes-two-to-chacha-poly/
|
||||
# see https://blog.cloudflare.com/do-the-chacha-better-mobile-performance-with-cryptography/
|
||||
# NB even though we have CHACHA20 here, the OpenSSL library that ships with Ubuntu 16.04 does not have it. so this is a nop. no problema.
|
||||
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!aNULL:!MD5;
|
||||
|
||||
tcp_nodelay on;
|
||||
client_max_body_size 10G;
|
||||
proxy_send_timeout 120;
|
||||
proxy_read_timeout 300;
|
||||
proxy_buffering off;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Forwarded-Host \$host;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6001;
|
||||
}
|
||||
}
|
||||
|
||||
# docker-hub-proxy repository.
|
||||
server {
|
||||
listen 5002 ssl http2;
|
||||
server_name $config_fqdn;
|
||||
access_log /var/log/nginx/$config_fqdn-docker-hub-proxy.access.log;
|
||||
|
||||
ssl_certificate /etc/ssl/private/$config_fqdn-crt.pem;
|
||||
ssl_certificate_key /etc/ssl/private/$config_fqdn-keypair.pem;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
# see https://github.com/cloudflare/sslconfig/blob/master/conf
|
||||
# see https://blog.cloudflare.com/it-takes-two-to-chacha-poly/
|
||||
# see https://blog.cloudflare.com/do-the-chacha-better-mobile-performance-with-cryptography/
|
||||
# NB even though we have CHACHA20 here, the OpenSSL library that ships with Ubuntu 16.04 does not have it. so this is a nop. no problema.
|
||||
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!aNULL:!MD5;
|
||||
|
||||
tcp_nodelay on;
|
||||
client_max_body_size 10G;
|
||||
proxy_send_timeout 120;
|
||||
proxy_read_timeout 300;
|
||||
proxy_buffering off;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Forwarded-Host \$host;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6002;
|
||||
}
|
||||
}
|
||||
|
||||
# docker-hosted repository.
|
||||
server {
|
||||
listen 5003 ssl http2;
|
||||
server_name $config_fqdn;
|
||||
access_log /var/log/nginx/$config_fqdn-docker-hosted.access.log;
|
||||
|
||||
ssl_certificate /etc/ssl/private/$config_fqdn-crt.pem;
|
||||
ssl_certificate_key /etc/ssl/private/$config_fqdn-keypair.pem;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
# see https://github.com/cloudflare/sslconfig/blob/master/conf
|
||||
# see https://blog.cloudflare.com/it-takes-two-to-chacha-poly/
|
||||
# see https://blog.cloudflare.com/do-the-chacha-better-mobile-performance-with-cryptography/
|
||||
# NB even though we have CHACHA20 here, the OpenSSL library that ships with Ubuntu 16.04 does not have it. so this is a nop. no problema.
|
||||
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!aNULL:!MD5;
|
||||
|
||||
tcp_nodelay on;
|
||||
client_max_body_size 10G;
|
||||
proxy_send_timeout 120;
|
||||
proxy_read_timeout 300;
|
||||
proxy_buffering off;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Forwarded-Host \$host;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6003;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
ln -s ../sites-available/$config_fqdn.conf /etc/nginx/sites-enabled/
|
||||
systemctl restart nginx
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
set -eux
|
||||
|
||||
# NB execute apt-cache madison docker-ce to known the available versions.
|
||||
docker_version="${1:-5:19.03.8~3-0~ubuntu-bionic}"; shift || true
|
||||
registry_proxy_domain="${1:-$(hostname --fqdn)}"; shift || true
|
||||
# NB as-of docker 19.03.8, there is still no way to specify a registry mirror credentials,
|
||||
# as such, we cannot use our docker-group registry, instead we must use the docker-proxy
|
||||
# registry and allow anonymous access to it.
|
||||
# see https://github.com/moby/moby/issues/30880
|
||||
registry_proxy_host="$registry_proxy_domain:5002"
|
||||
registry_proxy_url="https://$registry_proxy_host"
|
||||
|
||||
# prevent apt-get et al from asking questions.
|
||||
# NB even with this, you'll still get some warnings that you can ignore:
|
||||
# dpkg-preconfigure: unable to re-open stdin: No such file or directory
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# install docker.
|
||||
# see https://docs.docker.com/install/linux/docker-ce/ubuntu/
|
||||
apt-get install -y apt-transport-https software-properties-common gnupg2
|
||||
wget -qO- https://download.docker.com/linux/ubuntu/gpg | apt-key add -
|
||||
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
||||
apt-get update
|
||||
apt-get install -y "docker-ce=$docker_version" "docker-ce-cli=$docker_version" containerd.io
|
||||
|
||||
# configure it.
|
||||
cat >/etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"experimental": false,
|
||||
"debug": false,
|
||||
"log-driver": "journald",
|
||||
"labels": [
|
||||
"os=linux"
|
||||
],
|
||||
"hosts": [
|
||||
"fd://"
|
||||
],
|
||||
"containerd": "/run/containerd/containerd.sock",
|
||||
"registry-mirror": "$registry_proxy_url"
|
||||
}
|
||||
EOF
|
||||
# start docker without any command line flags as its entirely configured from daemon.json.
|
||||
install -d /etc/systemd/system/docker.service.d
|
||||
cat >/etc/systemd/system/docker.service.d/override.conf <<'EOF'
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/dockerd
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl restart docker
|
||||
|
||||
# let the vagrant user manage docker.
|
||||
usermod -aG docker vagrant
|
||||
|
||||
# kick the tires.
|
||||
ctr version
|
||||
docker version
|
||||
docker info
|
||||
|
|
@ -66,6 +66,23 @@ repository.createNugetProxy("chocolatey.org-proxy", "https://chocolatey.org/api/
|
|||
repository.createNugetGroup("chocolatey-group", ["chocolatey-hosted", "chocolatey.org-proxy"], "default")
|
||||
|
||||
|
||||
// create a docker registry repository backed by the default blob store.
|
||||
repository.createDockerHosted("docker-hosted", 6003, null, "default", true, true, WritePolicy.ALLOW, true)
|
||||
// create a docker proxy repository backed by the default blob store.
|
||||
// see https://help.sonatype.com/repomanager3/formats/docker-registry
|
||||
// TODO set Allow Nexus Repository Manager to download and cache foreign layers.
|
||||
// NB as-of docker 19.03.5, there is still no way to specify a registry mirror credentials...
|
||||
// as such, we cannot use our docker-group registry, instead we must use the docker-proxy
|
||||
// registry, enable the Docker Bearer Token Realm and allow anonymous access to it.
|
||||
// see https://github.com/moby/moby/issues/30880
|
||||
// NB this will make https://nexus.example.com:5002/v2/library/debian/manifests/buster-slim proxy
|
||||
// to https://registry-1.docker.io/v2/library/debian/manifests/buster-slim
|
||||
// https://registry-1.docker.io/v2/library/golang/tags/list
|
||||
repository.createDockerProxy("docker-hub-proxy", "https://registry-1.docker.io", "HUB", null, 6002, null, "default", true, true, false)
|
||||
// create a docker group repository that merges the docker-hosted and docker-hub-proxy together.
|
||||
repository.createDockerGroup("docker-group", 6001, null, ["docker-hosted", "docker-hub-proxy"], true, "default", true)
|
||||
|
||||
|
||||
// see http://stackoverflow.com/questions/8138164/groovy-generate-random-string-from-given-character-set
|
||||
def random(String alphabet, int n) {
|
||||
new Random().with {
|
||||
|
|
@ -94,12 +111,19 @@ taskConfiguration.setString("snapshotRetentionDays", "30")
|
|||
taskScheduler.scheduleTask(taskConfiguration, new Daily(new Date().clearTime().next()))
|
||||
|
||||
|
||||
// enable the NuGet API-Key Realm.
|
||||
// NB you can list the available realms with realmManager.availableRealms.
|
||||
realmManager = container.lookup(RealmManager.class.name)
|
||||
// enable the NuGet API-Key Realm.
|
||||
realmManager.enableRealm("NuGetApiKey")
|
||||
|
||||
// enable the npm Bearer Token Realm.
|
||||
realmManager.enableRealm("NpmToken")
|
||||
// enable the Docker Bearer Token Realm.
|
||||
realmManager.enableRealm("DockerToken")
|
||||
// allow Anonymous access to nexus to be able to use the docker-hub-proxy repository.
|
||||
// NB this might be worked around by creating an docker-anonymous user and force its
|
||||
// credentials in the nginx reverse-proxy configuration.
|
||||
// see https://github.com/moby/moby/issues/30880#issuecomment-601513505
|
||||
security.anonymousAccess = true
|
||||
|
||||
// set the admin password.
|
||||
// NB we set it to something different than the default (admin123) to get
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
#!/bin/bash
|
||||
set -eux
|
||||
|
||||
nexus_domain=$(hostname --fqdn)
|
||||
docker_group_registry_host="$nexus_domain:5001"
|
||||
docker_hosted_registry_host="$nexus_domain:5003"
|
||||
registry_username='alice.doe'
|
||||
registry_password='password'
|
||||
|
||||
# login into the registry.
|
||||
echo "logging in the registry $docker_group_registry_host..."
|
||||
docker login $docker_group_registry_host --username "$registry_username" --password-stdin <<EOF
|
||||
$registry_password
|
||||
EOF
|
||||
echo "logging in the registry $docker_hosted_registry_host..."
|
||||
docker login $docker_hosted_registry_host --username "$registry_username" --password-stdin <<EOF
|
||||
$registry_password
|
||||
EOF
|
||||
|
||||
mkdir -p tmp/use-docker-repository && cd tmp/use-docker-repository
|
||||
|
||||
#
|
||||
# test the docker repository.
|
||||
|
||||
cat >main.go <<'EOF'
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
|
||||
var listenAddress = flag.String("listen", ":8000", "Listen address.")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() != 0 {
|
||||
flag.Usage()
|
||||
log.Fatalf("\nERROR You MUST NOT pass any positional arguments")
|
||||
}
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
fmt.Printf("%s %s%s\n", r.Method, r.Host, r.URL)
|
||||
fmt.Fprintf(w, "%s %s%s\n", r.Method, r.Host, r.URL)
|
||||
})
|
||||
|
||||
fmt.Printf("Listening at http://%s\n", *listenAddress)
|
||||
|
||||
err := http.ListenAndServe(*listenAddress, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to ListenAndServe: %v", err)
|
||||
}
|
||||
}
|
||||
EOF
|
||||
cat >Dockerfile <<'EOF'
|
||||
FROM golang:1.14.1-buster as builder
|
||||
WORKDIR /app
|
||||
COPY main.go .
|
||||
RUN CGO_ENABLED=0 go build -ldflags="-s" -o=go-hello
|
||||
|
||||
# NB we use the buster-slim (instead of scratch) image so we
|
||||
# can enter the container to execute bash etc.
|
||||
FROM debian:buster-slim
|
||||
COPY --from=builder /app/go-hello .
|
||||
WORKDIR /
|
||||
EXPOSE 8000
|
||||
ENTRYPOINT ["/go-hello"]
|
||||
EOF
|
||||
|
||||
# build the image.
|
||||
docker build -t go-hello:1.0.0 .
|
||||
docker image ls go-hello:1.0.0
|
||||
|
||||
# push the image to the docker-hosted registry.
|
||||
docker tag go-hello:1.0.0 $docker_hosted_registry_host/go-hello:1.0.0
|
||||
docker push $docker_hosted_registry_host/go-hello:1.0.0
|
||||
|
||||
# show the repository (image) details directly from the docker-hosted registry.
|
||||
# see https://docs.docker.com/registry/spec/api/
|
||||
# see https://docs.docker.com/registry/spec/manifest-v2-2/
|
||||
wget -qO- --user "$registry_username" --password "$registry_password" \
|
||||
"https://$docker_hosted_registry_host/v2/go-hello/tags/list" | jq .
|
||||
manifest=$(wget -qO- --user "$registry_username" --password "$registry_password" \
|
||||
'--header=Accept: application/vnd.docker.distribution.manifest.v2+json' \
|
||||
"https://$docker_hosted_registry_host/v2/go-hello/manifests/1.0.0")
|
||||
config_digest=$(echo "$manifest" | jq -r .config.digest)
|
||||
echo "$manifest" | jq .
|
||||
wget -qO- --user "$registry_username" --password "$registry_password" \
|
||||
"https://$docker_hosted_registry_host/v2/go-hello/blobs/$config_digest" | jq .
|
||||
|
||||
# remove it from local cache.
|
||||
docker image remove go-hello:1.0.0
|
||||
docker image remove $docker_hosted_registry_host/go-hello:1.0.0
|
||||
|
||||
# pull it from the docker-group registry.
|
||||
docker pull $docker_group_registry_host/go-hello:1.0.0
|
||||
Loading…
Reference in New Issue