diff --git a/images/webapp/code/rosetta/base_app/models.py b/images/webapp/code/rosetta/base_app/models.py
index 6c1603c9ca1f6910bee5e1fcec50c7f95f535699..9a20326612a7e94946570c82b4cb73df58a23cd7 100644
--- a/images/webapp/code/rosetta/base_app/models.py
+++ b/images/webapp/code/rosetta/base_app/models.py
@@ -25,6 +25,7 @@ class TaskStatuses(object):
 #=========================
 
 class Profile(models.Model):
+    uuid      = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
     user      = models.OneToOneField(User, on_delete=models.CASCADE)
     timezone  = models.CharField('User Timezone', max_length=36, default='UTC')
     authtoken = models.CharField('User auth token', max_length=36, blank=True, null=True)
@@ -43,6 +44,7 @@ class Profile(models.Model):
 #=========================
 
 class LoginToken(models.Model):
+    uuid  = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
     user  = models.OneToOneField(User, on_delete=models.CASCADE)
     token = models.CharField('Login token', max_length=36)
 
@@ -51,16 +53,16 @@ class LoginToken(models.Model):
 #  Tasks 
 #=========================
 class Task(models.Model):
-    user      = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE)
-    tid       = models.CharField('Task ID', max_length=64, blank=False, null=False)
-    uuid      = models.CharField('Task UUID', max_length=36, blank=False, null=False)
-    name      = models.CharField('Task name', max_length=36, blank=False, null=False)
-    status    = models.CharField('Task status', max_length=36, blank=True, null=True)
-    created   = models.DateTimeField('Created on', default=timezone.now)
-    compute   = models.CharField('Task compute', max_length=36, blank=True, null=True)
-    pid       = models.IntegerField('Task pid', blank=True, null=True)
-    port      = models.IntegerField('Task port', blank=True, null=True)
-    ip        = models.CharField('Task ip address', max_length=36, blank=True, null=True)
+    uuid     = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
+    user     = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE)
+    tid      = models.CharField('Task ID', max_length=64, blank=False, null=False)
+    name     = models.CharField('Task name', max_length=36, blank=False, null=False)
+    status   = models.CharField('Task status', max_length=36, blank=True, null=True)
+    created  = models.DateTimeField('Created on', default=timezone.now)
+    compute  = models.CharField('Task compute', max_length=36, blank=True, null=True)
+    pid      = models.IntegerField('Task pid', blank=True, null=True)
+    port     = models.IntegerField('Task port', blank=True, null=True)
+    ip       = models.CharField('Task ip address', max_length=36, blank=True, null=True)
     tunnel_port = models.IntegerField('Task tunnel port', blank=True, null=True)
 
     # Links
@@ -105,7 +107,7 @@ class Task(models.Model):
 
     @property
     def short_uuid(self):
-        return self.uuid.split('-')[0]
+        return str(self.uuid).split('-')[0]
 
 
 #=========================
@@ -113,8 +115,9 @@ class Task(models.Model):
 #=========================
 class Container(models.Model):
 
-    #uuid           = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
-    user           = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, null=True)
+    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
+    user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, null=True)
+    
     # If a container has no user, it will be available to anyone. Can be created, edited and deleted only by admins.
     image         = models.CharField('Container image', max_length=255, blank=False, null=False)
     type          = models.CharField('Container type', max_length=36, blank=False, null=False)
diff --git a/images/webapp/code/rosetta/base_app/templates/add_container.html b/images/webapp/code/rosetta/base_app/templates/add_container.html
index 0ca208b8a3f3d90a197d5e165faf5021e95891df..b4758e82b56fac603768f7915e6d039fbaa76b95 100644
--- a/images/webapp/code/rosetta/base_app/templates/add_container.html
+++ b/images/webapp/code/rosetta/base_app/templates/add_container.html
@@ -78,7 +78,7 @@
 
  
       {% else %}
