Install Private Docker Registry on Centos 7

A Docker Registry is a service which you can push Docker images to for storage and sharing. We can deploy our own private Docker Registry behind our firewall with SSL encryption and HTTP authentication. Here we can use centos 7 to install docker registry and using Apache for secure connection with htpasswd.

Docker Private Registry Installation

Docker Private Registry Installation

There are many ways available to install Docker Private Registry on CentOS 7.

Install Docker Private Registry Container

The easiest way to install docker private registry using the container.

Step 1

Install docker

Step 2

Install docker private registry

  • mount registry volume /var/lib/registry

Syntax,

 docker run -d -p 5000:5000 --restart=always --name registry -v <volume-location>:/var/lib/registry registry

Example

# docker run -d -p 5000:5000 --restart=always --name registry -v /var/lib/registry:/var/lib/registry registry

You can connect docker private registry using <hostname/ip>:5000

Browse http://<hostname/ip>:5000/v2/_catalog

Add your registry with docker daemon and push images.

Configure Secure Docker Private Registry

You can use Apache or Nginx web server to configure the registry.

Step 1

Install registry to listening only with localhost.

# docker run -d -p 127.0.0.1:5000:5000 --restart=always --name registry -v /var/lib/registry:/var/lib/registry -v /etc/docker/registry:/etc/docker/registry registry

Step 2

Install Nginx

# yum install epel-release -y
# yum install nginx -y
# cd /etc/nginx/conf.d/
# vi registry.conf
upstream docker-registry {
server 127.0.0.1:5000;
}

server {
listen 443 ssl;
server_name registry.cloudkb.net;

# SSL
ssl_certificate  /etc/nginx/cloudkb.pem;
ssl_certificate_key  /etc/nginx/cloudkb.pem;

# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;

# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on;

location /v2/ {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}

# To add basic authentication to v2 use auth_basic setting.
#auth_basic "Registry realm";
#auth_basic_user_file /etc/nginx/.htpasswd;

## If $docker_distribution_api_version is empty, the header will not be added.
## See the map directive above where this variable is defined.
#add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

proxy_pass http://docker-registry;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
}

Make sure the SSL configuration with your domain name and SSL certificate location.

#server_name

# ssl_certificate_key

# ssl_certificate

Step 3

Restart Nginx service.

Note: SELinux should be a permissive mode to access proxy.

# setenforce 0

Step 4

It is not required to add with docker deamon. Use this command to login the registry.

# docker login <server_name>

Configure Docker Private Registry with Authentication

Step 1

Install htpasswd and enable user auth.

htpasswd -c /etc/nginx/.htpasswd  guestuser

Step 2

Enable this configuration in registry.conf

#auth_basic “Registry realm”;
#auth_basic_user_file /etc/nginx/.htpasswd;

Step 3 

Restart Nginx service and connect your registry with authentication.

# docker login <server_name>

 

Install Private Docker Registry on Centos 7

Docker registry OLD V1 version Installation.

Update all packages and install docker registry

#yum update
#yum install docker-registry
#systemctl enable docker-registry.service
#service docker-registry start

Change your customized registry storage path if you required.

vi /etc/docker-registry.yml

search the storage path location and change it.

local
storage_path =

Once the changes are completed restart docker registry.

To verify the docker registry, use curl command

#curl 192.168.1.88:5000
“\”docker-registry server\””

That’s it!! Your insecure registry is working now.

Browse your Insecure Registry docker registry

http://192.168.1.88:5000/
Tag your images to push to the registry

Example

#docker tag <imageID> 192.168.1.88:5000/centos

Run your insecure docker registry with docker

#service docker stop
#docker -d --insecure-registry 192.168.1.88:5000 &

or

change your docker startup script with insecure registry

#vi /usr/lib/systemd/system/docker.service

add insecure registry url on ExecStart

–insecure-registry 192.168.1.88:5000

Example entry

ExecStart=/usr/bin/docker -d $OPTIONS \
 $DOCKER_STORAGE_OPTIONS \
 $DOCKER_NETWORK_OPTIONS \
 $ADD_REGISTRY \
 $BLOCK_REGISTRY \
 --insecure-registry 192.168.1.88:5000

Push your images

#docker push 192.168.1.88:5000/centos

Your images will successfully be pushed to insecure registry

Pull your images

change your docker startup script with insecure registry as per previous step

#docker pull 192.168.1.88:5000/centos

You are done with insecure registry

Secure Docker Private Registry

In order to use docker registry with secure URL, try to install apache and configure SSL.

install apache with mod SSL.

#yum install httpd mod_ssl

Create user authentication using htpasswd for docker registry

# htpasswd -c /etc/httpd/.htpasswd USERNAME

create your SSL certificate whether Self Signed or valid SSL cert, open your ssl.conf and add proxy settings before </VirtualHost>

#vi /etc/httpd/conf.d/ssl.conf

ProxyRequests off
 ProxyPreserveHost on
 ProxyPass / http://127.0.0.1:5000/
 ProxyPassReverse / http://127.0.0.1:5000/
<Location />
 Order deny,allow
 Allow from all
