Private Image Repositories

Deviceplane supports pulling and deploying containers from both public as well as private image repositories, with a little configuration.

Configuration

In order for your devices to pull data from your private image repositories, they need to have access granted to them. You'll need to follow these steps to make this happen:

  1. Push your private image
  2. Create a read-only access key
  3. Format and add the read-only access key to each device

Note: Make sure that your access key is read-only! Devices don't need to have write access, and giving it to them only opens up the possibility of malicious usage if a device is compromised.

Access Key Formatting

The exact process to do so varies based on the hosting provider, but the general idea is to add your credentials, formatted as "username:password", then encoded in base64 format, to the file /etc/deviceplane/registry-auth.

For instance, if your username was "user123", and password/auth token was "passw0rd", this would be encoded as "dXNlcjEyMzpwYXNzdzByZA==", which could be generated by the command echo -n "user123:passw0rd" | base64 > /etc/deviceplane/registry-auth.

If this sounds complex, don't worry. We've included snippets that will give you the correct output for most popular cloud hosting providers.

Hosting Provider Instructions

Docker's DockerHub

Pushing Private Images

Creating a Read-only Key

  • Create new Docker Hub account
  • Add account to your Docker Hub organization with read permissions
  • Check that the read permissions role (https://hub.docker.com/orgs/$YOUR_ORG/teams/read/permissions) actually gives the account read permission to the repository you want access to
  • Create an access token for that account in Dockerhub

Configuring your Device

To generate the value for your /etc/deviceplane/registry-auth file, you can use the following command. Substitute USER with the username of the above account, and TOKEN with the value of the Dockerhub access token for the account:

USER=cyrus TOKEN=123abc echo -n "$USER:$TOKEN" | base64`

Google's GCR

Pushing Private Images

  • Enable GCR in the UI
  • Follow the steps for pushing your image
  • Note: when tagging your image and creating a release, use the full image name, including the hostname. This should look something like gcr.io/example-proj-16521028/demo-go:latest

Creating a Read-only Key

Configuring your Device

GCR authenticates using "_json_key" as the user, and the password as the contents of the JSON key file. So, to generate the value for your /etc/deviceplane/registry-auth file, you can use the following command:

echo -n "_json_key:$(cat keyfile.json)" | base64

Amazon's ECR

Note: AWS's container repository login only works for 12 hours. It also requires using the AWS CLI to generate access keys, and parsing nonstandard output. For these reasons, we generally suggest starting with another container registry for simplicity.

Pushing Private Images

  • Create a repository (select your region)
  • Create a service account with the AmazonEC2ContainerRegistryFullAccess role
  • Download and configure the AWS CLI using the above service account
  • Docker login using the output of aws ecr get-login
  • Push to the given repository
  • Note: when tagging your image and creating a release, use the full image name, including the hostname. This should look something like AWS_ACCOUNT_ID.dkr.ecr.us-west-2.amazonaws.com/demo-go:latest

Creating a Read-only Key

Configuring your Device

Pulling is more complex with AWS ECR. Since container keys expire every 12 hours, we need to update our /etc/deviceplane/registry-auth file on a scheduled basis. The simplest method seems to be doing the following on each device:

  • Download and configure the AWS CLI
  • Write a script to parse the password from the AWS CLI's aws ecr get-login, base64 encode it as described at the top of this page, and pipe it into the /etc/deviceplane/registry-auth file
  • Schedule this script to run using cron or a similar time-based scheduling application

An example script and crontab are as follows:

aws ecr get-login | \
sed -En 's/.*\-u AWS \-p (.+) http.*/\1/p' | \
tr -d '\n' | \
{ echo -n "AWS:"; cat ${1}} | \
base64 >| \
/etc/deviceplane/registry-auth

Save this script in /usr/bin/update-aws-login.sh.

Then sudo crontab -e and add the line, and save and exit the text editor:

0 */6 * * * /usr/bin/update-aws-login.sh

This will run your job every 6 hours. After changing this, restart cron. On Debian-based distros, this command is sudo service cron restart, but it may vary based on your distribution.