-        Ok, Container added. Go back to your <a href="/tasks">tasks list</a>.
+        Ok, Container added. Go back to your <a href="/containers">container list</a>.
         
 
       {% endif %} 
diff --git a/images/webapp/code/rosetta/base_app/templates/containers.html b/images/webapp/code/rosetta/base_app/templates/containers.html
index 24fd1b15ff331c0e9e7bbd55b61bf64d1eb1f3e2..f5b893ce73761acf608fac9ea20a385682df75ef 100644
--- a/images/webapp/code/rosetta/base_app/templates/containers.html
+++ b/images/webapp/code/rosetta/base_app/templates/containers.html
@@ -8,7 +8,7 @@
 <div class="container">
   <div class="dashboard">
     <div class="span8 offset2">
-      <h1>Containers List</h1>
+      <h1>Container List</h1>
       <hr/>
 
              
@@ -63,6 +63,11 @@
         <td>{{ container.service_ports}}</td>
        </tr>
 
+       <tr>
+        <td><b>Operations</b></td>
+        <td><a href="?action=delete&uuid={{ container.uuid }}">Delete</a></td>
+       </tr>
+
       </table>
       <br />
       {% endfor %}    
diff --git a/images/webapp/code/rosetta/base_app/templates/create_task.html b/images/webapp/code/rosetta/base_app/templates/create_task.html
index 4148c3dad080484071e30c0ed0a9202bf53bfde8..c1cd016235d469d7d13a27635ec84a6e22c62f10 100644
--- a/images/webapp/code/rosetta/base_app/templates/create_task.html
+++ b/images/webapp/code/rosetta/base_app/templates/create_task.html
@@ -46,15 +46,15 @@
 
            <tr>
             <td><b>Task container</b></td><td>
-              <select name="task_container_id" >
+              <select name="task_container_uuid" >
               <!-- <option value="metadesktop" selected>Meta Desktop</option>
               <option value="astroccok">Astrocook</option>
               <option value="gadgetviewer">Gadget Viewer</option> -->
               {% for container in data.platform_containers %}
-              <option value="{{container.id}}">{{container.image}} (platform)</option> -->
+              <option value="{{container.uuid}}">{{container.image}} (platform)</option> -->
               {% endfor %}
               {% for container in data.user_containers %}
-              <option value="{{container.id}}">{{container.image}} (user)</option> -->
+              <option value="{{container.uuid}}">{{container.image}} (user)</option> -->
               {% endfor %}              
               
               </select>
@@ -103,7 +103,7 @@
 
  
       {% else %}
-        Ok, task created. Go back to your <a href="/tasks">tasks list</a>.
+        Ok, task created. Go back to your <a href="/tasks">task list</a>.
         
 
       {% endif %} 
diff --git a/images/webapp/code/rosetta/base_app/views.py b/images/webapp/code/rosetta/base_app/views.py
index e185e0f27f42aa33f0d21e02c69aa39b19206204..3fdb3b457a04495cb80a6eed78ee4e0b2593edfd 100644
--- a/images/webapp/code/rosetta/base_app/views.py
+++ b/images/webapp/code/rosetta/base_app/views.py
@@ -7,7 +7,7 @@ import json
 import socket
 import os
 import subprocess
-                
+
 # Django imports
 from django.conf import settings
 from django.shortcuts import render
@@ -32,7 +32,7 @@ from .exceptions import ErrorMessage, ConsistencyException
 
 # Conf
 SUPPORTED_CONTAINER_TYPES = ['docker', 'singularity']
-SUPPORTED_REGISTRIES = ['docker_local', 'docker_hub', 'signularity_hub'] 
+SUPPORTED_REGISTRIES = ['docker_local', 'docker_hub', 'signularity_hub']
 TASK_DATA_DIR = "/data"
 
 #=========================
@@ -45,7 +45,7 @@ def public_view(wrapped_view):
         # -------------- START Public/private common code --------------
         try:
             log_user_activity("DEBUG", "Called", request, wrapped_view.__name__)
