Public | Automated Build

Last pushed: 13 days ago
Short Description
This is a containerized Portus server.
Full Description


This is a containerized Portus server for the Docker registry (based on Alpine Linux). The authentication process can be described in 6 steps:

<p align="center">
<img src="six-steps.png">

  1. Attempt to begin a push/pull operation with the registry.
  2. If the registry requires authorization it will return a 401 Unauthorized HTTP response with information on how to authenticate.
  3. The registry client makes a request to the authorization service for a Bearer token.
  4. The authorization service returns an opaque Bearer token representing the client’s authorized access.
  5. The client retries the original request with the Bearer token embedded in the request’s Authorization header.
  6. The Registry authorizes the client by validating the Bearer token and the claim set embedded within it and begins the push/pull session as usual.

1. Certificate:

Configure one certificate to rule them all:

mkdir portus && cd portus

cat << EOF > ssl.conf
[ req ]
prompt             = no
distinguished_name = req_subj
x509_extensions    = x509_ext

[ req_subj ]
CN = Localhost

[ x509_ext ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints       = CA:true
subjectAltName         = @alternate_names

[ alternate_names ]
DNS.1 = localhost
IP.1  =

Build the certificate:

mkdir certs && openssl req -config ssl.conf \
-new -x509 -nodes -sha256 -days 365 -newkey rsa:4096 \
-keyout certs/server-key.pem -out certs/server-crt.pem

You can now (optionally) verify the certificate:

openssl x509 -in certs/server-crt.pem -text -noout
openssl verify -CAfile certs/server-crt.pem certs/server-crt.pem

Instruct docker daemon to trust the certificate:

sudo mkdir -p /etc/docker/certs.d/
sudo cp certs/server-crt.pem /etc/docker/certs.d/
sudo systemctl restart docker
2. MariaDB:
docker run -it --rm \
--net host --name mariadb \
--env MYSQL_ROOT_PASSWORD=portus \
--env MYSQL_USER=portus \
--env MYSQL_PASSWORD=portus \
--env MYSQL_DATABASE=portus \
3. Portus:

Note that PUMA_IP is to be used if you want to have the registry and portus running on the same port but on different addresses, for example:

  • Portus ->
  • Registry ->
cd portus && docker run -it --rm \
--net host --name portus \
--volume ${PWD}/certs:/certs \
--env DEBUG=true \
--env MARIADB_ADAPTER=mysql2 \
--env MARIADB_PORT=3306 \
--env MARIADB_USER=portus \
--env MARIADB_PASSWORD=portus \
--env MARIADB_DATABASE=portus \
--env RACK_ENV=production \
--env RAILS_ENV=production \
--env PUMA_SSL_KEY=/certs/server-key.pem \
--env PUMA_SSL_CRT=/certs/server-crt.pem \
--env PUMA_IP= \
--env PUMA_PORT=443 \
--env PUMA_WORKERS=4 \
--env PORTUS_SECRET_KEY_BASE=$(openssl rand -hex 64) \
--env PORTUS_ENCRYPTION_PRIVATE_KEY_PATH=/certs/server-key.pem \
--env PORTUS_PORTUS_PASSWORD=some-password \

Browse to and fill the 'Create admin' form. Do not fill the 'New Registry' form until you have actually started the registry in step 4.

4. Registry:

Make sure any endpoint defined in SSL_TRUST is up and running before starting the registry.

cd portus && docker run -it --rm \
--net host --name registry \
--volume ${PWD}/certs:/certs \
--env REGISTRY_LOG_LEVEL=debug \
--env REGISTRY_HTTP_SECRET=$(openssl rand -hex 64) \
--env REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server-crt.pem \
--env REGISTRY_HTTP_TLS_KEY=/certs/server-key.pem \
--env REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/certs/server-crt.pem \
--env SSL_TRUST= \
--env ENDPOINT_NAME=portus \

Verify the status of the registry:

curl -s | jq '.'
curl -s | jq '.'

Now you can fill the 'New Registry' form. Use for the hostname and check the SSL checkbox.

5. Docker:
docker login -u ${USER}
docker pull busybox:latest
docker tag busybox:latest${USER}/busybox:latest
docker push${USER}/busybox:latest
docker rmi busybox:latest${USER}/busybox:latest
docker pull${USER}/busybox:latest
Docker Pull Command
Source Repository

Comments (1)
a year ago

portus_1 | Waiting for the database rake aborted!
portus_1 | LoadError: cannot load such file -- bigdecimal/util
portus_1 | /portus/config/application.rb:3:in require' portus_1 | /portus/config/application.rb:3:in<top (required)>'
portus_1 | /portus/Rakefile:4:in require' portus_1 | /portus/Rakefile:4:in<top (required)>'
portus_1 | (See full trace by running task with --trace)

portus_1 | /usr/lib/ruby/gems/2.2.0/gems/activesupport-4.2.2/lib/active_support/core_ext/big_decimal/conversions.rb:2:in require': cannot load such file -- bigdecimal/util (LoadError) portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/activesupport-4.2.2/lib/active_support/core_ext/big_decimal/conversions.rb:2:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/activesupport-4.2.2/lib/active_support/core_ext/object/json.rb:4:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/activesupport-4.2.2/lib/active_support/core_ext/object/json.rb:4:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/activesupport-4.2.2/lib/active_support/core_ext/object.rb:12:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/activesupport-4.2.2/lib/active_support/core_ext/object.rb:12:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/configuration.rb:2:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/configuration.rb:2:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/railtie.rb:2:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/railtie.rb:2:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/engine.rb:1:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/engine.rb:1:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/application.rb:6:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/application.rb:6:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails.rb:11:in require' portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails.rb:11:in<top (required)>'
portus_1 | from /usr/lib/ruby/gems/2.2.0/gems/railties-4.2.2/lib/rails/all.rb:1:in `require'