diff --git a/services/webapp/code/rosetta/core_app/computing_managers.py b/services/webapp/code/rosetta/core_app/computing_managers.py
index 6fe2a40ff6fc53eba3dfaf8c8137617c970f379c..e130bb85c3c9ae2d1b1b72390fde8ee39a87836f 100644
--- a/services/webapp/code/rosetta/core_app/computing_managers.py
+++ b/services/webapp/code/rosetta/core_app/computing_managers.py
@@ -111,7 +111,7 @@ class InternalSingleNodeComputingManager(SingleNodeComputingManager):
         #run_command += ' -v {}/user-{}:/data'.format(settings.LOCAL_USER_DATA_DIR, task.user.id)
 
         # Host name, image entry command
-        run_command += ' -h task-{} -d -t {}/{}:{}'.format(task.uuid, task.container.registry, task.container.image, task.container.tag)
+        run_command += ' -h task-{} -d -t {}/{}:{}'.format(task.uuid, task.container.registry, task.container.image_name, task.container.image_tag)
 
         # Debug
         logger.debug('Running new task with command="{}"'.format(run_command))
@@ -238,7 +238,7 @@ class SSHSingleNodeComputingManager(SingleNodeComputingManager, SSHComputingMana
             run_command += 'exec nohup singularity run {} --pid --writable-tmpfs --no-home --home=/home/metauser --workdir /tmp/{}_data/tmp -B/tmp/{}_data/home:/home --containall --cleanenv '.format(binds, task.uuid, task.uuid)
             
             # Container part
-            run_command+='docker://{}/{}:{} &>> /tmp/{}_data/task.log & echo \$!"\''.format(task.container.registry, task.container.image, task.container.tag, task.uuid)
+            run_command+='docker://{}/{}:{} &>> /tmp/{}_data/task.log & echo \$!"\''.format(task.container.registry, task.container.image_name, task.container.image_tag, task.uuid)
             
 
         else:
@@ -377,7 +377,7 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag
             run_command += 'exec nohup singularity run {} --pid --writable-tmpfs --no-home --home=/home/metauser --workdir /tmp/{}_data/tmp -B/tmp/{}_data/home:/home --containall --cleanenv '.format(binds, task.uuid, task.uuid)
             
             # Double to escape for Python, six for shell (double times three as \\\ escapes a single slash in shell)
-            run_command+='docker://{}/{}:{} &> \$HOME/{}.log\\" > \$HOME/{}.sh && sbatch {} \$HOME/{}.sh"\''.format(task.container.registry, task.container.image, task.container.tag, task.uuid, task.uuid, sbatch_args, task.uuid)
+            run_command+='docker://{}/{}:{} &> \$HOME/{}.log\\" > \$HOME/{}.sh && sbatch {} \$HOME/{}.sh"\''.format(task.container.registry, task.container.image_name, task.container.image_tag, task.uuid, task.uuid, sbatch_args, task.uuid)
 
         else:
             raise NotImplementedError('Default container runtime "{}" not supported'.format(task.computing.default_container_runtime))
diff --git a/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py b/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
index 3084c8ebad09df303f130f13d7e3a94b1df8760b..a945d05a3f0f50ba4d15023e6f40b5698a347034 100644
--- a/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
+++ b/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
@@ -132,12 +132,12 @@ to provide help, news and informations on your deployment. Or you can just ignor
                                      name     = 'Minimal Desktop ',
                                      description = 'A minimal desktop environment providing basic window management functionalities and a terminal.',
                                      registry = 'docker.io',
-                                     image    = 'sarusso/minimaldesktop',
-                                     tag      = 'v0.2.0',
-                                     arch = 'amd64',
-                                     os = 'linux',
-                                     interface_port     = '8590',
-                                     interface_protocol = 'http',
+                                     image_name = 'sarusso/minimaldesktop',
+                                     image_tag  = 'v0.2.0',
+                                     image_arch = 'amd64',
+                                     image_os   = 'linux',
+                                     interface_port      = '8590',
+                                     interface_protocol  = 'http',
                                      interface_transport = 'tcp/ip',
                                      supports_custom_interface_port = True,
                                      supports_interface_auth = True)