-            
+
             # Try to get the templates from view kwargs
             # Todo: Python3 compatibility: https://stackoverflow.com/questions/2677185/how-can-i-read-a-functions-signature-including-default-argument-values
 
@@ -55,10 +55,10 @@ def public_view(wrapped_view):
                 template = argSpec.defaults[0]
             else:
                 template = None
-            
+
             # Call wrapped view
             data = wrapped_view(request, *argv, **kwargs)
-            
+
             if not isinstance(data, HttpResponse):
                 if template:
                     #logger.debug('using template + data ("{}","{}")'.format(template,data))
@@ -72,21 +72,21 @@ def public_view(wrapped_view):
         except Exception as e:
             if isinstance(e, ErrorMessage):
                 error_text = str(e)
-            else: 
-                
+            else:
+
                 # Raise te exception if we are in debug mode
                 if settings.DEBUG:
                     raise
-                    
+
                 # Otherwise,
                 else:
-                    
+
                     # first log the exception
                     logger.error(format_exception(e))
-                    
+
                     # and then mask it.
                     error_text = 'something went wrong'
-                    
+
             data = {'user': request.user,
                     'title': 'Error',
                     'error' : 'Error: "{}"'.format(error_text)}
@@ -95,7 +95,7 @@ def public_view(wrapped_view):
                 return render(request, template, {'data': data})
             else:
                 return render(request, 'error.html', {'data': data})
-        # --------------  END Public/private common code --------------        
+        # --------------  END Public/private common code --------------
     return public_view_wrapper
 
 # Private view
@@ -105,20 +105,20 @@ def private_view(wrapped_view):
             # -------------- START Public/private common code --------------
             log_user_activity("DEBUG", "Called", request, wrapped_view.__name__)
             try:
-                
+
                 # Try to get the templates from view kwargs
                 # Todo: Python3 compatibility: https://stackoverflow.com/questions/2677185/how-can-i-read-a-functions-signature-including-default-argument-values
-    
+
                 argSpec=inspect.getargspec(wrapped_view)
-    
+
                 if 'template' in argSpec.args:
                     template = argSpec.defaults[0]
                 else:
                     template = None
-                
+
                 # Call wrapped view
                 data = wrapped_view(request, *argv, **kwargs)
-                
+
                 if not isinstance(data, HttpResponse):
                     if template:
                         #logger.debug('using template + data ("{}","{}")'.format(template,data))
@@ -128,25 +128,25 @@ def private_view(wrapped_view):
                 else:
                     #logger.debug('using returned httpresponse')
                     return data
-    
-            except Exception as e:    
+
+            except Exception as e:
                 if isinstance(e, ErrorMessage):
                     error_text = str(e)
-                else: 
-                    
+                else:
+
                     # Raise te exception if we are in debug mode
                     if settings.DEBUG:
                         raise
-                        
+
                     # Otherwise,
                     else:
-                        
+
                         # first log the exception
                         logger.error(format_exception(e))
-                        
+
                         # and then mask it.
                         error_text = 'something went wrong'
-                        
+
                 data = {'user': request.user,
                         'title': 'Error',
                         'error' : 'Error: "{}"'.format(error_text)}
@@ -159,7 +159,7 @@ def private_view(wrapped_view):
 
         else:
             log_user_activity("DEBUG", "Redirecting to login since not authenticated", request)
-            return HttpResponseRedirect('/login')               
+            return HttpResponseRedirect('/login')
     return private_view_wrapper
 
 
@@ -167,14 +167,14 @@ def private_view(wrapped_view):
 
 @public_view
 def login_view(request):
-    
+
     data = {}
     data['title'] = "{} - Login".format(settings.DJANGO_PROJECT_NAME)
 
     # If authenticated user reloads the main URL
     if request.method == 'GET' and request.user.is_authenticated:
         return HttpResponseRedirect('/main/')
-    
+
     # If unauthenticated user tries to log in
     if request.method == 'POST':
         if not request.user.is_authenticated:
@@ -182,7 +182,7 @@ def login_view(request):
             password = request.POST.get('password')
             # Use Django's machinery to attempt to see if the username/password
             # combination is valid - a User object is returned if it is.
-            
+
             if "@" in username:
                 # Get the username from the email
                 try:
@@ -195,7 +195,7 @@ def login_view(request):
                         # Return here, we don't want to give any hints about existing users
                         data['success'] = 'Ok, if we have your data you will receive a login link by email shortly.'
                         return render(request, 'success.html', {'data': data})
-            
+
             if password:
                 user = authenticate(username=username, password=password)
                 if user:
@@ -204,16 +204,16 @@ def login_view(request):
                 else:
                     raise ErrorMessage('Check email and password')
             else:
-                
+
                 # If empty password, send mail with login token
                 logger.debug('Sending login token via mail to {}'.format(user.email))
-                
+
                 token = uuid.uuid4()
-                
+
                 # Create token or update if existent (and never used)
                 try:
                     loginToken = LoginToken.objects.get(user=user)
-                except LoginToken.DoesNotExist:     
+                except LoginToken.DoesNotExist:
                     LoginToken.objects.create(user=user, token=token)
                 else:
                     loginToken.token = token
@@ -223,49 +223,49 @@ def login_view(request):
                 except Exception as e:
                     logger.error(format_exception(e))
                     raise ErrorMessage('Something went wrong. Please retry later.')
-               
+
                 # Return here, we don't want to give any hints about existing users
                 data['success'] = 'Ok, if we have your data you will receive a login link by email shortly.'
                 return render(request, 'success.html', {'data': data})
-                    
-                
+
+
         else:
             # This should never happen.
             # User tried to log-in while already logged in: log him out and then render the login
-            logout(request)        
-              
+            logout(request)
+
     else:
         # If we are logging in through a token
         token = request.GET.get('token', None)
 
         if token:
-            
+
             loginTokens = LoginToken.objects.filter(token=token)
-            
+
             if not loginTokens:
                 raise ErrorMessage('Token not valid or expired')
-    
-            
+
+
             if len(loginTokens) > 1:
                 raise Exception('Consistency error: more than one user with the same login token ({})'.format(len(loginTokens)))
-            
+
             # Use the first and only token (todo: use the objects.get and correctly handle its exceptions)
             loginToken = loginTokens[0]
-            
+
             # Get the user from the table
             user = loginToken.user
-            
+
             # Set auth backend
             user.backend = 'django.contrib.auth.backends.ModelBackend'
-    
+
             # Ok, log in the user
             login(request, user)
             loginToken.delete()
-            
+
             # Now redirect to site
             return HttpResponseRedirect('/main/')
 
-                
+
     # All other cases, render the login page again with no other data than title
     return render(request, 'login.html', {'data': data})
 
@@ -277,7 +277,7 @@ def logout_view(request):
 
 @public_view
 def entrypoint(request):
-    return HttpResponseRedirect('/main/')  
+    return HttpResponseRedirect('/main/')
 
 @public_view
 def main_view(request):
@@ -303,7 +303,7 @@ def account(request):
     try:
         profile = Profile.objects.get(user=request.user)
     except Profile.DoesNotExist:
-        profile = Profile.objects.create(user=request.user)  
+        profile = Profile.objects.create(user=request.user)
     data['profile'] = profile
     data['title'] = "{} - Account".format(settings.DJANGO_PROJECT_NAME)
 
@@ -313,50 +313,50 @@ def account(request):
         edit = request.GET.get('edit', None)
         data['edit'] = edit
     value = request.POST.get('value', None)
-    
+
     # Fix None
     if value and value.upper() == 'NONE':
         value = None
     if edit and edit.upper() == 'NONE':
         edit = None
-    
+
     # Edit values
     if edit and value:
         try:
             logger.info('Setting "{}" to "{}"'.format(edit,value))