AuthName "Registry Authentication"
 AuthType basic
 AuthUserFile "/etc/httpd/.htpassword"
 Require valid-user
 </Location>
# Allow ping and users to run unauthenticated.
 <Location /v1/_ping>
 Satisfy any
 Allow from all
 </Location>
 # Allow ping and users to run unauthenticated.
 <Location /_ping>
 Satisfy any
 Allow from all
 </Location>

Change the valid SSL certificate paths

SSLCertificateFile
SSLCertificateKeyFile
Now you try to restart httpd service.

# service httpd restart

Browse your registry with SSL and make sure it works.

https://192.168.1.88/
Now you can login to private registry server

docker login https://192.168.1.88/

provide your username and password, the same you provided when creating the htpasswd file.

-Push your images to docker registry

#docker push 192.168.1.88/centos

 

Docker registry itself authentication setup

New private docker repository moved as docker distribution. Once you installed docker registry.

Create htpasswd in any file, example /etc/nginx/.htpasswd

example,

# htpasswd -c /etc/nginx/.htpasswd admin

Once done, modify the following docker distribution configuration config

vi /etc/docker-distribution/registry/config.yml

add the additional auth configuration.

auth:
 htpasswd:
 realm: basic-realm
 path: /etc/nginx/.htpasswd

 

Example config.yml file

version: 0.1
log:
 fields:
 service: registry
storage:
 cache:
 layerinfo: inmemory
 filesystem:
 rootdirectory: /var/lib/registry
http:
 addr: :5000
auth:
 htpasswd:
 realm: basic-realm
 path: /etc/nginx/.htpasswd

Restart docker registry service.

Done, before you push or pull the images. you must log in the Docker registry.

docker login 192.168.1.88:5000
 

Create Private Gem Server using geminabox

A sinatra based gem hosting app, with client side gem push style functionality. Really simple rubygem hosting. Geminabox lets you host your own gems, and push new gems to it just like with rubygems.org. The bundler dependencies API is supported out of the box. Authentication is left up to either the web server, or the Rack stack.

FEATURES:

  • upload a gems via command line.
  • via web interface
  • replace a gems
  • delete a gems
  • install gems like any other source
  • list the available gems.

 

gem in a box

To get started, Create Private Gem Server using geminabox :

Install Gem

#yum install gem

When you install RubyGems, it adds the gem server command to your system. This is the fastestway to start hosting gems. Just run the command: #gem server

#gem install geminabox

Make a data directory for storing gems:

#mkdir data

Create a config.ru as follows:

require "rubygems"
require "geminabox"
Geminabox.data = "/date" # …or wherever run Geminabox
run Geminabox::Server

And finally, hook up the config.ru as you normally would (passenger, thin, unicorn, whatever floats you boat).

#rackup

Now you can push gems using the gem inabox command.

There is a web interface available on http://localhost:9292 as well.

 

In order to access it globally. You should configure with apache or nginx proxy.

here is the example for apache config.

vi /etc/httpd/conf/httpd.conf

ProxyRequests Off
ProxyPass / http://localhost:9292/
ProxyPassReverse / http://localhost:9292/

 

Gem CLIENT USAGE

If you did not need any credentials to get to this page

gem sources -a http://gems.localhost/

If you needed some credentials to get to this page

gem sources -a http://username:password@gems.localhost/

Then run the following commands.

gem install geminabox
gem inabox [gemfile]

 

Command Line Help

Usage: gem inabox GEM [options]

Options:
-c, –configure Configure GemInABox
-g, –host HOST Host to upload to.
-o, –overwrite Overwrite Gem.
Common Options:
-h, –help Get help on this command
-V, –[no-]verbose Set the verbose level of output
-q, –quiet Silence commands
–config-file FILE Use this config file instead of default
–backtrace Show stack backtrace on errors
–debug Turn on Ruby debugging
Arguments:
GEM built gem to push up

Summary:
Push a gem up to your GemInABox

Description:
Push a gem up to your GemInABox

 

Disable delete option in GUI

 

Login your geminabox installed server and change the following ruby file.

 

#cd /usr/local/share/gems/gems/geminabox-0.12.4/lib/
#vi geminabox.rb

change the following option under set_defaults function allow_delete to false instead of true.

allow_delete:         false,

 

 

Install Chef Server and Chef Client in Centos 6

There are three configuration scenarios for the Chef server:

Standalone (everything on a single machine)
High availability (machines configured for front-end and back-end, allowing for failover on the back-end and load-balancing on the front-end, as required)
Tiered (machines configured for front-end and back-end, with a single back-end and load-balancing on the front-end, as required)

Prerequisites

  • An x86_64 compatible system architecture; Red Hat Enterprise Linux and CentOS may require updates prior to installation
  • A resolvable hostname that is specified using a FQDN or an IP address
  • A connection to NTP to prevent clock drift
  • A local mail transfer agent that allows the Chef server to send email notifications
  • Using cron and the /etc/cron.d directory for periodic maintenance tasks
  • Disabling the Apache Qpid daemon on CentOS and Red Hat systems
  • A local user account under which services will run
  • A local user account for PostgreSQL
  • A group account under which services will run

 

