diff --git a/deadlock-plugins/deadlock-extension/src/config.ts b/deadlock-plugins/deadlock-extension/src/config.ts
index 21960df6fea4d8e530bc89caaf217a4219f82ab8..fcbe08addba35d99f5fd64632720c89235514ed1 100644
--- a/deadlock-plugins/deadlock-extension/src/config.ts
+++ b/deadlock-plugins/deadlock-extension/src/config.ts
@@ -4,7 +4,6 @@ export const KEYCLOAK_TOKEN_CREATE_URL =
   'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/token';
 export const KEYCLOAK_USER_INFO_URL =
   'https://auth.dev.deadlock.io/auth/realms/Deadlock/protocol/openid-connect/userinfo';
-export const REGISTRY_MISSION_URL = 'registry.takima.io/deadlock/deadlock-challenges';
 export const REJECT_UNAUTHORIZED = false;
 export const ENABLE_AUTOMATIC_SAVE = true;
 export const ENABLE_RECORDER_HTTP_SERVER = false;
diff --git a/deadlock-plugins/deadlock-extension/src/core/callApi.service.ts b/deadlock-plugins/deadlock-extension/src/core/callApi.service.ts
index da086311594036b8ad2bc2bc9b27dd064ae4449b..e82c9df4d800e5495c415114400881ad83d1c021 100644
--- a/deadlock-plugins/deadlock-extension/src/core/callApi.service.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/callApi.service.ts
@@ -1,43 +1,44 @@
-import axios, { AxiosInstance } from 'axios';
-import { API_QUERY_REFERER, API_URL } from '../config';
-import { GiteaPublicProperties } from '../model/giteaPublicProperties.model';
-import { SshKeyPair } from '../model/sshKeyPair.model';
-import { User } from '../model/user.model';
+import axios, {AxiosInstance} from 'axios';
+import {API_QUERY_REFERER, API_URL} from '../config';
+import {GiteaPublicProperties} from '../model/giteaPublicProperties.model';
+import {SshKeyPair} from '../model/sshKeyPair.model';
+import {User} from '../model/user.model';
 import Controller from './controller';
 import ExtensionStore from './extensionStore';
 import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection';
 
 export default class CallApiService {
-  private callApi: AxiosInstance;
-  constructor(
-    private keycloackConnection: KeycloakOAuth2DeviceFlowConnection,
-    private extensionStore: ExtensionStore,
-    private controller: Controller,
-  ) {
-    this.callApi = axios.create({
-      baseURL: API_URL,
-      headers: {
-        'Content-Type': 'application/json',
-        referer: API_QUERY_REFERER,
-      },
-    });
+    private axiosInstance: AxiosInstance;
 
-    this.initApiInterceptor();
-  }
+    constructor(
+        private keycloackConnection: KeycloakOAuth2DeviceFlowConnection,
+        private extensionStore: ExtensionStore,
+        private controller: Controller,
+    ) {
+        this.axiosInstance = axios.create({
+            baseURL: API_URL,
+            headers: {
+                'Content-Type': 'application/json',
+                referer: API_QUERY_REFERER,
+            },
+        });
 
-  initApiInterceptor() {
-    this.callApi.interceptors.request.use(
-      async (config) => {
-        let accessToken = await this.extensionStore.getAccessToken();
-        if (accessToken && config.headers) {
-          config.headers['authorization'] = `BEARER ${accessToken}`;
-        }
-        return config;
-      },
-      (error) => {
-        return Promise.reject(error);
-      },
-    );
+        this.initApiInterceptor();
+    }
+
+    initApiInterceptor() {
+        this.axiosInstance.interceptors.request.use(
+            async (config) => {
+                let accessToken = await this.extensionStore.getAccessToken();
+                if (accessToken && config.headers) {
+                    config.headers['authorization'] = `BEARER ${accessToken}`;
+                }
+                return config;
+            },
+            (error) => {
+                return Promise.reject(error);
+            },
+        );
 
     this.callApi.interceptors.response.use(
       (res) => {
@@ -88,15 +89,15 @@ export default class CallApiService {
     );
   }
 
-  getGiteaPublicProperties(): Promise<GiteaPublicProperties> {
-    return this.callApi.get<GiteaPublicProperties>(`gitea`).then((res) => res.data);
-  }
+    getGiteaPublicProperties(): Promise<GiteaPublicProperties> {
+        return this.axiosInstance.get<GiteaPublicProperties>(`gitea`).then((res) => res.data);
+    }
 
-  getUserSshKey(): Promise<SshKeyPair> {
-    return this.callApi.put<SshKeyPair>(`users/gitea/keypair`).then((res) => res.data);
-  }
+    getUserSshKey(): Promise<SshKeyPair> {
+        return this.axiosInstance.put<SshKeyPair>(`users/gitea/keypair`).then((res) => res.data);
+    }
 
-  getUser(): Promise<User> {
-    return this.callApi.get<User>(`auth`).then((res) => res.data);
-  }
+    getUser(): Promise<User> {
+        return this.axiosInstance.get<User>(`auth`).then((res) => res.data);
+    }
 }
diff --git a/deadlock-plugins/deadlock-extension/src/core/controller.ts b/deadlock-plugins/deadlock-extension/src/core/controller.ts
index e2435100647345293570d8be520c03acbc59b442..a628c1ca01b275a1062ccb16165fba59357a0833 100644
--- a/deadlock-plugins/deadlock-extension/src/core/controller.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/controller.ts
@@ -1,119 +1,128 @@
 import * as vscode from 'vscode';
 import {
-  KEYCLOAK_DEVICE_AUTH_URL,
-  KEYCLOAK_TOKEN_CREATE_URL,
-  KEYCLOAK_USER_INFO_URL,
-  REGISTRY_MISSION_URL,
+    KEYCLOAK_DEVICE_AUTH_URL,
+    KEYCLOAK_TOKEN_CREATE_URL,
+    KEYCLOAK_USER_INFO_URL,
+    REGISTRY_MISSION_URL,
 } from '../config';
 
-import { log } from '../recorder/utils';
-import { OPEN_QUICK_SETUP_COMMAND } from '../theia/command';
+import {log} from '../recorder/utils';
+import {OPEN_QUICK_SETUP_COMMAND} from '../theia/command';
 import BriefingView from '../view/briefingView';
 import QuickSetupView from '../view/quickSetupView';
-import { CHOOSE_MISSION_WORKDIR_COMMAND, CommandHandler, OPEN_URL_IN_BROWSER_COMMAND } from './commandHandler';
+import {CHOOSE_MISSION_WORKDIR_COMMAND, CommandHandler, OPEN_URL_IN_BROWSER_COMMAND} from './commandHandler';
 import ExtensionStore from './extensionStore';
 import KeycloakOAuth2DeviceFlowConnection from './keycloakOAuth2DeviceFlowConnection';
-import Mission from './mission';
+import Mission from './mission/mission';
 import CallApiService from './callApi.service';
 import KeycloakOAuth2DeviceFlowConnectionVSCodeImpl from './keycloakOAuth2DeviceFlowConnectionVSCodeImpl';
 import SshKeyManager from './sshKeyManager';
-import { GiteaPublicProperties } from '../model/giteaPublicProperties.model';
-import { User } from '../model/user.model';
+import {GiteaPublicProperties} from '../model/giteaPublicProperties.model';
+import {User} from '../model/user.model';
 
 export default class Controller {
-  public connection: KeycloakOAuth2DeviceFlowConnection;
-  private commandHandler: CommandHandler;
-  private briefingView: BriefingView;
-  private quickSetupView: QuickSetupView;
-  private extensionStore: ExtensionStore;
-  private callApiService: CallApiService;
-  private sshKeyManager: SshKeyManager;
-
-  constructor(private context: vscode.ExtensionContext) {
-    this.extensionStore = ExtensionStore.getInstance(context);
-    this.briefingView = new BriefingView();
-    this.quickSetupView = new QuickSetupView(context.extensionUri);
-    this.commandHandler = new CommandHandler(this);
-    this.connection = new KeycloakOAuth2DeviceFlowConnectionVSCodeImpl(
-      KEYCLOAK_DEVICE_AUTH_URL,
-      KEYCLOAK_TOKEN_CREATE_URL,
-      KEYCLOAK_USER_INFO_URL,
-    );
-
-    this.callApiService = new CallApiService(this.connection, this.extensionStore, this);
-    this.sshKeyManager = new SshKeyManager();
-
-    this.init();
-  }
-  private async init() {
-    const that = this;
-    vscode.window.registerUriHandler({
-      handleUri(uri: vscode.Uri) {
-        const queryParams: URLSearchParams = new URLSearchParams(uri.query);
-        const action: string | null = queryParams.get('action');
-        log('Opening link', uri);
-
-        switch (action) {
-          case 'open-challenge':
-            that.launchMission(queryParams.get('missionId'), queryParams.get('missionVersion'));
-            break;
-
-          default:
-            vscode.window.showInformationMessage('Aucune action trouvée!');
+    public connection: KeycloakOAuth2DeviceFlowConnection;
+    private commandHandler: CommandHandler;
+    private briefingView: BriefingView;
+    private quickSetupView: QuickSetupView;
+    private extensionStore: ExtensionStore;
+    private callApiService: CallApiService;
+    private sshKeyManager: SshKeyManager;
+
+    constructor(private context: vscode.ExtensionContext) {
+        this.extensionStore = ExtensionStore.getInstance(context);
+        this.briefingView = new BriefingView();
+        this.quickSetupView = new QuickSetupView(context.extensionUri);
+        this.commandHandler = new CommandHandler(this);
+        this.connection = new KeycloakOAuth2DeviceFlowConnectionVSCodeImpl(
+            KEYCLOAK_DEVICE_AUTH_URL,
+            KEYCLOAK_TOKEN_CREATE_URL,
+            KEYCLOAK_USER_INFO_URL,
+        );
+
+        this.callApiService = new CallApiService(this.connection, this.extensionStore, this);
+        this.sshKeyManager = new SshKeyManager();
+
+        this.init();
+    }
+
+    private async init() {
+        const that = this;
+        vscode.window.registerUriHandler({
+            handleUri(uri: vscode.Uri) {
+                const queryParams = new URLSearchParams(uri.query);
+                const action = queryParams.get('action');
+                log('Opening link', uri);
+
+                switch (action) {
+                    case 'open-challenge':
+                        const missionId = queryParams.get('missionId');
+                        const missionVersion = queryParams.get('missionVersion');
+                        if (!missionId || !missionVersion) {
+                            //display smth
+                        }
+                        that.launchMission(queryParams.get('missionId'), queryParams.get('missionVersion'));
+                        break;
+
+                    default:
+                        vscode.window.showInformationMessage('Aucune action trouvée!');
+                }
+            },
+        });
+
+        const exensionStorage = ExtensionStore.getInstance();
+        this.quickSetupView.isAlreadyConnected = !!(await exensionStorage.getAccessToken());
+    }
+
+    async chooseMissionWorkdir() {
+        const actualMissionWorkDir = this.extensionStore.getMissionWorkdir();
+
+        const folderUri = await vscode.window.showOpenDialog({
+            defaultUri: actualMissionWorkDir ? vscode.Uri.file(actualMissionWorkDir) : undefined,
+            canSelectFolders: true,
+            canSelectFiles: false,
+            title: 'Choisis le dossier qui contiendra tes missions',
+        });
+
+        if (!folderUri) {
+            if (this.extensionStore.getMissionWorkdir()) {
+                return;
+            }
+            this.chooseMissionWorkdir();
+        } else {
+            this.extensionStore.setMissionWorkdir(folderUri[0].path);
         }
-      },
-    });
-
-    const exensionStorage = ExtensionStore.getInstance();
-    this.quickSetupView.isAlreadyConnected = !!(await exensionStorage.getAccessToken());
-  }
-  async chooseMissionWorkdir() {
-    const actualMissionWorkDir = this.extensionStore.getMissionWorkdir();
-
-    const folderUri = await vscode.window.showOpenDialog({
-      defaultUri: actualMissionWorkDir ? vscode.Uri.file(actualMissionWorkDir) : undefined,
-      canSelectFolders: true,
-      canSelectFiles: false,
-      title: 'Choisis le dossier qui contiendra tes missions',
-    });
-
-    if (!folderUri) {
-      if (this.extensionStore.getMissionWorkdir()) {
-        return;
-      }
-      this.chooseMissionWorkdir();
-    } else {
-      this.extensionStore.setMissionWorkdir(folderUri[0].path);
     }
-  }
-
-  public async clear() {
-    const exensionStorage = ExtensionStore.getInstance();
-    await exensionStorage.clear();
-    this.quickSetupView.isAlreadyConnected = false;
-  }
-
-  public async createSshKeyPairIfNotExist() {
-    if (this.sshKeyManager.isSshKeyPairExist()) return;
-    const { publicKey, privateKey } = await this.callApiService.getUserSshKey();
-    this.sshKeyManager.createSshKeyFiles(publicKey, privateKey);
-  }
-
-  public async authenticate() {
-    // WARN generate a new device code every time student clicks on log in button. Should I keep it ?\
-    // The answer might be 'yes' because when the student is already authenticated, the log in button should be disabled.
-    await this.connection.registerDevice();
-    const tokens = await this.connection.getToken({ openLink: Controller.openBrowserWithUrl });
-    await this.extensionStore.setAccessToken(tokens.accessToken);
-    await this.extensionStore.setRefreshToken(tokens.refreshToken);
-    await this.createSshKeyPairIfNotExist();
-    this.quickSetupView.isAlreadyConnected = true;
-  }
-  public static openBrowserWithUrl(url: string) {
-    vscode.commands.executeCommand(OPEN_URL_IN_BROWSER_COMMAND.cmd, vscode.Uri.parse(url));
-  }
-
-  public async launchMission(missionId: string | null, missionVersion: string | null) {
+
+    public async clear() {
+        const exensionStorage = ExtensionStore.getInstance();
+        await exensionStorage.clear();
+        this.quickSetupView.isAlreadyConnected = false;
+    }
+
+    public async createSshKeyPairIfNotExist() {
+        if (this.sshKeyManager.isSshKeyPairExist()) return;
+
+        const {publicKey, privateKey} = await this.callApiService.getUserSshKey();
+        await this.sshKeyManager.createSshKeyFiles(publicKey, privateKey);
+    }
+
+    public async authenticate() {
+        // WARN generate a new device code every time student clicks on log in button. Should I keep it ?\
+        // The answer might be 'yes' because when the student is already authenticated, the log in button should be disabled.
+        await this.connection.registerDevice();
+        const tokens = await this.connection.getToken({openLink: Controller.openBrowserWithUrl});
+        await this.extensionStore.setAccessToken(tokens.accessToken);
+        await this.extensionStore.setRefreshToken(tokens.refreshToken);
+        await this.createSshKeyPairIfNotExist();
+        this.quickSetupView.isAlreadyConnected = true;
+    }
+
+    public static openBrowserWithUrl(url: string) {
+        vscode.commands.executeCommand(OPEN_URL_IN_BROWSER_COMMAND.cmd, vscode.Uri.parse(url));
+    }
+
+  public async launchMission(missionId: string, missionVersion: string) {
     console.log('LAUCH MISSION : ' + missionId);
     if (missionId && missionVersion) {
       vscode.window.showInformationMessage(`vous lancez la mission ${missionId}`);
@@ -122,37 +131,34 @@ export default class Controller {
         await vscode.commands.executeCommand(CHOOSE_MISSION_WORKDIR_COMMAND.cmd);
       }
 
-      const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined;
+        const hadBeenConnected = (await this.extensionStore.getAccessToken()) !== undefined;
 
-      if (!hadBeenConnected) {
-        await this.authenticate();
-        vscode.window.showInformationMessage('Nouvelle connexion validée');
-      } else {
-        vscode.window.showInformationMessage('Déjà connecté: session récupérée');
-      }
+        if (!hadBeenConnected) {
+            await this.authenticate();
+            vscode.window.showInformationMessage('Connexion validée');
+        }
 
-      const user: User = await this.callApiService.getUser();
-      const giteaPublicProperties: GiteaPublicProperties = await this.callApiService.getGiteaPublicProperties();
-      // TODO Should I fetch GET api/missions/{missionId} one day instead of passing necessary parameters in vscode xdg-open link ?
-      const mission = new Mission(
-        {
-          registryBaseURL: REGISTRY_MISSION_URL,
-          missionId: missionId,
-          missionVersion: missionVersion,
-        },
-        user,
-        giteaPublicProperties,
-      );
-      vscode.window.showInformationMessage(
-        'opening inside folder ' + this.extensionStore.getMissionWorkdir()! + '/' + missionId,
-      );
-      console.log('BEFORE SETUP');
-      await mission.setup({});
-      console.log('BEFORE open editor');
-
-      await mission.openEditorInFolder();
-
-      vscode.commands.executeCommand(OPEN_QUICK_SETUP_COMMAND.cmd);
+        const user: User = await this.callApiService.getUser();
+        const giteaPublicProperties: GiteaPublicProperties = await this.callApiService.getGiteaPublicProperties();
+        // TODO Should I fetch GET api/missions/{missionId} one day instead of passing necessary parameters in vscode xdg-open link ?
+        const mission = new Mission(
+            {
+                registryBaseURL: REGISTRY_MISSION_URL,
+                missionId: missionId,
+                missionVersion: missionVersion,
+            },
+            user,
+            giteaPublicProperties,
+        );
+        vscode.window.showInformationMessage(
+            'opening inside folder ' + this.extensionStore.getMissionWorkdir()! + '/' + missionId,
+        );
+        console.log('BEFORE SETUP');
+        await mission.setup();
+        console.log('BEFORE open editor');
+
+        await mission.openEditorInFolder();
+
+        vscode.commands.executeCommand(OPEN_QUICK_SETUP_COMMAND.cmd);
     }
-  }
 }
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/DevContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/DevContainer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c1e4f8aad32a6b00cf6609a4a3e30e6d5ac4c034
--- /dev/null
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/DevContainer.ts
@@ -0,0 +1,44 @@
+export interface DockerfileSpecific {
+    image?;
+    dockerFile?;
+    context?;
+    'build.args'?;
+    'build.target'?;
+    'build.cacheFrom'?;
+    containerEnv?;
+    containerUser?;
+    mounts?;
+    workspaceMount?;
+    workspaceFolder?;
+    runArgs?;
+}
+
+export interface Base {
+    name?;
+    forwardPorts?;
+    portsAttributes?;
+    otherPortsAttributes?;
+    remoteEnv?;
+    remoteUser?;
+    updateRemoteUserUID?;
+    userEnvProbe?;
+    overrideCommand?;
+    features?;
+    shutdownAction?;
+}
+
+export interface VSCodespecific {
+    extensions?;
+    settings?;
+    devPort?;
+}
+
+export interface LifecycleScripts {
+    initializeCommand?;
+    onCreateCommand?;
+    updateContentCommand?;
+    postCreateCommand?;
+    postStartCommand?;
+    postAttachCommand?;
+    waitFor?;
+}
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/MissionDevContainer.ts b/deadlock-plugins/deadlock-extension/src/core/mission/MissionDevContainer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bcf4acfdfa455d08eaab939993b208d2cbe98a84
--- /dev/null
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/MissionDevContainer.ts
@@ -0,0 +1,48 @@
+import {MissionResource} from "./Mission";
+import {userSshKeyFolderPath} from "../config";
+import ExtensionStore from "../extensionStore";
+import {DockerfileSpecific, LifecycleScripts, VSCodespecific} from "./DevContainer";
+
+const DOCKER_IMAGE_URL = 'registry.takima.io/deadlock/deadlock-challenges';
+
+
+export function createDevContainerFile(mission: MissionResource) {
+
+    const hostBaseWorkDir = ExtensionStore.getInstance().getMissionWorkdir() ?? '';
+    const hostMissionDir = `${hostBaseWorkDir}/${mission.id}`
+
+    return fs.promises.writeFile(
+        this.hostMissionDevcontainerFileDir,
+        (() => {
+            const devcontainer: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts> = {
+                name: `deadlock-${this.params.missionId}`,
+                image: this.dockerImageURL,
+                extensions: ['Deadlock.deadlock-coding'],
+                remoteUser: 'deadlock',
+                mounts: [
+                    `source=${userSshKeyFolderPath},target=/tmp/.ssh,type=bind,consistency=cached,readonly`,
+                    `source=${this.userMissionConfigPath},target=/home/config/,type=bind,consistency=cached,readonly`,
+                    'source=/etc/hosts,target=/etc/hosts,type=bind,consistency=cached,readonly',
+                ],
+                userEnvProbe: 'interactiveShell',
+                settings: {
+                    'terminal.integrated.defaultProfile.linux': 'bash',
+                    'terminal.integrated.profiles.linux': {
+                        bash: {
+                            path: '/bin/bash',
+                        },
+                    },
+                },
+                overrideCommand: false,
+                shutdownAction: 'stopContainer',
+                workspaceMount: `source=${this.hostMissionMountDir},target=${this.remoteMissionDir},type=bind`,
+                workspaceFolder: `${this.remoteMissionDir}`,
+                onCreateCommand: `cp -R ${this.remoteGiteaWorkDir}/. ${this.remoteMissionDir}`,
+                runArgs: ['--privileged'],
+                ...options,
+            };
+            return JSON.stringify(devcontainer, null, 2);
+        })(),
+    );
+
+}
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/MissionDocker.ts b/deadlock-plugins/deadlock-extension/src/core/mission/MissionDocker.ts
new file mode 100644
index 0000000000000000000000000000000000000000..139597f9cb07c5d48bed18984ec4747f4b4f3438
--- /dev/null
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/MissionDocker.ts
@@ -0,0 +1,2 @@
+
+
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission/MissionResource.ts b/deadlock-plugins/deadlock-extension/src/core/mission/MissionResource.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dc3f3ca4c5eed56e8745f971ddab59d4ef4c0b78
--- /dev/null
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/MissionResource.ts
@@ -0,0 +1,8 @@
+
+export class MissionResource {
+    constructor(public missionDir: string, public id: string, public version: string) {
+
+    }
+}
+
+
diff --git a/deadlock-plugins/deadlock-extension/src/core/mission.ts b/deadlock-plugins/deadlock-extension/src/core/mission/mission.ts
similarity index 82%
rename from deadlock-plugins/deadlock-extension/src/core/mission.ts
rename to deadlock-plugins/deadlock-extension/src/core/mission/mission.ts
index da765ccb2724f4dd0f1f04f3e7c6401fdbb22783..31a37f5ba7298373cf2839cc8068fe077541d4f2 100644
--- a/deadlock-plugins/deadlock-extension/src/core/mission.ts
+++ b/deadlock-plugins/deadlock-extension/src/core/mission/mission.ts
@@ -2,11 +2,11 @@ import { exec as _exec } from 'child_process';
 import * as fs from 'fs';
 import * as util from 'util';
 import * as vscode from 'vscode';
-import { error as err, log } from '../recorder/utils';
-import ExtensionStore from './extensionStore';
-import { userSshKeyFolderPath } from './config';
-import { GiteaPublicProperties } from '../model/giteaPublicProperties.model';
-import { User, UserChallengeJson } from '../model/user.model';
+import { error as err, log } from '../../recorder/utils';
+import ExtensionStore from '../extensionStore';
+import { userSshKeyFolderPath } from '../config';
+import { GiteaPublicProperties } from '../../model/giteaPublicProperties.model';
+import { User, UserChallengeJson } from '../../model/user.model';
 
 /**
  * {@link https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback}
@@ -47,12 +47,6 @@ export default class Mission {
     this.giteaPublicProperties = giteaPublicProperties;
   }
 
-  static async pullImage(url) {
-    const { stdout, stderr } = await exec(`docker pull ${url}`);
-    log(stdout);
-    err(stderr);
-  }
-
   public async setup(options?: Partial<DockerfileSpecific & Base & VSCodespecific & LifecycleScripts>) {
     await fs.promises.mkdir(this.hostMissionDevcontainerDir, { recursive: true });
     await fs.promises.mkdir(this.hostMissionMountDir, { recursive: true });
@@ -131,47 +125,4 @@ export default class Mission {
 export function getDockerImageURL(base, missionId, missionVersion) {
   return `${base}/${missionId}:${missionVersion}`;
 }
-interface DockerfileSpecific {
-  image?;
-  dockerFile?;
-  context?;
-  'build.args'?;
-  'build.target'?;
-  'build.cacheFrom'?;
-  containerEnv?;
-  containerUser?;
-  mounts?;
-  workspaceMount?;
-  workspaceFolder?;
-  runArgs?;
-}
-
-interface Base {
-  name?;
-  forwardPorts?;
-  portsAttributes?;
-  otherPortsAttributes?;
-  remoteEnv?;
-  remoteUser?;
-  updateRemoteUserUID?;
-  userEnvProbe?;
-  overrideCommand?;
-  features?;
-  shutdownAction?;
-}
-
-interface VSCodespecific {
-  extensions?;
-  settings?;
-  devPort?;
-}
 
-interface LifecycleScripts {
-  initializeCommand?;
-  onCreateCommand?;
-  updateContentCommand?;
-  postCreateCommand?;
-  postStartCommand?;
-  postAttachCommand?;
-  waitFor?;
-}
diff --git a/deadlock-plugins/deadlock-extension/src/extension.ts b/deadlock-plugins/deadlock-extension/src/extension.ts
index e3f711319ec858062167cfa41d305f03a339eae5..1d049e8a7943e1de2d348d6fc643b33cd16e06fb 100644
--- a/deadlock-plugins/deadlock-extension/src/extension.ts
+++ b/deadlock-plugins/deadlock-extension/src/extension.ts
@@ -4,12 +4,10 @@ import { error } from './recorder/utils';
 import { DepNodeProvider } from './theia/deadlockPanel';
 import UserConfigTheia from './theia/userConfigTheia';
 
-export const userConfig = new UserConfigTheia();
 
 export async function activate(context: vscode.ExtensionContext) {
   vscode.window.showInformationMessage('Bienvenue sur Deadlock!');
-
-  const controller = new Controller(context);
+  extensionContext = context;
 
   const workspaceFolders = vscode.workspace.workspaceFolders?.toString() ?? '';
   if (!workspaceFolders) vscode.window.showInformationMessage('Pas de répertoires ouverts');