-            
+
             # Timezone
             if edit=='timezone' and value:
                 # Validate
                 timezonize(value)
                 profile.timezone = value
                 profile.save()
-    
+
             # Email
             elif edit=='email' and value:
                 request.user.email=value
                 request.user.save()
-    
+
             # Password
             elif edit=='password' and value:
                 request.user.set_password(value)
                 request.user.save()
-    
+
             # API key
             elif edit=='apikey' and value:
                 profile.apikey=value
                 profile.save()
-    
+
             # Plan
             elif edit=='plan' and value:
                 profile.plan=value
                 profile.save()
-            
+
             # Generic property
             elif edit and value:
                 raise Exception('Attribute to change is not valid')
-    
-                   
+
+
         except Exception as e:
             logger.error(format_exception(e))
             data['error'] = 'The property "{}" does not exists or the value "{}" is not valid.'.format(edit, value)
@@ -379,7 +379,7 @@ def tasks(request):
     data['user']  = request.user
     data['profile'] = Profile.objects.get(user=request.user)
     data['title'] = 'Tasks'
-    
+
     # Get action if any
     action = request.GET.get('action', None)
     uuid = request.GET.get('uuid', None)
@@ -396,11 +396,11 @@ def tasks(request):
         if action=='delete':
             if task.status not in [TaskStatuses.stopped, TaskStatuses.exited]:
                 data['error'] = 'Can delete only tasks in the stopped state'
-                return render(request, 'error.html', {'data': data})  
+                return render(request, 'error.html', {'data': data})
             try:
                 # Get the task (raises if none available including no permission)
                 task = Task.objects.get(user=request.user, uuid=uuid)
-                
+
                 # Delete
                 task.delete()
 
@@ -410,39 +410,38 @@ def tasks(request):
             except Exception as e:
                 data['error'] = 'Error in deleting the task'
                 logger.error('Error in deleting task with uuid="{}": "{}"'.format(uuid, e))
-                return render(request, 'error.html', {'data': data})  
-        
+                return render(request, 'error.html', {'data': data})
+
         elif action=='stop': # or delete,a and if delete also remove object
             try:
 
                 if task.compute == 'local':
-                    str_shortuuid = task.uuid.split('-')[0]
-    
+
                     # Delete the Docker container
                     if standby_supported:
                         stop_command = 'sudo docker stop {}'.format(task.tid)
                     else:
                         stop_command = 'sudo docker stop {} && sudo docker rm {}'.format(task.tid,task.tid)
-    
+
                     out = os_shell(stop_command, capture=True)
-                    if out.exit_code != 0:                        
+                    if out.exit_code != 0:
                         raise Exception(out.stderr)
-                    
+
                 elif task.compute == 'demoremote':
-                    
+
                     # Stop the task remotely
                     stop_command = 'ssh -4 -o StrictHostKeyChecking=no slurmclusterworker-one  "kill -9 {}"'.format(task.pid)
                     logger.debug(stop_command)
                     out = os_shell(stop_command, capture=True)
-                    if out.exit_code != 0:                        
+                    if out.exit_code != 0:
                         raise Exception(out.stderr)
-   
+
                 else:
                     data['error']= 'Don\'t know how to stop tasks on "{}" compute resource.'.format(task.compute)
-                    return render(request, 'error.html', {'data': data})   
-           
+                    return render(request, 'error.html', {'data': data})
+
                 # Ok, save status as deleted
-                task.status = 'stopped' 
+                task.status = 'stopped'
                 task.save()
 
                 # Check if the tunnel is active and if so kill it
@@ -456,32 +455,32 @@ def tasks(request):
                     tunnel_pid = out.stdout
                     # Kill Tunnel command
                     kill_tunnel_command= 'kill -9 {}'.format(tunnel_pid)
-                    
+
                     # Log
                     logger.debug('Killing tunnel with command: {}'.format(kill_tunnel_command))
-    
+
                     # Execute
                     os_shell(kill_tunnel_command, capture=True)
