diff --git a/.gitea/workflows/backed_build-image.yaml b/.gitea/workflows/backend_build-image.yaml
similarity index 95%
rename from .gitea/workflows/backed_build-image.yaml
rename to .gitea/workflows/backend_build-image.yaml
index 5542a1f..1552c03 100644
--- a/.gitea/workflows/backed_build-image.yaml
+++ b/.gitea/workflows/backend_build-image.yaml
@@ -2,6 +2,8 @@ on:
   pull_request:
     branches:
       - main
+    paths:
+      - backend/**
 
 name: Build and push docker image
 
diff --git a/backend/Dockerfile b/backend/Dockerfile
index 79dbe76..01d58a2 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -6,6 +6,11 @@ COPY Pipfile Pipfile.lock .
 RUN pip install pipenv
 RUN pipenv install --deploy --system
 
-COPY . /src
+COPY src src
 
-CMD ["pipenv", "run", "python", "/app/src/main.py"]
+EXPOSE 8000
+
+# Set environment variables used by the deployment. These can be overridden by the user using this image.
+ENV NUM_WORKERS=1
+
+CMD ["pipenv", "run", "fastapi", "run", "src/main.py", '--port 8000', '--workers $NUM_WORKERS']
diff --git a/backend/src/constants.py b/backend/src/constants.py
new file mode 100644
index 0000000..515a040
--- /dev/null
+++ b/backend/src/constants.py
@@ -0,0 +1,9 @@
+from pathlib import Path
+
+
+PARAMETERS_DIR = Path('src/parameters')
+AMENITY_SELECTORS_PATH = PARAMETERS_DIR / 'amenity_selectors.yaml'
+LANDMARK_PARAMETERS_PATH = PARAMETERS_DIR / 'landmark_parameters.yaml'
+OPTIMIZER_PARAMETERS_PATH = PARAMETERS_DIR / 'optimizer_parameters.yaml'
+
+OSM_CACHE_DIR = Path('cache')
diff --git a/backend/src/landmarks_manager.py b/backend/src/landmarks_manager.py
index 618e169..39fa404 100644
--- a/backend/src/landmarks_manager.py
+++ b/backend/src/landmarks_manager.py
@@ -1,9 +1,11 @@
 import math as m
 import json, os
+import yaml
 
 from typing import List, Tuple, Optional
 from OSMPythonTools.overpass import Overpass, overpassQueryBuilder
 
+import constants
 from structs.landmarks import Landmark, LandmarkType
 from structs.preferences import Preferences, Preference
 
@@ -13,34 +15,40 @@ NATURE = LandmarkType(landmark_type='nature')
 SHOPPING = LandmarkType(landmark_type='shopping')
 
 
+
 # Include the json here
 # Create a list of all things to visit given some preferences and a city. Ready for the optimizer
 def generate_landmarks(preferences: Preferences, coordinates: Tuple[float, float]) :
+    with constants.AMENITY_SELECTORS_PATH.open('r') as f:
+        amenity_selectors = yaml.safe_load(f)
+    
+    with constants.LANDMARK_PARAMETERS_PATH.open('r') as f:
+        # even though we don't use the parameters here, we already load them to avoid unnecessary io operations
+        parameters = yaml.safe_load(f)
 
-    l_sights, l_nature, l_shop = get_amenities()
     L = []
 
     # List for sightseeing
     if preferences.sightseeing.score != 0 :
-        L1 = get_landmarks(l_sights, SIGHTSEEING, coordinates=coordinates)
+        L1 = get_landmarks(amenity_selectors['sightseeing'], SIGHTSEEING, coordinates, parameters)
         correct_score(L1, preferences.sightseeing)
         L += L1
     
     # List for nature
     if preferences.nature.score != 0 :
-        L2 = get_landmarks(l_nature, NATURE, coordinates=coordinates)
+        L2 = get_landmarks(amenity_selectors['nature'], NATURE, coordinates, parameters)
         correct_score(L2, preferences.nature)
         L += L2
     
     # List for shopping
     if preferences.shopping.score != 0 :
-        L3 = get_landmarks(l_shop, SHOPPING, coordinates=coordinates)
+        L3 = get_landmarks(amenity_selectors['shopping'], SHOPPING, coordinates, parameters)
         correct_score(L3, preferences.shopping)
         L += L3
 
     L = remove_duplicates(L)
 
-    return L, take_most_important(L)
+    return L, take_most_important(L, parameters)
 
 
 """def generate_landmarks(preferences: Preferences, city_country: str = None, coordinates: Tuple[float, float] = None) -> Tuple[List[Landmark], List[Landmark]] :
@@ -69,37 +77,8 @@ def generate_landmarks(preferences: Preferences, coordinates: Tuple[float, float
     return remove_duplicates(L), take_most_important(L)
 """
 # Helper function to gather the amenities list
-def get_amenities() -> List[List[str]] :
-    
-    # Get the list of amenities from the files
-    sightseeing = get_list('/amenities/sightseeing.am')
-    nature = get_list('/amenities/nature.am')
-    shopping = get_list('/amenities/shopping.am')
-
-    return sightseeing, nature, shopping
-
-
-# Helper function to read a .am file and generate the corresponding list
-def get_list(path: str) -> List[str] :
-
-    with open(os.path.dirname(os.path.abspath(__file__)) + path) as f :
-        content = f.readlines()
-
-        amenities = []
-        for line in content :
-            amenities.append(line.strip('\n'))
-
-    return amenities
-
-
 # Take the most important landmarks from the list
-def take_most_important(L: List[Landmark], N = 0) -> List[Landmark] :
-    
-    # Read the parameters from the file
-    with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/landmarks_manager.params', "r") as f :
-        parameters = json.loads(f.read())
-        N_important = parameters['N important']
-    
+def take_most_important(L: List[Landmark], parameters: dict, N: int = 0) -> List[Landmark]:
     L_copy = []
     L_clean = []
     scores = [0]*len(L)
@@ -127,7 +106,8 @@ def take_most_important(L: List[Landmark], N = 0) -> List[Landmark] :
     for i, elem in enumerate(L_copy) :
         scores[i] = elem.attractiveness
 
-    res = sorted(range(len(scores)), key = lambda sub: scores[sub])[-(N_important-N):]
+    
+    res = sorted(range(len(scores)), key = lambda sub: scores[sub])[-(parameters['N_important']-N):]
 
     for i, elem in enumerate(L_copy) :
         if i in res :
@@ -220,19 +200,25 @@ def create_bbox(coordinates: Tuple[float, float], side_length: int) -> Tuple[flo
     return min_lat, min_lon, max_lat, max_lon
 
 
-def get_landmarks(list_amenity: list, landmarktype: LandmarkType, coordinates: Tuple[float, float]) -> List[Landmark] :
+def get_landmarks(
+    list_amenity: list,
+    landmarktype: LandmarkType,
+    coordinates: Tuple[float, float],
+    parameters: dict
+) -> List[Landmark]:
     
-    # Read the parameters from the file
-    with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/landmarks_manager.params', "r") as f :
-        parameters = json.loads(f.read())
-        tag_coeff = parameters['tag coeff']
-        park_coeff = parameters['park coeff']
-        church_coeff = parameters['church coeff']
-        radius = parameters['radius close to']
-        bbox_side = parameters['city bbox side']
+    
+    # # Read the parameters from the file
+    # with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/landmarks_manager.params', "r") as f :
+    #     parameters = json.loads(f.read())
+    #     tag_coeff = parameters['tag coeff']
+    #     park_coeff = parameters['park coeff']
+    #     church_coeff = parameters['church coeff']
+    #     radius = parameters['radius close to']
+    #     bbox_side = parameters['city bbox side']
     
     # Create bbox around start location
-    bbox = create_bbox(coordinates, bbox_side)
+    bbox = create_bbox(coordinates, parameters['city_bbox_side'])
 
     # Initialize some variables
     N = 0
@@ -269,11 +255,11 @@ def get_landmarks(list_amenity: list, landmarktype: LandmarkType, coordinates: T
                 
                 # Add score of given landmark based on the number of surrounding elements. Penalty for churches as there are A LOT
                 if amenity == "'amenity'='place_of_worship'" :
-                    score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*church_coeff)  
+                    score = int((count_elements_within_radius(location, parameters['radius_close_to']) + n_tags*parameters['tag_coeff'] )*parameters['church_coeff'])  
                 elif amenity == "'leisure'='park'" :
-                    score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*park_coeff)  
+                    score = int((count_elements_within_radius(location, parameters['radius_close_to']) + n_tags*parameters['tag_coeff'] )*parameters['park_coeff'])  
                 else :
-                    score = count_elements_within_radius(location, radius) + n_tags*tag_coeff
+                    score = count_elements_within_radius(location, parameters['radius_close_to']) + n_tags*parameters['tag_coeff']
 
                 if score is not None :
                     # Generate the landmark and append it to the list
diff --git a/backend/src/main_example.py b/backend/src/main_example.py
deleted file mode 100644
index 1a49305..0000000
--- a/backend/src/main_example.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import fastapi
-from dataclasses import dataclass
-
-
-@dataclass
-class Destination:
-    name: str
-    location: tuple
-    attractiveness: int
-
-
-
-d = Destination()
-
-
-
-def get_route() -> list[Destination]:
-    return {"route": "Hello World"}
-
-endpoint = ("/get_route", get_route)
-end
-if __name__ == "__main__":
-    fastapi.run()
diff --git a/backend/src/optimizer.py b/backend/src/optimizer.py
index b346a8a..68362c6 100644
--- a/backend/src/optimizer.py
+++ b/backend/src/optimizer.py
@@ -1,13 +1,13 @@
 import numpy as np
 import json, os
+import yaml
 
 from typing import List, Tuple
 from scipy.optimize import linprog
 from math import radians, sin, cos, acos
-from shapely import Polygon
 
 from structs.landmarks import Landmark
-
+import constants
     
 # Function to print the result
 def print_res(L: List[Landmark], L_tot):
@@ -161,10 +161,11 @@ def get_distance(p1: Tuple[float, float], p2: Tuple[float, float], detour: float
 # We want to maximize the sightseeing :  max(c) st. A*x < b   and   A_eq*x = b_eq
 def init_ub_dist(landmarks: List[Landmark], max_steps: int):
     
-    with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
-        parameters = json.loads(f.read())
-        detour = parameters['detour factor']
-        speed = parameters['average walking speed']
+    # Read the parameters from the file
+    with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f:
+        parameters = yaml.safe_load(f)
+        detour = parameters['detour_factor']
+        speed = parameters['average_walking_speed']
     
     # Objective function coefficients. a*x1 + b*x2 + c*x3 + ...
     c = []
@@ -194,9 +195,9 @@ def respect_number(L:int, A_ub, b_ub):
         b_ub.append(1)
 
     # Read the parameters from the file
-    with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
-        parameters = json.loads(f.read())
-        max_landmarks = parameters['max landmarks']
+    with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f:
+        parameters = yaml.safe_load(f)
+        max_landmarks = parameters['max_landmarks']
 
     A_ub = np.vstack((A_ub, ones*L))
     b_ub.append(max_landmarks+1)
@@ -300,13 +301,14 @@ def respect_order(N: int, A_eq, b_eq):
 
 
 # Computes the time to reach from each landmark to the next
-def link_list(order: List[int], landmarks: List[Landmark])->List[Landmark] :
+def link_list(order: List[int], landmarks: List[Landmark]) -> List[Landmark]:
     
     # Read the parameters from the file
-    with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
-        parameters = json.loads(f.read())
-        detour_factor = parameters['detour factor']
-        speed = parameters['average walking speed']
+    with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f:
+        parameters = yaml.safe_load(f)
+        
+    detour_factor = parameters['detour_factor']
+    speed = parameters['average_walking_speed']
     
     L =  []
     j = 0
@@ -329,10 +331,11 @@ def link_list(order: List[int], landmarks: List[Landmark])->List[Landmark] :
 def link_list_simple(ordered_visit: List[Landmark])-> List[Landmark] :
     
     # Read the parameters from the file
-    with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
-        parameters = json.loads(f.read())
-        detour_factor = parameters['detour factor']
-        speed = parameters['average walking speed']
+    with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f:
+        parameters = yaml.safe_load(f)
+        
+    detour_factor = parameters['detour_factor']
+    speed = parameters['average_walking_speed']
 
     L =  []
     j = 0
diff --git a/backend/src/parameters/amenity_selectors.yaml b/backend/src/parameters/amenity_selectors.yaml
new file mode 100644
index 0000000..43e8220
--- /dev/null
+++ b/backend/src/parameters/amenity_selectors.yaml
@@ -0,0 +1,26 @@
+nature:
+  - "'leisure'='park'"
+  - "geological"
+  - "'natural'='geyser'"
+  - "'natural'='hot_spring'"
+  - "'natural'='arch'"
+  - "'natural'='volcano'"
+  - "'natural'='stone'"
+  - "'tourism'='alpine_hut'"
+  - "'tourism'='viewpoint'"
+  - "'tourism'='zoo'"
+  - "'waterway'='waterfall'"
+
+shopping:
+  - "'shop'='department_store'"
+  - "'shop'='mall'"
+
+sightseeing:
+  - "'tourism'='museum'"
+  - "'tourism'='attraction'"
+  - "'tourism'='gallery'"
+  - "historic"
+  - "'amenity'='planetarium'"
+  - "'amenity'='place_of_worship'"
+  - "'amenity'='fountain'"
+  - "'water'='reflecting_pool'"
diff --git a/backend/src/parameters/landmark_parameters.yaml b/backend/src/parameters/landmark_parameters.yaml
new file mode 100644
index 0000000..3cf1c76
--- /dev/null
+++ b/backend/src/parameters/landmark_parameters.yaml
@@ -0,0 +1,6 @@
+city_bbox_side: 10
+radius_close_to: 27.5
+church_coeff: 0.6
+park_coeff: 1.5
+tag_coeff: 100
+N_important: 40
diff --git a/backend/src/parameters/landmarks_manager.params b/backend/src/parameters/landmarks_manager.params
deleted file mode 100644
index 942c214..0000000
--- a/backend/src/parameters/landmarks_manager.params
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "city bbox side" : 10,
-  "radius close to" : 27.5,
-  "church coeff" : 0.6,
-  "park coeff" : 1.5,
-  "tag coeff" : 100,
-  "N important" : 40
-}
\ No newline at end of file
diff --git a/backend/src/parameters/optimizer.params b/backend/src/parameters/optimizer.params
deleted file mode 100644
index 18ca240..0000000
--- a/backend/src/parameters/optimizer.params
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "detour factor" : 1.4,
-  "average walking speed" : 4.8,
-  "max landmarks" : 10
-}
\ No newline at end of file
diff --git a/backend/src/parameters/optimizer_parameters.yaml b/backend/src/parameters/optimizer_parameters.yaml
new file mode 100644
index 0000000..b6dca0e
--- /dev/null
+++ b/backend/src/parameters/optimizer_parameters.yaml
@@ -0,0 +1,3 @@
+detour_factor: 1.4
+average_walking_speed: 4.8
+max_landmarks: 10
diff --git a/backend/src/refiner.py b/backend/src/refiner.py
index 282f2f9..a292b73 100644
--- a/backend/src/refiner.py
+++ b/backend/src/refiner.py
@@ -1,7 +1,8 @@
 from collections import defaultdict
 from heapq import heappop, heappush
 from itertools import permutations
-import os, json
+import os
+import yaml
 
 from shapely import buffer, LineString, Point, Polygon, MultiPoint, convex_hull, concave_hull, LinearRing
 from typing import List, Tuple
@@ -10,6 +11,7 @@ from math import pi
 from structs.landmarks import Landmark
 from landmarks_manager import take_most_important
 from optimizer import solve_optimization, link_list_simple, print_res, get_distance
+import constants
 
 
 def create_corridor(landmarks: List[Landmark], width: float) :
@@ -122,12 +124,12 @@ def total_path_distance(path: List[Landmark], detour, speed) -> float:
 
 
 def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> List[Landmark]:
-    
-  # Read from data
-  with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
-    parameters = json.loads(f.read())
-    detour = parameters['detour factor']
-    speed = parameters['average walking speed']
+  # Read the parameters from the file
+  with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f:
+    parameters = yaml.safe_load(f)
+
+    detour = parameters['detour_factor']
+    speed = parameters['average_walking_speed']
     
   # Step 1: Find 'start' and 'finish' landmarks
   start_idx = next(i for i, lm in enumerate(landmarks) if lm.name == 'start')
@@ -174,8 +176,10 @@ def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[L
   for landmark in all_landmarks :
     if is_in_area(area, landmark.location) and landmark.name not in visited_names:
       second_order_landmarks.append(landmark)
-
-  return take_most_important(second_order_landmarks, len(visited_landmarks))
+  
+  with constants.LANDMARK_PARAMETERS_PATH.open('r') as f:
+    parameters = yaml.safe_load(f)
+  return take_most_important(second_order_landmarks, parameters, len(visited_landmarks))
 
 
 
@@ -195,10 +199,10 @@ def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[L
 
 def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
 
-  # Read from the file
-  with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
-    parameters = json.loads(f.read())
-    max_landmarks = parameters['max landmarks']
+  # Read the parameters from the file
+  with constants.OPTIMIZER_PARAMETERS_PATH.open('r') as f:
+    parameters = yaml.safe_load(f)
+    max_landmarks = parameters['max_landmarks']
   
   if len(base_tour)-2 >= max_landmarks :
     return base_tour