Running a local container registry for Execution Environments

Running a local container registry for Execution Environments

After building an execution environment container image, you can push it to a registry and use on your other machines with ansible-navigator or in Ansible AWX/Automation controller jobs.

If you’re unfamiliar with the technology, please take a look at the Getting started with Execution Environments guide.

This wiki post will show you how to set up a basic local container registry for your execution environments as a systemd unit run on behalf of a non-root user.

The shell commands were made on Fedora 33 (yeah, you’re right, I need to update it one day).

Setting up a registry server

We assume you are logged in to your machine as a non-root user with the sudo permission.

1. Install the required packages:

sudo dnf install -y podman httpd-tools

2. Create directories on the host system which will be later mounted in the container running your registry:

mkdir -p ~/registry/{auth,data}

3. Generate a file containing credentials for accessing the registry:

htpasswd -bBc ~/registry/auth/htpasswd myuser mypassword

In the command above, myuser and mypassword can be replaced with any value you want to use as credentials to log in to to the registry.

4. Create a directory to store a systemd unit for the registry container you are about to create and change your location to the directory:

mkdir -p ~/.config/systemd/user && cd ~/.config/systemd/user

5. Run the registry container:

podman run -d --rm --name myregistry -p 5000:5000 \
-v ~/registry/data:/var/lib/registry:z \
-v ~/registry/auth:/auth:ro,z \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
docker.io/library/registry:latest

6. Generate a systemd unit file based on the running myregistry container you created in the previous step.

For podman < 4.4:

podman generate systemd --name myregistry --files --new

For podman 4.4+ use quadlets. You can create a unit file using the podlet utility:

podlet generate container myregistry

7. Stop the myregistry container:

podman stop myregistry

8. Reload systemd and start your registry container as a systemd unit:

systemctl --user daemon-reload
systemctl --user enable --now container-myregistry.service
systemctl --user status container-myregistry.service
loginctl enable-linger

From now on, your registry container will start automatically after system reboot on behalf of your current regular user.

9. Open port 5000 in your firewall:

sudo firewall-cmd --add-port=5000/tcp --permanent
sudo firewall-cmd --reload

10. Reboot your machine and check if systemd has started the unit:

systemctl --user status container-myregistry.service

11. Check the container is running:

podman ps

CONTAINER ID  IMAGE                              COMMAND               CREATED        STATUS          PORTS                   NAMES
31ef59550685  docker.io/library/registry:latest  /etc/docker/regis...  2 seconds ago  Up 3 seconds    0.0.0.0:5000->5000/tcp  myregistry

Your registry now is available by using the myregistry:5000 URL.

Pushing your container image to the registry

1. Log in to your machine where you built your execution environment.

2. Make sure myregistry is resolvable by DNS or the /etc/hosts file from your client to the IP address of your registry machine.

3. Create the registries.conf file and put the following content in it:

mkdir -p ~/.config/containers/
  
cat > ~/.config/containers/registries.conf<<EOF
[[registry]]
location="myregistry:5000"
insecure=true
EOF

4. Log in to the registry:

podman login myregistry:5000

The command will ask you a login and password. Use those you passed to the htpasswd command when setting up the registry.

5. We assume, you have the following execution environment built locally:

podman images

REPOSITORY                                  TAG         IMAGE ID      CREATED      SIZE
localhost/my_ee                             latest      1d39f6a0fbeb  2 weeks ago  388 MB

6. Add tags associated with the registry to the image:

podman tag localhost/my_ee myregistry:5000/my_ee:1.0
podman tag localhost/my_ee myregistry:5000/my_ee:latest

7. Push the execution environments to the registry:

podman push myregistry:5000/my_ee:1.0
podman push myregistry:5000/my_ee:latest

8. List the tags for the image available in the registry:

podman search --list-tags myregistry:5000/my_ee

NAME                           TAG
myregistry:5000/my_ee          1.0
myregistry:5000/my_ee          latest

Now you can similarly log in to the registry from your other machines and run the execution environment with ansible-navigator or in your Ansible AWX/Automation Controller jobs.

Thanks for reading :slightly_smiling_face:

15 Likes

Looks great @Andersson007 !

2 Likes

Oh, I didn’t know that we could create local registries, that’s pretty neat @Andersson007! bookmarking post in 3,2,1… :rocket:

2 Likes

I would probably use -v ~/registry/auth:/auth:ro,z so that the container cannot modify anything in /auth.

5 Likes

@jbericat thanks for the feedback! I’m happy it helps!

@felixfontein thanks for the suggestion! Tested and updated the guide with ro

2 Likes

This is so cool! Thank you

1 Like

Step 6 in creating the registry doesn’t work under Podman 4.4+. You need to use Quadlet. See https://linuxconfig.org/how-to-run-podman-containers-under-systemd-with-quadlet

1 Like

The podlet command can be used to generate the necessary systemd units. See: GitHub - containers/podlet: Generate Podman Quadlet files from a Podman command, compose file, or existing object

1 Like

@hgolden thanks a lot for the feedback! I’ve changed the guide, please take a look. Any further feedback will be much appreciated