-                    if out.exit_code != 0:                    
+                    if out.exit_code != 0:
                         raise Exception(out.stderr)
 
             except Exception as e:
                 data['error'] = 'Error in stopping the task'
                 logger.error('Error in stopping task with uuid="{}": "{}"'.format(uuid, e))
-                return render(request, 'error.html', {'data': data})            
+                return render(request, 'error.html', {'data': data})
 
             # Unset uuid to load the list again
             uuid = None
-            
+
         elif action=='connect':
-            
+
             # Get the task (raises if none available including no permission)
             task = Task.objects.get(user=request.user, uuid=uuid)
-            
+
             # Create task tunnel
             if task.compute in ['local', 'demoremote']:
-                
-                # If there is no tunnel port allocated yet, find one                
+
+                # If there is no tunnel port allocated yet, find one
                 if not task.tunnel_port:
 
                     # Get a free port fot the tunnel:
@@ -489,13 +488,13 @@ def tasks(request):
                     for other_task in Task.objects.all():
                         if other_task.tunnel_port and not other_task.status in [TaskStatuses.exited, TaskStatuses.stopped]:
                             allocated_tunnel_ports.append(other_task.tunnel_port)
-                    
+
                     for port in range(7000, 7006):
                         if not port in allocated_tunnel_ports:
                             tunnel_port = port
                             break
                     if not tunnel_port:
-                        logger.error('Cannot find a free port for the tunnel for task "{}"'.format(task.tid))                      
+                        logger.error('Cannot find a free port for the tunnel for task "{}"'.format(task.tid))
                         raise ErrorMessage('Cannot find a free port for the tunnel to the task')
 
                     task.tunnel_port = tunnel_port
@@ -504,24 +503,24 @@ def tasks(request):
 
                 # Check if the tunnel is active and if not create it
                 logger.debug('Checking if task "{}" has a running tunnel'.format(task.tid))
-                
+
                 out = os_shell('ps -ef | grep ":{}:{}:{}" | grep -v grep'.format(task.tunnel_port, task.ip, task.port), capture=True)
 
                 if out.exit_code == 0:
                     logger.debug('Task "{}" has a running tunnel, using it'.format(task.tid))
                 else:
                     logger.debug('Task "{}" has no running tunnel, creating it'.format(task.tid))
-                    
+
                     # Tunnel command
                     tunnel_command= 'ssh -4 -o StrictHostKeyChecking=no -nNT -L 0.0.0.0:{}:{}:{} localhost & '.format(task.tunnel_port, task.ip, task.port)
                     background_tunnel_command = 'nohup {} >/dev/null 2>&1 &'.format(tunnel_command)
-                    
+
                     # Log
                     logger.debug('Opening tunnel with command: {}'.format(background_tunnel_command))
 
                     # Execute
                     subprocess.Popen(background_tunnel_command, shell=True)
-                   
+
             else:
                 raise ErrorMessage('Connecting to tasks on compute "{}" is not supported yet'.format(task.compute))
 
@@ -537,14 +536,14 @@ def tasks(request):
         except Exception as e:
             data['error'] = 'Error in getting info for Task "{}"'.format(uuid)
             logger.error('Error in getting Virtual Device with uuid="{}": "{}"'.format(uuid, e))
-            return render(request, 'error.html', {'data': data})   
+            return render(request, 'error.html', {'data': data})
     else:
         try:
             tasks = Task.objects.filter(user=request.user).order_by('created')
         except Exception as e:
             data['error'] = 'Error in getting Virtual Devices info'
             logger.error('Error in getting Virtual Devices: "{}"'.format(e))
-            return render(request, 'error.html', {'data': data})   
+            return render(request, 'error.html', {'data': data})
 
     # Update task statuses
     for task in tasks:
@@ -567,7 +566,7 @@ def create_task(request):
     data['user']    = request.user
     data['profile'] = Profile.objects.get(user=request.user)
     data['title']   = 'New Task'