@@ -147,12 +147,12 @@ to provide help, news and informations on your deployment. Or you can just ignor
                                      name     = 'Basic Desktop',
                                      description = 'A basic desktop environment. Provides a terminal, a file manager, a web browser and other generic applications.',
                                      registry = 'docker.io',
-                                     image    = 'sarusso/basicdesktop',
-                                     tag      = 'v0.2.0',
-                                     arch = 'amd64',
-                                     os = 'linux',
-                                     interface_port     = '8590',
-                                     interface_protocol = 'http',
+                                     image_name = 'sarusso/basicdesktop',
+                                     image_tag  = 'v0.2.0',
+                                     image_arch = 'amd64',
+                                     image_os   = 'linux',
+                                     interface_port      = '8590',
+                                     interface_protocol  = 'http',
                                      interface_transport = 'tcp/ip',
                                      supports_custom_interface_port = True,
                                      supports_interface_auth = True,
@@ -164,46 +164,48 @@ to provide help, news and informations on your deployment. Or you can just ignor
                                      name     = 'Jupyter Notebook',
                                      description = 'A Jupyter Notebook server',
                                      registry = 'docker.io',
-                                     image    = 'sarusso/jupyternotebook',
-                                     tag      = 'v0.2.0',
-                                     arch = 'amd64',
-                                     os = 'linux',
-                                     interface_port     = '8888',
-                                     interface_protocol = 'http',
+                                     image_name = 'sarusso/jupyternotebook',
+                                     image_tag  = 'v0.2.0',
+                                     image_arch = 'amd64',
+                                     image_os   = 'linux',
+                                     interface_port      = '8888',
+                                     interface_protocol  = 'http',
                                      interface_transport = 'tcp/ip',
                                      supports_custom_interface_port = True,
                                      supports_interface_auth = True,
                                      interface_auth_user = None)
 
-            # Official Jupyter Lab
-            Container.objects.create(user     = None,
-                                     name     = 'Jupyter Lab',
-                                     description = 'The official Jupyter Lab. The Scipy variant, which includes popular packages from the scientific Python ecosystem.',
-                                     registry = 'docker.io',
-                                     image    = 'jupyter/scipy-notebook',
-                                     tag      = 'lab-3.2.2',
-                                     arch = 'amd64,arm64',
-                                     os = 'linux',
-                                     interface_port     = '8888',
-                                     interface_protocol = 'http',
-                                     interface_transport = 'tcp/ip',
-                                     supports_custom_interface_port = True,
-                                     supports_interface_auth = True)
-
-            Container.objects.create(user     = None,
-                                     name     = 'Jupyter Lab',
-                                     description = 'The official Jupyter Lab. Includes popular packages from the scientific Python ecosystem.',
-                                     registry = 'docker.io',
-                                     image    = 'jupyter/scipy-notebook',
-                                     tag      = 'lab-3.1.17',
-                                     arch = 'amd64,arm64',
-                                     os = 'linux',
-                                     interface_port     = '8888',
-                                     interface_protocol = 'http',
-                                     interface_transport = 'tcp/ip',
-                                     supports_custom_interface_port = True,
-                                     supports_interface_auth = True)
-
+            # Official Jupyter containers
+            for tag in ['lab-3.2.2', 'lab-3.1.17']:
+                
+                Container.objects.create(user     = None,
+                                         name     = 'Jupyter Data Science Lab',
+                                         description = 'The official Jupyter Lab. The Data Science variant, which includes libraries for data analysis from the Julia, Python, and R communities.',
+                                         registry = 'docker.io',
+                                         image_name = 'jupyter/scipy-notebook',
+                                         image_tag  = tag,
+                                         image_arch = None,
+                                         image_os   = None,
+                                         interface_port      = '8888',
+                                         interface_protocol  = 'http',
+                                         interface_transport = 'tcp/ip',
+                                         supports_custom_interface_port = True,
+                                         supports_interface_auth = True)
+                
+                for arch in ['amd64', 'arm64']:
+                    Container.objects.create(user     = None,
+                                             name     = 'Jupyter Lab',
+                                             description = 'The official Jupyter Lab. The Scipy variant, which includes popular packages from the scientific Python ecosystem.',
+                                             registry = 'docker.io',
+                                             image_name = 'jupyter/scipy-notebook',
+                                             image_tag  = tag,
+                                             image_arch = arch,
+                                             image_os   = 'linux',
+                                             interface_port      = '8888',
+                                             interface_protocol  = 'http',
+                                             interface_transport = 'tcp/ip',
+                                             supports_custom_interface_port = True,
+                                             supports_interface_auth = True)
 
 
             # SSH server
