diff --git a/deadlock-plugins/deadlock-extension/package.json b/deadlock-plugins/deadlock-extension/package.json
index acb460290121cc42bb73f8b76693923075fa9917..2c4d9e6071d796877d54f7257acda81c8349a2b0 100644
--- a/deadlock-plugins/deadlock-extension/package.json
+++ b/deadlock-plugins/deadlock-extension/package.json
@@ -33,7 +33,8 @@
       {
         "command": "deadlock.disconnect",
         "title": "Clear cache",
-        "category": "Deadlock Coding"
+        "category": "Deadlock Coding",
+        "enablement": "!deadlock.inContainer"
       }
     ],
     "viewsContainers": {
@@ -69,7 +70,8 @@
         {
           "id": "help",
           "name": "Help",
-          "visibility": "visible"
+          "visibility": "visible",
+          "when": "!deadlock.inContainer"
         }
       ]
     },
diff --git a/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts b/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts
index b73494fb57264fefeb9b8d2a4e2e0a2f43d975b1..455c8ad9484d0cdc6b0525e3fd83e4299ab9d198 100644
--- a/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/commandHandler.ts
@@ -1,5 +1,6 @@
 import { Command, commands } from 'vscode';
 import Controller from './controller';
+import isMissionStarted from './utils/mission.util';
 
 export class CommandHandler {
   private static _instance?: CommandHandler;
@@ -18,7 +19,12 @@ export class CommandHandler {
     this.disconnectCommand = { title: 'Disconnect', command: 'deadlock.disconnect' };
     this.authenticateCommand = { title: 'Authenticate', command: 'deadlock.authenticate' };
     this.openUrlInBrowserCommand = { title: 'Open url in browser', command: 'vscode.open' };
-    commands.registerCommand(this.disconnectCommand.command, Controller.instance.disconnect.bind(Controller.instance));
+    if (!isMissionStarted()) {
+      commands.registerCommand(
+        this.disconnectCommand.command,
+        Controller.instance.disconnect.bind(Controller.instance),
+      );
+    }
     commands.registerCommand(
       this.authenticateCommand.command,
       Controller.instance.authenticate.bind(Controller.instance),
diff --git a/deadlock-plugins/deadlock-extension/src/core/config.ts b/deadlock-plugins/deadlock-extension/src/core/config.ts
index 1fa0a2c72b0812521a55a9c7607da36e4e633914..1c3a158013df241eb506d9b66ce540ccfd7fe2fa 100644
--- a/deadlock-plugins/deadlock-extension/src/core/config.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/config.ts
@@ -1,9 +1,6 @@
 import { homedir } from 'os';
 import { join } from 'path';
-import isDocker from './utils/isdocker';
-
-// if we are on container, means the directory will depend differently
-const onContainer = isDocker();
+import isMissionStarted from './utils/mission.util';
 
 const deadlockConfigPath = join(homedir(), '.deadlock');
 
@@ -19,7 +16,7 @@ export const MISSION_PATH_IC = `${homedir()}/mission`;
 
 export const MISSION_FILE_IC = join('/', 'deadlock', 'challenge.yaml');
 
-export const DEADLOCK_WORKDIR_PATH = onContainer ? '/deadlock' : deadlockConfigPath;
+export const DEADLOCK_WORKDIR_PATH = isMissionStarted() ? '/deadlock' : deadlockConfigPath;
 
 export const USER_MISSION_PATH = join('/home/config/user-challenge.json');
 
diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts
index a60950a5a6948b8e416bd96dc8752907e825b035..602b7a89185ff514e70382e469f5747b5b8ee834 100644
--- a/deadlock-plugins/deadlock-extension/src/core/controller.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts
@@ -13,8 +13,8 @@ import { hasStatusNumber } from './utils/typeguards';
 import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, writeFileSync } from 'fs';
 import { extract } from 'tar';
 import { parse } from 'yaml';
-import isDocker from './utils/isdocker';
-import { getReviewedStudentWorkdirPath } from './utils/mission.utils';
+import { clearDevContainers } from './utils/docker.util';
+import isMissionStarted, { getReviewedStudentWorkdirPath } from './utils/mission.util';
 import { join } from 'path';
 import Mission from '../model/mission';
 import ApiService from './api.service';
@@ -31,7 +31,7 @@ export default class Controller {
       throw new Error('Controller is a singleton');
     }
     Controller._instance = this;
-    if (isDocker()) {
+    if (isMissionStarted()) {
       this.briefingView = new BriefingView();
     } else {
       this.startedMissions = new StartedMissionsView();
@@ -46,7 +46,7 @@ export default class Controller {
   }
 
   getChallenge(missionId: string): Mission | undefined {
-    if (!isDocker()) {
+    if (!isMissionStarted()) {
       return parse(`${missionWorkdir}/${missionId}/challenge.yaml`);
     }
   }
@@ -130,6 +130,12 @@ export default class Controller {
       extensionWarn('Could not clear extension store');
       extensionWarn(e);
     }
+    try {
+      await clearDevContainers();
+    } catch (e) {
+      extensionWarn('Could not clear dev containers');
+      extensionWarn(e);
+    }
     this.quickSetupView.isAlreadyConnected = false;
   }
 
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts
index 13d3329e20819d8cacdb7afdb46fe73de5097e01..d76607bdd8310afb98a0304a8865d3d9dde4565f 100644
--- a/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/missionDevContainer.ts
@@ -7,7 +7,7 @@ import { join } from 'path';
 
 import UserMission from './model/userMission';
 import { REGISTRY_MISSION_URL } from '../../config';
-import { getReviewedStudentWorkdirPath } from '../utils/mission.utils';
+import { getReviewedStudentWorkdirPath } from '../utils/mission.util';
 import { homedir } from 'os';
 import { extensionError } from '../../recorder/utils/log';
 import { createDirectories } from '../../recorder/utils/workdir';
@@ -136,8 +136,10 @@ export class MissionDevContainer {
     return writeFile(
       `${this.dirs.devcontainer}/devcontainer.json`,
       (() => {
+        const containerName =
+          `deadlock-mission-${this.missionId}-${this.missionVersion}` + (this.revieweeId ? `-${this.revieweeId}` : '');
         const devcontainer: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts> = {
-          name: `deadlock-${this.missionId}`,
+          name: containerName,
           image: `${REGISTRY_MISSION_URL}/${this.missionId}:${this.missionVersion}`,
           containerEnv: {
             WORKDIR: `${remoteMissionDir}`,
@@ -152,7 +154,7 @@ export class MissionDevContainer {
           workspaceMount: `source=${this.dirs.mounted},target=${remoteMissionDir},type=bind`,
           workspaceFolder: `${remoteMissionDir}`,
           onCreateCommand: `cp -R ${remoteGiteaWorkDir}/* ${remoteMissionDir} && sudo bash /start.desktop.sh`,
-          runArgs: ['--privileged'],
+          runArgs: ['--name', containerName, '--privileged'],
           ...options,
         };
         return JSON.stringify(devcontainer, null, 2);
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/model/devContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/model/devContainer.ts
index 677faea6f2f59105971ffdf5add20a8eb7461224..e887cf378efadf581c26e7cfcec0b73d684685a7 100644
--- a/deadlock-plugins/deadlock-extension/src/core/mission/model/devContainer.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/model/devContainer.ts
@@ -2,7 +2,7 @@ export interface DockerfileSpecific {
   image?: string;
   dockerFile?: string;
   context?: string;
-  'build.args'?: string[];
+  build?: { args: Record<string, string> };
   'build.target'?: string;
   'build.cacheFrom'?: string;
   containerEnv?: { [id: string]: string };
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/model/userMission.ts b/deadlock-plugins/deadlock-extension/src/core/mission/model/userMission.ts
index 829a829430e584589db3d4d4df4b1eacd08e93b4..66b16d7a9b81d0f3d267b8affb041092b349242a 100644
--- a/deadlock-plugins/deadlock-extension/src/core/mission/model/userMission.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/model/userMission.ts
@@ -4,7 +4,7 @@ import { join } from 'path';
 import { createDirectories } from '../../../recorder/utils/workdir';
 import ApiService from '../../api.service';
 import { missionWorkdir, USER_MISSION_PATH } from '../../config';
-import { getReviewedStudentWorkdirPath } from '../../utils/mission.utils';
+import { getReviewedStudentWorkdirPath } from '../../utils/mission.util';
 
 interface UserMissionModel {
   missionId: string;
diff --git a/deadlock-plugins/deadlock-extension/src/core/utils/docker.util.ts b/deadlock-plugins/deadlock-extension/src/core/utils/docker.util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a10f7580f56855d90cbfed26ccf65672c5b58e2
--- /dev/null
+++ b/deadlock-plugins/deadlock-extension/src/core/utils/docker.util.ts
@@ -0,0 +1,35 @@
+import { exec as execCallback } from 'child_process';
+import { promisify } from 'util';
+
+const exec = promisify(execCallback);
+
+async function getDevContainerContainers(): Promise<string[]> {
+  return (await exec('docker container ps -a --format {{.Names}}')).stdout
+    .split('\n')
+    .filter((container) => container.includes('deadlock-mission-'));
+}
+
+async function removeContainers(...containers: string[]) {
+  await exec(`docker container rm -f ${containers.join(' ')}`);
+}
+
+async function getDevContainerImages(): Promise<string[]> {
+  return (await exec('docker image ls --format {{.Repository}}')).stdout
+    .split('\n')
+    .filter((image) => image.includes('code_'));
+}
+
+async function removeImages(...images: string[]) {
+  await exec(`docker image rm -f ${images.join(' ')}`);
+}
+
+export async function clearDevContainers() {
+  const containers = await getDevContainerContainers();
+  const images = await getDevContainerImages();
+  if (containers.length > 0) {
+    await removeContainers(...containers);
+  }
+  if (images.length > 0) {
+    await removeImages(...images);
+  }
+}
diff --git a/deadlock-plugins/deadlock-extension/src/core/utils/isdocker.ts b/deadlock-plugins/deadlock-extension/src/core/utils/isdocker.ts
deleted file mode 100644
index fe8c3d1686c4b8203b7822be99715cac12ffbfab..0000000000000000000000000000000000000000
--- a/deadlock-plugins/deadlock-extension/src/core/utils/isdocker.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { readFileSync, statSync } from 'fs';
-
-let isDockerCached: undefined | boolean;
-
-function hasDockerEnv() {
-  try {
-    statSync('/.dockerenv');
-    return true;
-  } catch {
-    return false;
-  }
-}
-
-function hasDockerCGroup() {
-  try {
-    return readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
-  } catch {
-    return false;
-  }
-}
-
-export default function isDocker() {
-  // TODO: Use `??=` when targeting Node.js 16.
-  if (isDockerCached === undefined) {
-    isDockerCached = hasDockerEnv() || hasDockerCGroup();
-  }
-
-  return isDockerCached;
-}
diff --git a/deadlock-plugins/deadlock-extension/src/core/utils/mission.utils.ts b/deadlock-plugins/deadlock-extension/src/core/utils/mission.util.ts
similarity index 80%
rename from deadlock-plugins/deadlock-extension/src/core/utils/mission.utils.ts
rename to deadlock-plugins/deadlock-extension/src/core/utils/mission.util.ts
index 8238c3a78c585139b4badc5f00fbcb2132b9c52c..eb2828225571a8e9a890c389cd0d3fb424383b6f 100644
--- a/deadlock-plugins/deadlock-extension/src/core/utils/mission.utils.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/utils/mission.util.ts
@@ -1,8 +1,7 @@
-import { PathLike, readFileSync } from 'fs';
+import { existsSync, PathLike, readFileSync } from 'fs';
 import { join } from 'path';
 import { missionWorkdir, USER_MISSION_PATH } from '../config';
 import UserMission from '../mission/model/userMission';
-import isDocker from './isdocker';
 
 export function getReviewedStudentWorkdirPath(userId: string): string {
   return join(missionWorkdir, 'students', `${userId}`);
@@ -10,7 +9,7 @@ export function getReviewedStudentWorkdirPath(userId: string): string {
 
 export function getUserChallenge(userId: string, missionid: string, isReviewing = false): UserMission {
   let path: number | PathLike;
-  if (isDocker()) {
+  if (isMissionStarted()) {
     path = USER_MISSION_PATH;
   } else if (isReviewing) {
     path = join(getReviewedStudentWorkdirPath(userId), missionid, '.config', 'userChallenge.json');
@@ -19,3 +18,7 @@ export function getUserChallenge(userId: string, missionid: string, isReviewing
   }
   return JSON.parse(readFileSync(path, 'utf8'));
 }
+
+export default function isMissionStarted() {
+  return existsSync(USER_MISSION_PATH);
+}
diff --git a/deadlock-plugins/deadlock-extension/src/extension.ts b/deadlock-plugins/deadlock-extension/src/extension.ts
index 95cd3b2cfedd9a3fc9f826d85f5c4981e962a3a7..4082bd01444f78114b87b36295bfc6f7ed8ad729 100644
--- a/deadlock-plugins/deadlock-extension/src/extension.ts
+++ b/deadlock-plugins/deadlock-extension/src/extension.ts
@@ -1,10 +1,10 @@
 import { window, ExtensionContext, workspace, commands } from 'vscode';
-import isDocker from './core/utils/isdocker';
 import Recorder from './recorder/recorder';
 import { extensionError as error } from './recorder/utils/log';
 import { DepNodeProvider } from './view/deadlockPanel';
 import { CommandTreeProvider } from './view/CommandTree';
 import Controller from './core/controller';
+import isMissionStarted from './core/utils/mission.util';
 
 export async function activate(context: ExtensionContext) {
   new Controller(context);
@@ -17,7 +17,7 @@ export async function activate(context: ExtensionContext) {
   if (Controller.instance.startedMissions) {
     window.registerWebviewViewProvider('startedMissions', Controller.instance.startedMissions);
   }
-  if (isDocker()) {
+  if (isMissionStarted()) {
     commands.executeCommand('setContext', 'deadlock.inContainer', true);
     window.registerTreeDataProvider('commandTree', new CommandTreeProvider());
     try {
diff --git a/deadlock-plugins/deadlock-extension/src/view/briefingView.ts b/deadlock-plugins/deadlock-extension/src/view/briefingView.ts
index 71db47c9617ece2ea80bbbf8f9ec7136b3c95ba5..6f5e5e1baad4385434c829aa6fcd69cd87bd09ae 100644
--- a/deadlock-plugins/deadlock-extension/src/view/briefingView.ts
+++ b/deadlock-plugins/deadlock-extension/src/view/briefingView.ts
@@ -7,7 +7,7 @@ import ApiService from '../core/api.service';
 import { BRIEFING_FILE_NAME, DOCS_PATH_IC } from '../core/config';
 import { openBriefingCommand } from '../core/controller';
 import UserMission from '../core/mission/model/userMission';
-import isDocker from '../core/utils/isdocker';
+import isMissionStarted from '../core/utils/mission.util';
 import { WebviewBase } from './webviewBase';
 
 export const briefingId = 'brefingView';
@@ -55,7 +55,7 @@ export default class BriefingView extends WebviewBase {
               console.error(e);
               this.briefingContent = 'Error while parsing your briefing.';
             }
-            if (isDocker()) this.show();
+            if (isMissionStarted()) this.show();
           },
           (error) => {
             console.error('Cannot load briefing', error);