-    
+
     # Get containers configured on the platform, both private to this user and public
     data['user_containers'] = Container.objects.filter(user=request.user)
     data['platform_containers'] = Container.objects.filter(user=None)
@@ -576,28 +575,28 @@ def create_task(request):
     task_name = request.POST.get('task_name', None)
 
     if task_name:
-        
+
         # Task container
-        task_container_id = request.POST.get('task_container_id', None)
+        task_container_uuid = request.POST.get('task_container_uuid', None)
 
         # Get the container object, first try as public and then as private
         try:
-            task_container = Container.objects.get(id=task_container_id, user=None)
+            task_container = Container.objects.get(uuid=task_container_uuid, user=None)
         except Container.DoesNotExist:
             try:
-                task_container =  Container.objects.get(id=task_container_id, user=request.user)
+                task_container =  Container.objects.get(uuid=task_container_uuid, user=request.user)
             except Container.DoesNotExist:
-                raise Exception('Consistency error, container with id "{}" does not exists or user "{}" does not have access rights'.format(task_container_id, request.user.email))
+                raise Exception('Consistency error, container with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_container_uuid, request.user.email))
 
         # Compute
         task_compute = request.POST.get('task_compute', None)
         if task_compute not in ['local', 'demoremote']:
             raise ErrorMessage('Unknown compute resource "{}')
-        
+
         # Generate the task uuid
         str_uuid = str(uuid.uuid4())
         str_shortuuid = str_uuid.split('-')[0]
-        
+
         # Create the task object
         task = Task.objects.create(uuid      = str_uuid,
                                    user      = request.user,
@@ -605,54 +604,54 @@ def create_task(request):
                                    status    = TaskStatuses.created,
                                    container = task_container,
                                    compute   = task_compute)
-        
-                
+
+
         # Actually start tasks
         try:
-            if task_compute == 'local':            
+            if task_compute == 'local':
 
-                # Get our ip address             
+                # Get our ip address
                 #import netifaces
                 #netifaces.ifaddresses('eth0')
-                #backend_ip = netifaces.ifaddresses('eth0')[netifaces.AF_INET][0]['addr']       
-    
-                # Init run command #--cap-add=NET_ADMIN --cap-add=NET_RAW 
+                #backend_ip = netifaces.ifaddresses('eth0')[netifaces.AF_INET][0]['addr']
+
+                # Init run command #--cap-add=NET_ADMIN --cap-add=NET_RAW
                 run_command  = 'sudo docker run  --network=rosetta_default --name rosetta-task-{}'.format( str_shortuuid)
-    
+
                 # Data volume
                 run_command += ' -v {}/task-{}:/data'.format(TASK_DATA_DIR, str_shortuuid)
-    
+
                 # Set registry string
                 if task.container.registry == 'local':
                     registry_string = 'localhost:5000/'
                 else:
                     registry_string  = ''
-                    
+
                 # Host name, image entry command
                 run_command += ' -h task-{} -d -t {}{}'.format(str_shortuuid, registry_string, task.container.image)
-      
+
                 # Run the task Debug
                 logger.debug('Running new task with command="{}"'.format(run_command))
                 out = os_shell(run_command, capture=True)
-                if out.exit_code != 0:                        
+                if out.exit_code != 0:
                     raise Exception(out.stderr)
                 else:
                     task_tid = out.stdout
                     logger.debug('Created task with id: "{}"'.format(task_tid))
-                    
+
 
                     # Get task IP address
                     out = os_shell('sudo docker inspect --format \'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' ' + task_tid + ' | tail -n1', capture=True)
                     if out.exit_code != 0:
                         raise Exception('Error: ' + out.stderr)
                     task_ip = out.stdout
-                    
+
                     # Set fields
                     task.tid    = task_tid
                     task.status = TaskStatuses.running
                     task.ip     = task_ip
                     task.port   = int(task.container.service_ports.split(',')[0])
-                
+
                     # Save
                     task.save()
 
@@ -663,9 +662,9 @@ def create_task(request):
                 # 1) Run the singularity container on slurmclusterworker-one (non blocking)
                 run_command = 'ssh -4 -o StrictHostKeyChecking=no slurmclusterworker-one  "export SINGULARITY_NOHTTPS=true && exec nohup singularity run --pid --writable-tmpfs --containall --cleanenv docker://dregistry:5000/rosetta/metadesktop &> /dev/null & echo \$!"'
                 out = os_shell(run_command, capture=True)
-                if out.exit_code != 0:                        
+                if out.exit_code != 0:
                     raise Exception(out.stderr)
-                
+
                 # Save pid echoed by the command above
                 task_pid = out.stdout
 
@@ -676,17 +675,17 @@ def create_task(request):
                 if out.exit_code != 0:
                     raise Exception('Error: ' + out.stderr)
                 task_ip = out.stdout
-                
+
                 # Set fields
                 task.tid    = task.uuid
                 task.status = TaskStatuses.running
                 task.ip     = task_ip
                 task.pid    = task_pid
                 task.port   = int(task.container.service_ports.split(',')[0])
-                
+
                 # Save
                 task.save()
-                
+
 
             else:
                 raise Exception('Consistency exception: invalid compute resource "{}'.format(task_compute))
@@ -695,7 +694,7 @@ def create_task(request):
             data['error'] = 'Error in creating new Task.'
             logger.error(e)
             return render(request, 'error.html', {'data': data})
-    
+
         # Set created switch
         data['created'] = True
 
@@ -715,9 +714,32 @@ def containers(request):
     data={}
     data['user']    = request.user
     data['profile'] = Profile.objects.get(user=request.user)
-    data['title']   = 'Add compute'
+    data['title']   = 'Containers'
     data['name']    = request.POST.get('name',None)
-    
+
+    # Get action if any
+    action = request.GET.get('action', None)
+    uuid = request.GET.get('uuid', None)
+
+
+    if action and uuid:
+
+        if action=='delete':
+            try:
+                # Get the task (raises if none available including no permission)
+                container = Container.objects.get(user=request.user, uuid=uuid)
+
+                # Delete
+                container.delete()
+
+                # Unset uuid to load the list again
+                uuid = None
+
+            except Exception as e:
+                data['error'] = 'Error in deleting the container'
+                logger.error('Error in deleting task with uuid="{}": "{}"'.format(uuid, e))
+                return render(request, 'error.html', {'data': data})
+
     # Get containers configured on the platform, both private to this user and public
     data['user_containers'] = Container.objects.filter(user=request.user)
     data['platform_containers'] = Container.objects.filter(user=None)
@@ -738,12 +760,12 @@ def add_container(request):
     data['user']    = request.user
     data['profile'] = Profile.objects.get(user=request.user)
     data['title']   = 'Add container'
-    
+
     # Container image if any
     container_image = request.POST.get('container_image',None)
 
     if container_image:
-        
+
         # Container type
         container_type = request.POST.get('container_type', None)
         if not container_type:
@@ -760,7 +782,7 @@ def add_container(request):
 
         # Container service ports
         container_service_ports = request.POST.get('container_service_ports', None)
-        
+
         try:
             for container_service_port in container_service_ports:
                 int(container_service_port)
@@ -796,7 +818,7 @@ def computes(request):
     data['profile'] = Profile.objects.get(user=request.user)
     data['title']   = 'Add compute'
     data['name']    = request.POST.get('name',None)
-    
+
 
     return render(request,  'computes.html', {'data': data})
 
@@ -813,7 +835,6 @@ def add_compute(request):
     data['profile'] = Profile.objects.get(user=request.user)
     data['title']   = 'Add compute'
     data['name']    = request.POST.get('name',None)
-    
 
-    return render(request, 'add_compute.html', {'data': data})
 
+    return render(request, 'add_compute.html', {'data': data})