Install Chef Server and Chef Client in Centos 6

We have tested chef server and chef client with centos 6 as well.

Chef server : 192.168.1.160
chef client : 192.168.1.161

Before proceed chef server installation, you should verify and do the following steps.

  • Disable selinux
  • Set FQDN name before running reconfigure. ( chef.example.com )

vi /etc/hosts

192.168.1.160 chef.example.com

Download chef server

https://www.chef.io/chef/install/

I have used 11.1.6-1 version of chef server.

Login your chef server

#wget https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-server-11.1.6-1.el6.x86_64.rpm
#chef-server-ctl reconfigure

It will take few minutes to complete this process.

Run these commands on your Chef server to install the management console.
#chef-server-ctl install chef-manage
#chef-server-ctl reconfigure
#chef-manage-ctl reconfigure

Run these commands to install the reporting feature.

#chef-server-ctl install opscode-reporting
#chef-server-ctl reconfigure
#opscode-reporting-ctl reconfigure

Once installation completed.
Installation Path

/opt/chef
Enable Chef Server Knife Access ports in your Firewall.

TCP Port 4000
Chef Server WebUI
TCP Port 80
TCP Port 443
TCP Port 9462
Run Test Suite

#chef-server-ctl test

Open Chef Server WebUI

https://chef.example.com
The default login information should be over on the right side of the screen:

username: admin
password : p@ssw0rd1

Set new admin password
Thats all..

Login your chef client 192.168.1.161 server.

Install chef client

check the chefclient installation various steps

#wget https://www.getchef.com/chef/install.sh
#./install.sh

Once installation completed, verify your version.

# chef-client -v
Chef: 12.2.1

Now we will start working to communicate with our chef server. To communicate with chef server follow the below steps.

Create a directory named chef inside the /etc directory.

#mkdir /etc/chef

We need to copy the chef-validator.pem file from our chef server. You can find this file in /etc/chef directory of the server. Issue the below command to copy it to our client machine.

#scp root@chef.example.com:/etc/chef/chef-validator.pem /etc/chef/

Now we need a client.rb file in the client machine in which we have to mention about our chef server.

#vi /etc/chef/client.rb

Append the below code to the file

log_level :info
log_location STDOUT
chef_server_url 'https://chef.example.com/'
validation_key "/etc/chef/chef-validator.pem"
validation_client_name 'chef-validator'

or you can configure knife settings using knife command

#knife configure

example :

# cat /root/.chef/knife.rb
log_level :info
log_location STDOUT
node_name 'admin'
client_key '/root/.chef/admin.pem'
validation_client_name 'chef-validator'
validation_key '/etc/chef-server/chef-validator.pem'
chef_server_url 'https://chef.example.com:443'
syntax_check_cache_path '/root/.chef/syntax_check_cache'

client_key : I have copied admin.pem file from chef server ( /etc/chef-server/admin.pem) to chef client /root/.chef/admin.pem
validation_key : I have copied /etc/chef/chef-validator.pem from chef server to /etc/chef-server/chef-validator.pem

Finally we need to register the client with the chef server. Issue the below command to register the client in chef server.

#/usr/bin/chef-client

You are done!!

#knife client list

chef-validator
chef-webui
check your chef server node list

Errors :

[2015-04-01T08:17:12-04:00] INFO: Forking chef instance to converge…
Starting Chef Client, version 12.2.1
[2015-04-01T08:17:12-04:00] INFO: *** Chef 12.2.1 ***
[2015-04-01T08:17:12-04:00] INFO: Chef-client pid: 29241
Creating a new client identity for repos1.example.com using the validator key.
[2015-04-01T08:17:13-04:00] INFO: Client key /etc/chef/client.pem is not present – registering
[2015-04-01T08:17:13-04:00] ERROR: SSL Validation failure connecting to host: chef.example.com – SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

================================================================================
Chef encountered an error attempting to create the client “repos1.example.com”
================================================================================

[2015-04-01T08:17:13-04:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 1.226835116 seconds
[2015-04-01T08:17:13-04:00] ERROR: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
[2015-04-01T08:17:13-04:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
TO FIX THIS ERROR:

If the server you are connecting to uses a self-signed certificate, you must
configure chef to trust that server’s certificate.

By default, the certificate is stored in the following location on the host
where your chef-server runs:

/var/opt/chef-server/nginx/ca/chef.example.com.crt

Copy that file to your trusted_certs_dir (currently: /root/.chef/trusted_certs/)
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server’s certificate is now trusted.

#knife ssl fetch

WARNING: Certificates from chef-server.example.com will be fetched and placed in your trusted_cert
directory ( /root/.chef/trusted_certs/).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

Adding certificate for chef-server.example.com in /var/opt/chef-server/nginx/ca/chef.example.com.crt
The certificate should be verified that what was downloaded is in fact the same as the certificate on the Chef Server. For example, I compared SHA256 checksums:

#ssh root@chef.example.com sha256sum /root/.chef/trusted_certs/chef_example_com.crt
#sha256sum /root/.chef/trusted_certs/chef_example_com.crt

Now check knife client list again.

# knife client list
chef-validator
chef-webui