@@ -211,10 +213,10 @@ to provide help, news and informations on your deployment. Or you can just ignor
                                      name     = 'SSH server',
                                      description = 'An SSH server supporting X forwarding as well.',
                                      registry = 'docker.io',
-                                     image    = 'sarusso/ssh',
-                                     tag      = 'v0.2.0',
-                                     arch = 'amd64',
-                                     os = 'linux',
+                                     image_name = 'sarusso/ssh',
+                                     image_tag  = 'v0.2.0',
+                                     image_arch = 'amd64',
+                                     image_os   = 'linux',
                                      interface_port     = '22',
                                      interface_protocol = 'ssh',
                                      interface_transport = 'tcp/ip',
diff --git a/services/webapp/code/rosetta/core_app/migrations/0025_auto_20211122_1332.py b/services/webapp/code/rosetta/core_app/migrations/0025_auto_20211122_1332.py
new file mode 100644
index 0000000000000000000000000000000000000000..4be61771093dc932cb2d367e45736f604c04f3d9
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0025_auto_20211122_1332.py
@@ -0,0 +1,38 @@
+# Generated by Django 2.2.1 on 2021-11-22 13:32
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0024_computing_emulated_archs'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='container',
+            old_name='arch',
+            new_name='image_arch',
+        ),
+        migrations.RenameField(
+            model_name='container',
+            old_name='image',
+            new_name='image_name',
+        ),
+        migrations.RenameField(
+            model_name='container',
+            old_name='os',
+            new_name='image_os',
+        ),
+        migrations.RenameField(
+            model_name='container',
+            old_name='tag',
+            new_name='image_tag',
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='image_digest',
+            field=models.CharField(blank=True, max_length=96, null=True, verbose_name='SHA 256 digest'),
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/migrations/0026_auto_20211123_0037.py b/services/webapp/code/rosetta/core_app/migrations/0026_auto_20211123_0037.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e335e86ceaf3ab1ca80d72d76e635e1dd794e43
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0026_auto_20211123_0037.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2.1 on 2021-11-23 00:37
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0025_auto_20211122_1332'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='container',
+            name='image_arch',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Architecture'),
+        ),
+        migrations.AlterField(
+            model_name='container',
+            name='image_os',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Operating system'),
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/models.py b/services/webapp/code/rosetta/core_app/models.py
index 587377fbc3e5a4d7e01ce50702599272699d8fb9..c8eaa4568cd496dc9a4743b9c0c35b9e7b902c8b 100644
--- a/services/webapp/code/rosetta/core_app/models.py
+++ b/services/webapp/code/rosetta/core_app/models.py
@@ -1,5 +1,6 @@
 import uuid
 import json
+import base64
 from django.conf import settings
 from django.db import models
 from django.contrib.auth.models import User, Group
@@ -110,19 +111,22 @@ class Container(models.Model):
     group = models.ForeignKey(Group, related_name='containers', on_delete=models.CASCADE, blank=True, null=True)
     # If a container has no group, it will be available to anyone. Can be created, edited and deleted only by admins.
 
-
     # Generic attributes
     name        = models.CharField('Name', max_length=255, blank=False, null=False)
     description = models.TextField('Description', blank=True, null=True)
     
-    # Registry-related attributes
+    # Registry
     registry = models.CharField('Registry', max_length=255, blank=False, null=False)
-    image    = models.CharField('Image', max_length=255, blank=False, null=False)
-    tag      = models.CharField('Tag', max_length=255, blank=False, null=False, default='latest')
 
-    # Platform-related
-    arch = models.CharField('Architecture', max_length=36, blank=False, null=False, default='x86_64')
-    os   = models.CharField('Operating system', max_length=36, blank=False, null=False, default='linux')
+    # Image name
+    image_name = models.CharField('Image', max_length=255, blank=False, null=False)
+    
+    # Image identifiers
+    image_tag  = models.CharField('Tag', max_length=255, blank=True, null=True, default='latest')
+    image_arch = models.CharField('Architecture', max_length=36, blank=True, null=True)
+    image_os   = models.CharField('Operating system', max_length=36, blank=True, null=True)
+    # -- OR --
+    image_digest  = models.CharField('SHA 256 digest', max_length=96, blank=True, null=True)
     
     # TODO: do we want more control with respect to kernel, CPUs, instruction sets? 
     # requires = i.e. kernel > 3, intel, AVX2
@@ -142,15 +146,29 @@ class Container(models.Model):
 
     def __str__(self):
         user_str = self.user.email if self.user else None
-        return str('Container "{}" of user "{}" with image "{}" and tag "{}" on registry "{}" '.format(self.name, user_str, self.image, self.tag, self.registry))
+        return str('Container "{}" of user "{}" with image name "{}" and image tag "{}" on registry "{}" '.format(self.name, user_str, self.image_name, self.image_tag, self.registry))
+
+    def save(self, *args, **kwargs):
+        # Check that digest starts with sha256:
+        if self.image_digest and not self.image_digest.startswith('sha256:'):
+            raise ValueError('The digest field must start with "sha256:"')
+        
+        super(Container, self).save(*args, **kwargs)
 
-    @ property
+    @property
+    def family_id(self):
+        return base64.b64encode('{}\t{}\t{}'.format(self.name, self.registry, self.image_name).encode('utf8')).decode('utf8')
+
+
+    @property
     def color(self):
-        string_int_hash = hash_string_to_int(self.name + self.registry + self.image)
+        string_int_hash = hash_string_to_int(self.name + self.registry + self.image_name)
         color_map_index = string_int_hash % len(color_map)
         return color_map[color_map_index]
 
 
+
+
 #=========================
 #  Computing resources
 #=========================
diff --git a/services/webapp/code/rosetta/core_app/templates/components/container.html b/services/webapp/code/rosetta/core_app/templates/components/container.html
index c4e167ac1049b59c2329a5fea10cb63748ea6ada..355abf06eb5f93d10d0cbbd8a921860f96bf58f9 100644
--- a/services/webapp/code/rosetta/core_app/templates/components/container.html
+++ b/services/webapp/code/rosetta/core_app/templates/components/container.html
@@ -2,7 +2,12 @@
 
       {% if details %}     
 
-      <table class="dashboard" style="margin:10px; max-width:600px">
+      <div style="width:400px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:15px">
+      <table class="dashboard" style="margin:0px; border:0px; width:398px">
+
+       <tr>
+        <td colspan=2 align=center style="padding:10px; font-size:1.2em"><a href="/software/?container_uuid={{ container.uuid }}">{{ container.name }} <font style="font-size:0.9em">({{ container.image_tag }})</font></a></td>
+       </tr>
         
        <tr>
         <td colspan="2" style="background:{{ container.color }}; height:15px"></td>
@@ -10,41 +15,36 @@
 
        <tr><td colspan=2 style="height:5px"></td></tr>
 
-
        <tr>
-        <td><b>Name</b></td>
-        <td>{{ container.name }}</td>
+        <td colspan=2>{{ container.description }}</td>
        </tr>
 
+       <tr><td colspan=2><hr style="margin:5px"></td></tr>
+
        <tr>
         <td><b>Owner</b></td>
         <td>{% if container.user %}{{ container.user }}{% else %}platform{% endif %}</td>
        </tr>
 
-       <tr>
-        <td><b>Description</b></td>
-        <td>{{ container.description }}</td>
-       </tr>
-
-       <tr><td colspan=2><hr style="margin:5px"></td></tr>
-
        <tr>
         <td><b>Registry</b></td>
         <td>{{ container.registry }}</td>
        </tr>
 
        <tr>
-        <td><b>Image</b></td>
-        <td><code>{{ container.image }}</code></td>
+        <td><b>Image&nbsp;name</b></td>
+        <td><code>{{ container.image_name }}</code></td>
        </tr>
 
        <tr>
-        <td><b>Tag</b></td>
-        <td>{{ container.tag }}</td>
+        <td><b>Image tag</b></td>
+        <td><span class="badge badge-secondary">{{ container.image_tag }}</span></td>
        </tr>
 
        <tr><td colspan=2><hr style="margin:5px"></td></tr>
-
+       </table>
+       
+      <table class="dashboard" style="margin:0px; border:0px;">
        <tr>
         <td><b>Interface protocol</b></td>
         <td>{{ container.interface_protocol }}</td>
@@ -61,13 +61,18 @@
        </tr>
 
        <tr>
-        <td><b>Architecture</b></td>
-        <td>{{ container.arch }}</td>
+        <td><b>Image arch</b></td>
+        <td>{{ container.image_arch }}</td>
        </tr>
 
        <tr>
-        <td><b>Operating System</b></td>
-        <td>{{ container.os }}</td>
+        <td><b>Image OS</b></td>
+        <td>{{ container.image_os }}</td>
+       </tr>
+
+       <tr>
+        <td><b>Image digest</b></td>
+        <td>{{ container.image_digest }}</td>
        </tr>
 
        <tr><td colspan=2><hr style="margin:5px"></td></tr>
@@ -101,7 +106,7 @@
        </tr>
        {% endif %}
       </table>
-      <br/>
+      </div>
       
       
       {% else %}
@@ -109,7 +114,7 @@
 
         
         <div style="padding:10px; margin-top:5px; text-align:center; border-bottom: {{container.color}} solid 10px; ">
-        <a href="/software/container_?uuid={{ container.uuid }}">{{ container.name }}</a>&nbsp; 
+        <a href="/software/?container_uuid={{ container.uuid }}">{{ container.name }}</a>&nbsp; 
         </div>
         
         <div style="padding:10px; height: 110px; vertical-align: middle; ">
@@ -124,8 +129,13 @@
         
         <div class="image-version-box">
         <!-- <font style="font-family:monospace; font-size:1.2em"></font> -->
-        <b>Image:</b> <code>{{ container.image }}</code><br/>
-        <b>Tag:</b> &nbsp;{{ container.tag }} &nbsp;<b>Arch:</b> {{container_arch}}
+        <b>Image:</b> <code>{{ container.image_name }}</code><br/>
+        <b>Tag:</b> &nbsp;<span class="badge badge-secondary" style="margin-right:3px">{{ container.image_tag }}</span>
+        {% if container.image_arch %}
+        <font style="font-size:0.9em">({{ container.image_arch }})</font>
+        {% endif %}
+        
+        <!--  &nbsp; <b>Arch:</b> {{ container.image_arch }} -->
         </div> 
        
         </div>
diff --git a/services/webapp/code/rosetta/core_app/templates/components/container_family.html b/services/webapp/code/rosetta/core_app/templates/components/container_family.html
index 043523a2b4304e2337a692f1a99fd174c73cbc69..f8e80181b9570a16421fea999758f88d83020dfb 100644
--- a/services/webapp/code/rosetta/core_app/templates/components/container_family.html
+++ b/services/webapp/code/rosetta/core_app/templates/components/container_family.html
@@ -27,23 +27,60 @@
         {% endif %}
         
         <div class="image-version-box">
-        <b>Image:</b> <code>{{ container_family.image }}</code><br/>
+        <b>Image:</b> <code>{{ container_family.image_name }}</code><br/>
         <div style="margin-top:2px">
         
-        <span style="vertical-align:top;"><b>Tag:</b>&nbsp;</span>
+        <!-- <span style="vertical-align:top;"><b>Tag:</b>&nbsp;</span>
         <select name="task_container_uuid" style="font-size:0.8em">
         {% for container in container_family.members %}
-        <option value="{{ container.uuid }}">{{ container.tag }}</option>
+        <option value="{{ container.uuid }}">{{ container.image_tag }} ({{ container.image_arch }})</option>
+        {% endfor %}
+        </select> -->
+
+        <!--<span style="vertical-align:top; margin-left:0px"><b>Tag:</b>&nbsp;</span>
+        <select name="task_container" style="font-size:0.8em">
+        {% for arch,container_by_tags in container_family.container_by_tags_by_arch.items %}
+        {% if not arch %}
+        {% for tag,container in container_by_tags.items %}
+        <option value="family:{{ container_family_id }},tag:{{ tag }}">{{ tag }}</option>
+        {% endfor %}
+        {% endif %}
         {% endfor %}
-        </select>
 
-        <span style="vertical-align:top; margin-left:5px"><b>Arch:</b>&nbsp;</span>
-        <select name="task_container_arch" style="font-size:0.8em">
-        <option value="auto" selected>auto</option>
+        {% for arch,container_by_tags in container_family.container_by_tags_by_arch.items %}
+        {% if arch %}
+        <optgroup label="{{ arch }}">
+        {% for tag,container in container_by_tags.items %}
+        <option value="uuid:{{ container.uuid }}">{{ tag }}</option>
+        {% endfor %}
+        {% endif %}
+        {% endfor %}
+        </optgroup>-->
 
-        {% for arch in container_family.all_archs %}
-        <option value="{{ arch }}">{{ arch }}</option>
+
+        <span style="vertical-align:top; margin-left:0px"><b>Tag:</b>&nbsp;</span>
+        <select name="task_container_uuid" style="font-size:0.8em">
+        {% for arch,container_by_tags in container_family.container_by_tags_by_arch.items %}
+        {% if not arch %}
+        {% for tag,container in container_by_tags.items %}
+        <option value="{{container.uuid}}">{{ tag }}</option>
         {% endfor %}
+        {% endif %}
+        {% endfor %}
+
+        {% for arch,container_by_tags in container_family.container_by_tags_by_arch.items %}
+        {% if arch %}
+        <optgroup label="{{ arch }}">
+        {% for tag,container in container_by_tags.items %}
+        <option value="{{container.uuid}}">{{ tag }}</option>
+        {% endfor %}
+        {% endif %}
+        {% endfor %}
+        </optgroup>
+
+
+   
+
         </select>
 
             
diff --git a/services/webapp/code/rosetta/core_app/templates/software.html b/services/webapp/code/rosetta/core_app/templates/software.html
index b5094966c39a8706b89c225b1291705942bcefc2..4b9223bae72d2eac9a76c151044d202db3f0d182 100644
--- a/services/webapp/code/rosetta/core_app/templates/software.html
+++ b/services/webapp/code/rosetta/core_app/templates/software.html
@@ -9,11 +9,11 @@
   <div class="dashboard">
     <div class="span8 offset2">
       
-      {% if data.details %}
+      {% if data.details or data.container %}
       {% if data.container_families %}
       <h1><a href="/software">Software containers</a> <span style="font-size:18px"> / {{ data.containers.0.name }}</span></h1>
-      {% else %}
-      <h1><a href="/software">Software containers</a> <span style="font-size:18px"> / {{ data.container.name }}</span></h1>
+      {% else %}      
+      <h1><a href="/software">Software containers</a> <span style="font-size:18px"> / <a href="/software/?container_family_id={{data.container.family_id}}&details=True">{{ data.container.name }}</a> / {{ data.container.image_tag}}</span></h1>
       {% endif %}
       {% else %}
       {% if data.mode == 'new_task' %}
diff --git a/services/webapp/code/rosetta/core_app/views.py b/services/webapp/code/rosetta/core_app/views.py
index 1f6c35cf9bb70b92ecf7b9ad2c7195c2e1b3d2d6..bd1bd898c953ffbbf3ab8c86747df66282f03650 100644
--- a/services/webapp/code/rosetta/core_app/views.py
+++ b/services/webapp/code/rosetta/core_app/views.py
@@ -507,7 +507,6 @@ def new_task(request):
         
         # Get software container and arch
         data['task_container'] = get_task_container(request)
-        data['task_container_arch'] = get_task_container_arch(request)
 
         # List all computing resources 
         data['computings'] = list(Computing.objects.filter(group=None)) + list(Computing.objects.filter(group__user=request.user))
@@ -519,24 +518,27 @@ def new_task(request):
 
         # Get software container and arch
         data['task_container'] = get_task_container(request)
-        data['task_container_arch'] = get_task_container_arch(request)
 
         # Get computing resource
         data['task_computing'] = get_task_computing(request)
         
         # Check that container required architecture is compatible with the computing resource
-        if data['task_container_arch'] != 'auto':
-            if data['task_container_arch'] != data['task_computing'].arch:
+        if data['task_container'].image_arch:
+            if data['task_container'].image_arch != data['task_computing'].arch:
                 # TODO: support setting the container runtime when creating the task
                 # TODO: refactor and unroll this code
-                container_runtime = data['task_computing'].container_runtimes[0]
-                if container_runtime in data['task_computing'].emulated_archs and data['task_container_arch'] in data['task_computing'].emulated_archs[container_runtime]:
-                    data['arch_emulation'] = True
+                # TODO: add support for setting the container runtime
+                if data['task_computing'].emulated_archs:
+                    container_runtime = data['task_computing'].container_runtimes[0]
+                    if container_runtime in data['task_computing'].emulated_archs and data['task_container'].image_arch in data['task_computing'].emulated_archs[container_runtime]:
+                        data['arch_emulation'] = True
+                    else:
+                        raise ErrorMessage('This computing resource does not support architecture "{}" nor as native or emulated'.format(data['task_container'].image_arch))
                 else:
-                    raise ErrorMessage('This computing resource does not support architecture "{}" nor as native or emulated'.format(data['task_container_arch']))
+                    raise ErrorMessage('This computing resource does not support architecture "{}" nor as native or emulated'.format(data['task_container'].image_arch))
 
         else:
-            raise ErrorMessage('Auto architectures are not supported yet')
+            raise ErrorMessage('Auto detecting architectures is not supported yet')
             
         
         # Generate random auth token        
@@ -767,82 +769,92 @@ def software(request):
             logger.error('Error in getting container with uuid="{}" or performing the required action: "{}"'.format(uuid, e))
             return render(request, 'error.html', {'data': data})
     
-    # Or, do we have to operate on a container family?
-    elif container_family_id:
-        
-        # Get back name, registry and image from contsainer url
-        container_name, container_registry, container_image = base64.b64decode(container_family_id.encode('utf8')).decode('utf8').split('\t')
-      
-        # get containers from the DB
-        user_containers = Container.objects.filter(user=request.user, name=container_name, registry=container_registry, image=container_image)
-        platform_containers = Container.objects.filter(user=None, name=container_name, registry=container_registry, image=container_image)
-    
-    else:    
-        
-        # Get containers (fitered by search term, or all)
-        if search_text:
-            search_query=(Q(name__icontains=search_text) | Q(description__icontains=search_text) | Q(image__icontains=search_text))
-            user_containers = Container.objects.filter(search_query, user=request.user)
-            platform_containers = Container.objects.filter(search_query, user=None)
-        else:
-            user_containers = Container.objects.filter(user=request.user)
-            platform_containers = Container.objects.filter(user=None)
-
-        
-    # Ok, nilter by owner
-    if search_owner != 'All':
-        if search_owner == 'User':
-            platform_containers =[]
-        if search_owner == 'Platform':
-            user_containers = []
+    else:
+        # Ddo we have to operate on a container family?
+        if container_family_id:
             
-    # Create all container list
-    data['containers'] = list(user_containers) + list(platform_containers)
+            # Get back name, registry and image from contsainer url
+            container_name, container_registry, container_image_name = base64.b64decode(container_family_id.encode('utf8')).decode('utf8').split('\t')
+          
+            # get containers from the DB
+            user_containers = Container.objects.filter(user=request.user, name=container_name, registry=container_registry, image_name=container_image_name)
+            platform_containers = Container.objects.filter(user=None, name=container_name, registry=container_registry, image_name=container_image_name)
         
-    # Merge containers with the same name, registry and image
-    data['container_families'] = {}
-    
-    # Container family support class
-    class ContainerFamily(object):
+        else:    
+            
+            # Get containers (fitered by search term, or all)
+            if search_text:
+                search_query=(Q(name__icontains=search_text) | Q(description__icontains=search_text) | Q(image_name__icontains=search_text))
+                user_containers = Container.objects.filter(search_query, user=request.user)
+                platform_containers = Container.objects.filter(search_query, user=None)
+            else:
+                user_containers = Container.objects.filter(user=request.user)
+                platform_containers = Container.objects.filter(user=None)
     
-        def __init__(self, id, name, registry, image):
-            self.id = id
-            self.name = name
-            self.registry = registry
-            self.image = image
-            self.description = None
-            self.members = []
-            self.all_archs = []
-            self.container_by_tags_by_arch = {} 
-
-        def add(self, container):
-            self.members.append(container)
-
-            if not self.description:
-                self.description = container.description
             
-            for arch in container.arch.split(','):
+        # Ok, nilter by owner
+        if search_owner != 'All':
+            if search_owner == 'User':
+                platform_containers =[]
+            if search_owner == 'Platform':
+                user_containers = []
                 
-                if not arch in self.all_archs:
-                    self.all_archs.append(arch)
-                if not arch in self.container_by_tags_by_arch:
-                    self.container_by_tags_by_arch[arch]={}
-                self.container_by_tags_by_arch[arch][container.tag] = container
+        # Create all container list
+        data['containers'] = list(user_containers) + list(platform_containers)
+            
+        # Merge containers with the same name, registry and image name
+        data['container_families'] = {}
         
-        @ property
-        def color(self):
-            try:
-                return self.members[0].color
-            except IndexError:
-                return '#000000'
+        # Container family support class
+        class ContainerFamily(object):
         
-    # Populate container families
-    for container in data['containers']:
-        container_family_id = base64.b64encode('{}\t{}\t{}'.format(container.name, container.registry, container.image).encode('utf8')).decode('utf8')
-        if container_family_id not in data['container_families']:
-            data['container_families'][container_family_id] = ContainerFamily(container_family_id, container.name, container.registry, container.image)
-        data['container_families'][container_family_id].add(container)    
+            def __init__(self, id, name, registry, image_name):
+                self.id = id
+                self.name = name
+                self.registry = registry
+                self.image_name = image_name
+                self.description = None
+                self.members = []
+                self.all_archs = []
+                self.container_by_tags_by_arch = {} 
+    
+            def add(self, container):
+                self.members.append(container)
+    
+                if not self.description:
+                    self.description = container.description
+    
+                if not container.image_arch in self.all_archs:
+                    self.all_archs.append(container.image_arch)
+    
+                if not container.image_arch in self.container_by_tags_by_arch:
+                    self.container_by_tags_by_arch[container.image_arch]={}
+                self.container_by_tags_by_arch[container.image_arch][container.image_tag] = container
+                
+                # Lastly, add the container to the "all tags"
+                #if None not in self.container_by_tags_by_arch:
+                #    self.container_by_tags_by_arch[None]={}
+                #self.container_by_tags_by_arch[None][container.image_tag] = container
+    
             
+            @ property
+            def color(self):
+                try:
+                    return self.members[0].color
+                except IndexError:
+                    return '#000000'
+            
+        # Populate container families
+        for container in data['containers']:
+            if container.family_id not in data['container_families']:
+                data['container_families'][container.family_id] = ContainerFamily(container.family_id, container.name, container.registry, container.image_name)
+            data['container_families'][container.family_id].add(container)
+        # Finalize the families
+        #for container.family_id in data['container_families']:
+        #    if len(data['container_families'][container.family_id].all_archs) == 1:
+        #        if data['container_families'][container.family_id].all_archs[0] != None:
+        #            data['container_families'][container.family_id].container_by_tags_by_arch.pop(None)
+                
     return render(request, 'software.html', {'data': data})
 
 
@@ -869,17 +881,17 @@ def add_software(request):
         # Container registry
         container_registry = request.POST.get('container_registry', None)
 
-        # Container image
-        container_image = request.POST.get('container_image',None)
+        # Container image name
+        container_image_name = request.POST.get('container_image_name',None)
         
         # Container tag
-        container_tag = request.POST.get('container_tag', None)
+        container_image_tag = request.POST.get('container_image_tag', None)
 
         # Container architecture
-        container_arch = request.POST.get('container_arch')
+        container_image_arch = request.POST.get('container_image_arch')
 
         # Container operating system
-        container_os = request.POST.get('container_os')
+        container_image_os = request.POST.get('container_image_os')
 
         # Container interface port
         container_interface_port = request.POST.get('container_interface_port', None) 
@@ -921,10 +933,10 @@ def add_software(request):
                                  name        = container_name,
                                  description = container_description,
                                  registry    = container_registry,
-                                 image       = container_image,
-                                 tag         = container_tag,
-                                 arch        = container_arch,
-                                 os          = container_os,
+                                 image_name  = container_image_name,
+                                 image_tag   = container_image_tag,
+                                 image_arch  = container_image_arch,
+                                 image_os    = container_image_os,
                                  interface_port      = container_interface_port,
                                  interface_protocol  = container_interface_protocol,
                                  interface_transport = container_interface_transport,