diff --git a/src/Application.ts b/src/Application.ts
index 2677958..17a23f5 100644
--- a/src/Application.ts
+++ b/src/Application.ts
@@ -64,16 +64,14 @@ export default abstract class Application {
 
         // Init express
         const app = express();
-        const mainRouter = express.Router();
-        const fileUploadFormRouter = express.Router();
-        app.use(fileUploadFormRouter);
-        app.use(mainRouter);
+        const initRouter = express.Router();
+        const handleRouter = express.Router();
+        app.use(initRouter);
+        app.use(handleRouter);
 
-        // Error handler
+        // Error handlers
         app.use((err: any, req: Request, res: Response, next: NextFunction) => {
-            if (res.headersSent) {
-                return next(err);
-            }
+            if (res.headersSent) return next(err);
 
             if (err instanceof ValidationBag) {
                 res.format({
@@ -135,13 +133,19 @@ export default abstract class Application {
             });
         });
 
-        // Start all components
+        // Start components
         for (const component of this.components) {
-            await component.start(app, mainRouter);
+            await component.start(app);
+        }
+
+        // Components routes
+        for (const component of this.components) {
+            await component.init(initRouter);
+            await component.handle(handleRouter);
         }
 
         // Routes
-        this.routes(mainRouter, fileUploadFormRouter);
+        this.routes(initRouter, handleRouter);
 
         this.ready = true;
     }
@@ -177,10 +181,10 @@ export default abstract class Application {
         Logger.info(`${this.constructor.name} v${this.version} - bye`);
     }
 
-    private routes(mainRootRouter: Router, rootFileUploadFormRouter: Router) {
+    private routes(initRouter: Router, handleRouter: Router) {
         for (const controller of this.controllers) {
             if (controller.hasGlobalHandlers()) {
-                controller.setupGlobalHandlers(mainRootRouter);
+                controller.setupGlobalHandlers(handleRouter);
 
                 Logger.info(`Registered global middlewares for controller ${controller.constructor.name}`);
             }
@@ -188,13 +192,13 @@ export default abstract class Application {
 
         for (const controller of this.controllers) {
             const {mainRouter, fileUploadFormRouter} = controller.setupRoutes();
-            mainRootRouter.use(controller.getRoutesPrefix(), mainRouter);
-            rootFileUploadFormRouter.use(controller.getRoutesPrefix(), fileUploadFormRouter);
+            initRouter.use(controller.getRoutesPrefix(), fileUploadFormRouter);
+            handleRouter.use(controller.getRoutesPrefix(), mainRouter);
 
             Logger.info(`> Registered routes for controller ${controller.constructor.name}`);
         }
 
-        mainRootRouter.use((req: Request) => {
+        handleRouter.use((req: Request) => {
             throw new NotFoundHttpError('page', req.originalUrl);
         });
     }
diff --git a/src/ApplicationComponent.ts b/src/ApplicationComponent.ts
index c34b1cf..200c5fb 100644
--- a/src/ApplicationComponent.ts
+++ b/src/ApplicationComponent.ts
@@ -7,9 +7,18 @@ export default abstract class ApplicationComponent<T> {
     private val?: T;
     protected app?: Application;
 
-    public abstract async start(app: Express, router: Router): Promise<void>;
+    public async start(app: Express): Promise<void> {
+    }
 
-    public abstract async stop(): Promise<void>;
+    public async init(router: Router): Promise<void> {
+    }
+
+    public async handle(router: Router): Promise<void> {
+    }
+
+    public async stop(): Promise<void> {
+
+    }
 
     protected export(val: T) {
         this.val = val;
diff --git a/src/auth/AuthComponent.ts b/src/auth/AuthComponent.ts
index 3e5d8dd..a3db2d5 100644
--- a/src/auth/AuthComponent.ts
+++ b/src/auth/AuthComponent.ts
@@ -1,5 +1,5 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, NextFunction, Request, Response, Router} from "express";
+import {NextFunction, Request, Response, Router} from "express";
 import AuthGuard from "./AuthGuard";
 import Controller from "../Controller";
 import {ForbiddenHttpError} from "../HttpError";
@@ -12,16 +12,13 @@ export default class AuthComponent extends ApplicationComponent<void> {
         this.authGuard = authGuard;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async init(router: Router): Promise<void> {
         router.use(async (req, res, next) => {
             req.authGuard = this.authGuard;
             res.locals.user = await req.authGuard.getUserForSession(req.session!);
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
 }
 
 export const REQUIRE_REQUEST_AUTH_MIDDLEWARE = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
diff --git a/src/components/AutoUpdateComponent.ts b/src/components/AutoUpdateComponent.ts
index c6b75b3..cc275ca 100644
--- a/src/components/AutoUpdateComponent.ts
+++ b/src/components/AutoUpdateComponent.ts
@@ -1,20 +1,17 @@
-import {Express, Router} from "express";
+import {Router} from "express";
 import config from "config";
 import * as child_process from "child_process";
 import ApplicationComponent from "../ApplicationComponent";
 import {ForbiddenHttpError} from "../HttpError";
 import Logger from "../Logger";
 
-const ROUTE = '/update/push.json';
-
 export default class AutoUpdateComponent extends ApplicationComponent<void> {
-    public async start(app: Express, router: Router): Promise<void> {
-        router.post(ROUTE, (req, res, next) => {
+    public async init(router: Router): Promise<void> {
+        router.post('/update/push.json', (req, res) => {
             const token = req.header('X-Gitlab-Token');
             if (!token || token !== config.get<string>('gitlab_webhook_token')) throw new ForbiddenHttpError('Invalid token', req.url);
 
-            this.update(req.body.checkout_sha)
-                .catch(Logger.error);
+            this.update(req.body).catch(Logger.error);
 
             res.json({
                 'status': 'ok',
@@ -22,20 +19,14 @@ export default class AutoUpdateComponent extends ApplicationComponent<void> {
         });
     }
 
-    public async stop(): Promise<void> {
-    }
-
-    private async update(checkout_sha: string) {
-        await this.app!.stop();
+    private async update(params: any) {
+        Logger.info('Update params:', params);
 
         try {
             Logger.info('Starting auto update...');
 
             // Fetch
-            await this.runCommand(`git fetch`);
-
-            // Checkout new source
-            await this.runCommand(`git checkout ${checkout_sha}`);
+            await this.runCommand(`git pull`);
 
             // Install new dependencies
             await this.runCommand(`yarn install --production=false`);
@@ -43,13 +34,16 @@ export default class AutoUpdateComponent extends ApplicationComponent<void> {
             // Process assets
             await this.runCommand(`yarn dist`);
 
+            // Stop app
+            await this.app!.stop();
+
             Logger.info('Success!');
         } catch (e) {
             Logger.error(e, 'An error occurred while running the auto update.');
         }
     }
 
-    private async runCommand(command: string) {
+    private async runCommand(command: string): Promise<void> {
         Logger.info(`> ${command}`);
         Logger.info(child_process.execSync(command).toString());
     }
diff --git a/src/components/CsrfProtectionComponent.ts b/src/components/CsrfProtectionComponent.ts
index 5650a57..621e155 100644
--- a/src/components/CsrfProtectionComponent.ts
+++ b/src/components/CsrfProtectionComponent.ts
@@ -1,5 +1,5 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Router} from "express";
+import {Router} from "express";
 import crypto from "crypto";
 import {BadRequestError} from "../HttpError";
 
@@ -10,7 +10,7 @@ export default class CsrfProtectionComponent extends ApplicationComponent<void>
         this.routeExcluders.push(excluder);
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async handle(router: Router): Promise<void> {
         router.use(async (req, res, next) => {
             for (const excluder of CsrfProtectionComponent.routeExcluders) {
                 if (excluder(req.path)) return next();
@@ -46,9 +46,6 @@ export default class CsrfProtectionComponent extends ApplicationComponent<void>
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
 }
 
 class InvalidCsrfTokenError extends BadRequestError {
diff --git a/src/components/ExpressAppComponent.ts b/src/components/ExpressAppComponent.ts
index 91f4204..9c61146 100644
--- a/src/components/ExpressAppComponent.ts
+++ b/src/components/ExpressAppComponent.ts
@@ -1,9 +1,7 @@
 import ApplicationComponent from "../ApplicationComponent";
-import express, {Express, RequestHandler, Router} from "express";
+import express, {Express, Router} from "express";
 import Logger from "../Logger";
 import {Server} from "http";
-import {IncomingForm} from "formidable";
-import {FileError, ValidationBag} from "../db/Validator";
 import compression from "compression";
 
 export default class ExpressAppComponent extends ApplicationComponent<void> {
@@ -15,11 +13,13 @@ export default class ExpressAppComponent extends ApplicationComponent<void> {
         this.port = port;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async start(app: Express): Promise<void> {
         this.server = app.listen(this.port, 'localhost', () => {
             Logger.info(`Web server running on localhost:${this.port}.`);
         });
+    }
 
+    public async init(router: Router): Promise<void> {
         router.use(express.json());
         router.use(express.urlencoded({
             extended: true,
diff --git a/src/components/FormHelperComponent.ts b/src/components/FormHelperComponent.ts
index 607e223..4937107 100644
--- a/src/components/FormHelperComponent.ts
+++ b/src/components/FormHelperComponent.ts
@@ -1,8 +1,8 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Router} from "express";
+import {Router} from "express";
 
 export default class FormHelperComponent extends ApplicationComponent<void> {
-    public async start(app: Express, router: Router): Promise<void> {
+    public async init(router: Router): Promise<void> {
         router.use((req, res, next) => {
             if (!req.session) {
                 throw new Error('Session is unavailable.');
@@ -41,8 +41,4 @@ export default class FormHelperComponent extends ApplicationComponent<void> {
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
-
 }
\ No newline at end of file
diff --git a/src/components/LogRequestsComponent.ts b/src/components/LogRequestsComponent.ts
index 7ea9ea9..daf1a3e 100644
--- a/src/components/LogRequestsComponent.ts
+++ b/src/components/LogRequestsComponent.ts
@@ -1,7 +1,7 @@
 import ApplicationComponent from "../ApplicationComponent";
 import onFinished from "on-finished";
 import Logger from "../Logger";
-import {Express, Request, Response, Router} from "express";
+import {Request, Response, Router} from "express";
 
 export default class LogRequestsComponent extends ApplicationComponent<void> {
     private static fullRequests: boolean = false;
@@ -51,7 +51,7 @@ export default class LogRequestsComponent extends ApplicationComponent<void> {
         return '';
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async init(router: Router): Promise<void> {
         router.use((req, res, next) => {
             onFinished(res, (err) => {
                 if (!err) {
@@ -61,8 +61,4 @@ export default class LogRequestsComponent extends ApplicationComponent<void> {
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
-
 }
\ No newline at end of file
diff --git a/src/components/MailComponent.ts b/src/components/MailComponent.ts
index e204b14..20f2db7 100644
--- a/src/components/MailComponent.ts
+++ b/src/components/MailComponent.ts
@@ -1,9 +1,9 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Router} from "express";
+import {Express} from "express";
 import Mail from "../Mail";
 
 export default class MailComponent extends ApplicationComponent<void> {
-    public async start(app: Express, router: Router): Promise<void> {
+    public async start(app: Express): Promise<void> {
         await this.prepare('Mail connection', () => Mail.prepare());
     }
 
diff --git a/src/components/MaintenanceComponent.ts b/src/components/MaintenanceComponent.ts
index fc766f4..08442b6 100644
--- a/src/components/MaintenanceComponent.ts
+++ b/src/components/MaintenanceComponent.ts
@@ -1,5 +1,5 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, NextFunction, Request, Response, Router} from "express";
+import {NextFunction, Request, Response, Router} from "express";
 import {ServiceUnavailableHttpError} from "../HttpError";
 import Application from "../Application";
 import config from "config";
@@ -14,7 +14,7 @@ export default class MaintenanceComponent extends ApplicationComponent<void> {
         this.canServe = canServe;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async handle(router: Router): Promise<void> {
         router.use((req: Request, res: Response, next: NextFunction) => {
             if (res.headersSent) {
                 return next();
@@ -34,8 +34,4 @@ export default class MaintenanceComponent extends ApplicationComponent<void> {
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
-
 }
\ No newline at end of file
diff --git a/src/components/MysqlComponent.ts b/src/components/MysqlComponent.ts
index 0bf03e6..a1ab499 100644
--- a/src/components/MysqlComponent.ts
+++ b/src/components/MysqlComponent.ts
@@ -1,9 +1,9 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Router} from "express";
+import {Express} from "express";
 import MysqlConnectionManager from "../db/MysqlConnectionManager";
 
 export default class MysqlComponent extends ApplicationComponent<void> {
-    public async start(app: Express, router: Router): Promise<void> {
+    public async start(app: Express): Promise<void> {
         await this.prepare('Mysql connection', () => MysqlConnectionManager.prepare());
     }
 
diff --git a/src/components/NunjucksComponent.ts b/src/components/NunjucksComponent.ts
index f49c860..b887506 100644
--- a/src/components/NunjucksComponent.ts
+++ b/src/components/NunjucksComponent.ts
@@ -1,4 +1,4 @@
-import nunjucks from "nunjucks";
+import nunjucks, {Environment} from "nunjucks";
 import config from "config";
 import {Express, Router} from "express";
 import ApplicationComponent from "../ApplicationComponent";
@@ -7,13 +7,14 @@ import {ServerError} from "../HttpError";
 
 export default class NunjucksComponent extends ApplicationComponent<void> {
     private readonly viewsPath: string;
+    private env?: Environment;
 
     constructor(viewsPath: string = 'views') {
         super();
         this.viewsPath = viewsPath;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async start(app: Express): Promise<void> {
         let coreVersion = 'unknown';
         try {
             coreVersion = require('../../package.json').version;
@@ -24,7 +25,7 @@ export default class NunjucksComponent extends ApplicationComponent<void> {
             }
         }
 
-        const env = nunjucks.configure(this.viewsPath, {
+        this.env = nunjucks.configure(this.viewsPath, {
             autoescape: true,
             express: app,
             noCache: !config.get('view.cache'),
@@ -41,9 +42,11 @@ export default class NunjucksComponent extends ApplicationComponent<void> {
                 return v.toString(16);
             });
         app.set('view engine', 'njk');
+    }
 
+    public async init(router: Router): Promise<void> {
         router.use((req, res, next) => {
-            req.env = env;
+            req.env = this.env!;
             res.locals.url = req.url;
             res.locals.params = () => req.params;
 
@@ -52,8 +55,4 @@ export default class NunjucksComponent extends ApplicationComponent<void> {
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
-
 }
\ No newline at end of file
diff --git a/src/components/RedirectBackComponent.ts b/src/components/RedirectBackComponent.ts
index c3b9712..3b11582 100644
--- a/src/components/RedirectBackComponent.ts
+++ b/src/components/RedirectBackComponent.ts
@@ -1,11 +1,11 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Router} from "express";
+import {Router} from "express";
 import onFinished from "on-finished";
 import Logger from "../Logger";
 import {ServerError} from "../HttpError";
 
 export default class RedirectBackComponent extends ApplicationComponent<void> {
-    public async start(app: Express, router: Router): Promise<void> {
+    public async init(router: Router): Promise<void> {
         router.use((req, res, next) => {
             if (!req.session) {
                 throw new Error('Session is unavailable.');
@@ -36,8 +36,4 @@ export default class RedirectBackComponent extends ApplicationComponent<void> {
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
-
 }
\ No newline at end of file
diff --git a/src/components/RedisComponent.ts b/src/components/RedisComponent.ts
index 14855c9..1523267 100644
--- a/src/components/RedisComponent.ts
+++ b/src/components/RedisComponent.ts
@@ -1,5 +1,5 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Router} from "express";
+import {Express} from "express";
 import redis, {RedisClient} from "redis";
 import config from "config";
 import Logger from "../Logger";
@@ -12,7 +12,7 @@ export default class RedisComponent extends ApplicationComponent<void> {
     private redisClient?: RedisClient;
     private store?: Store;
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async start(app: Express): Promise<void> {
         this.redisClient = redis.createClient(config.get('redis.port'), config.get('redis.host'), {
             password: config.has('redis.password') ? config.get<string>('redis.password') : undefined,
         });
diff --git a/src/components/ServeStaticDirectoryComponent.ts b/src/components/ServeStaticDirectoryComponent.ts
index 5573c37..ff3429c 100644
--- a/src/components/ServeStaticDirectoryComponent.ts
+++ b/src/components/ServeStaticDirectoryComponent.ts
@@ -1,5 +1,5 @@
 import ApplicationComponent from "../ApplicationComponent";
-import express, {Express, Router} from "express";
+import express, {Router} from "express";
 import {PathParams} from "express-serve-static-core";
 
 export default class ServeStaticDirectoryComponent extends ApplicationComponent<void> {
@@ -12,7 +12,7 @@ export default class ServeStaticDirectoryComponent extends ApplicationComponent<
         this.path = routePath;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async handle(router: Router): Promise<void> {
         if (typeof this.path !== 'undefined') {
             router.use(this.path, express.static(this.root, {maxAge: 1000 * 3600 * 72}));
         } else {
diff --git a/src/components/SessionComponent.ts b/src/components/SessionComponent.ts
index 709cadb..c1993dd 100644
--- a/src/components/SessionComponent.ts
+++ b/src/components/SessionComponent.ts
@@ -3,18 +3,17 @@ import session from "express-session";
 import config from "config";
 import RedisComponent from "./RedisComponent";
 import flash from "connect-flash";
-import {Express, Router} from "express";
+import {Router} from "express";
 
 export default class SessionComponent extends ApplicationComponent<void> {
     private readonly storeComponent: RedisComponent;
 
-
     public constructor(storeComponent: RedisComponent) {
         super();
         this.storeComponent = storeComponent;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async init(router: Router): Promise<void> {
         router.use(session({
             saveUninitialized: true,
             secret: config.get('session.secret'),
@@ -56,7 +55,4 @@ export default class SessionComponent extends ApplicationComponent<void> {
             next();
         });
     }
-
-    public async stop(): Promise<void> {
-    }
 }
\ No newline at end of file
diff --git a/src/components/WebSocketServerComponent.ts b/src/components/WebSocketServerComponent.ts
index 4081e96..92b7940 100644
--- a/src/components/WebSocketServerComponent.ts
+++ b/src/components/WebSocketServerComponent.ts
@@ -1,5 +1,5 @@
 import ApplicationComponent from "../ApplicationComponent";
-import {Express, Request, Router} from "express";
+import {Express, Request} from "express";
 import WebSocket, {Server as WebSocketServer} from "ws";
 import Logger from "../Logger";
 import cookie from "cookie";
@@ -24,7 +24,7 @@ export default class WebSocketServerComponent extends ApplicationComponent<void>
         this.storeComponent = storeComponent;
     }
 
-    public async start(app: Express, router: Router): Promise<void> {
+    public async start(app: Express): Promise<void> {
         const listeners: { [p: string]: WebSocketListener } = this.application.getWebSocketListeners();
         this.wss = new WebSocketServer({
             server: this.expressAppComponent.getServer(),