diff --git a/.env.example b/.env.example
index f8209f46d40bb5947e16d98f126b6f2a634ed246..4b6ec2500455d9d90dbdb2eb2da08f22c69b6e80 100644
--- a/.env.example
+++ b/.env.example
@@ -9,5 +9,8 @@ DB_NAME=film-db
 # ADMINER
 ADMINER_PORT=8080
 
+# NGINX
+NGINX_PORT=3050
+
 # CLIENT
 CLIENT_PORT=3000
diff --git a/backend/.eslintrc.js b/backend/.eslintrc.js
index 8f5aedb718c87c8f4a192c2530ad1f90efc8dc25..b9aada61a79eb6224475099eed969af5cbd835c4 100644
--- a/backend/.eslintrc.js
+++ b/backend/.eslintrc.js
@@ -17,9 +17,85 @@ module.exports = {
   },
   ignorePatterns: ['.eslintrc.js'],
   rules: {
-    '@typescript-eslint/interface-name-prefix': 'off',
-    '@typescript-eslint/explicit-function-return-type': 'off',
-    '@typescript-eslint/explicit-module-boundary-types': 'off',
-    '@typescript-eslint/no-explicit-any': 'off',
+    '@typescript-eslint/explicit-function-return-type': ['error'],
+    '@typescript-eslint/no-explicit-any': ['error'],
+    '@typescript-eslint/prefer-nullish-coalescing': ['error'],
+    '@typescript-eslint/restrict-plus-operands': ['error'],
+    '@typescript-eslint/type-annotation-spacing': ['error'],
+
+    '@typescript-eslint/brace-style': ['error', '1tbs'],
+    '@typescript-eslint/comma-spacing': ['error', { 'before': false, 'after': true }],
+    '@typescript-eslint/default-param-last': ['error'],
+    '@typescript-eslint/dot-notation': ['error'],
+    '@typescript-eslint/indent': ['error', 2],
+    '@typescript-eslint/keyword-spacing': ['error', { 'before': true, 'after': true }],
+    '@typescript-eslint/no-empty-function': ['error'],
+    '@typescript-eslint/no-extra-parens': ['error'],
+    '@typescript-eslint/no-extra-semi': ['error'],
+    '@typescript-eslint/no-shadow': ['error'],
+    '@typescript-eslint/no-unused-expressions': ['error'],
+    '@typescript-eslint/no-unused-vars': ['error'],
+    '@typescript-eslint/quotes': ['error', 'single'],
+    '@typescript-eslint/require-await': ['error'],
+    '@typescript-eslint/semi': ['error', 'always'],
+    '@typescript-eslint/space-before-blocks': ['error'],
+
+    'no-unreachable': 'error',
+    'no-unused-vars': 'off',
+
+    'camelcase': 'error',
+    'default-param-last': 'off',
+    'dot-notation': 'off',
+    'eqeqeq': 'error',
+    'no-confusing-arrow': 'error',
+    'no-else-return': 'error',
+    'no-empty': 'error',
+    'no-empty-function': 'off',
+    'no-extra-semi': 'off',
+    'no-lonely-if': 'error',
+    'no-mixed-operators': 'error',
+    'no-multi-assign': 'error',
+    'no-negated-condition': 'error',
+    'no-nested-ternary': 'error',
+    'no-param-reassign': 'error',
+    'no-shadow': 'off',
+    'no-shadow-restricted-names': 'error',
+    'no-throw-literal': 'error',
+    'no-unneeded-ternary': 'error',
+    'no-unused-expressions': 'off',
+    'no-useless-rename': 'error',
+    'no-useless-return': 'error',
+    'no-var': 'error',
+    'operator-assignment': ['error', 'always'],
+    'prefer-const': 'error',
+    'prefer-template': 'error',
+    'require-await': 'off',
+    'require-yield': 'error',
+    'spaced-comment': ['error', 'always'],
+
+    'arrow-parens': ['error', 'always'],
+    'arrow-spacing': 'error',
+    'block-spacing': 'error',
+    'brace-style': 'off',
+    'comma-spacing': 'off',
+    'comma-style': ['error', 'last'],
+    'func-call-spacing': ['error', 'never'],
+    'implicit-arrow-linebreak': ['error', 'beside'],
+    'indent': 'off',
+    'jsx-quotes': ['error', 'prefer-single'],
+    'keyword-spacing': 'off',
+    'no-mixed-spaces-and-tabs': 'error',
+    'no-multi-spaces': 'error',
+    'no-multiple-empty-lines': 'error',
+    'no-tabs': 'error',
+    'no-trailing-spaces': 'error',
+    'no-whitespace-before-property': 'error',
+    'quotes': 'off',
+    'rest-spread-spacing': ['error', 'never'],
+    'semi': 'off',
+    'space-before-blocks': 'off',
+    'space-in-parens': 'error',
+    'switch-colon-spacing': 'error',
+    'wrap-regex': 'error',
   },
 };
diff --git a/backend/.prettierrc b/backend/.prettierrc
index dcb72794f5300a3e0ccd2ad0669d802b62f3d370..920290445a33e01b1497022e6106dbd300585243 100644
--- a/backend/.prettierrc
+++ b/backend/.prettierrc
@@ -1,4 +1,5 @@
 {
   "singleQuote": true,
-  "trailingComma": "all"
+  "trailingComma": "all",
+  "bracketSameLine": true
 }
\ No newline at end of file
diff --git a/backend/package-lock.json b/backend/package-lock.json
index a85dbef5bd9029312a90321961a7dfa6adabed22..ca5a6ee8fbbf039a2b1660f247e2d90311f7c3da 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -10,6 +10,7 @@
       "license": "UNLICENSED",
       "dependencies": {
         "@nestjs/common": "^8.0.0",
+        "@nestjs/config": "^2.1.0",
         "@nestjs/core": "^8.0.0",
         "@nestjs/platform-express": "^8.0.0",
         "jshint": "^2.13.4",
@@ -1541,6 +1542,22 @@
         }
       }
     },
+    "node_modules/@nestjs/config": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-2.1.0.tgz",
+      "integrity": "sha512-wUpt1/QJEN7xnJl4pM3c9rHrY1widq2yPOZfjaMD1//XAP9LLHTaW+RxSEG6BSGIm3w4wGtjco+gKNB2WL7yRg==",
+      "dependencies": {
+        "dotenv": "16.0.1",
+        "dotenv-expand": "8.0.3",
+        "lodash": "4.17.21",
+        "uuid": "8.3.2"
+      },
+      "peerDependencies": {
+        "@nestjs/common": "^7.0.0 || ^8.0.0",
+        "reflect-metadata": "^0.1.13",
+        "rxjs": "^6.0.0 || ^7.2.0"
+      }
+    },
     "node_modules/@nestjs/core": {
       "version": "8.4.6",
       "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-8.4.6.tgz",
@@ -3523,6 +3540,22 @@
         "domelementtype": "1"
       }
     },
+    "node_modules/dotenv": {
+      "version": "16.0.1",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
+      "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/dotenv-expand": {
+      "version": "8.0.3",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz",
+      "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -9979,6 +10012,17 @@
         "uuid": "8.3.2"
       }
     },
+    "@nestjs/config": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-2.1.0.tgz",
+      "integrity": "sha512-wUpt1/QJEN7xnJl4pM3c9rHrY1widq2yPOZfjaMD1//XAP9LLHTaW+RxSEG6BSGIm3w4wGtjco+gKNB2WL7yRg==",
+      "requires": {
+        "dotenv": "16.0.1",
+        "dotenv-expand": "8.0.3",
+        "lodash": "4.17.21",
+        "uuid": "8.3.2"
+      }
+    },
     "@nestjs/core": {
       "version": "8.4.6",
       "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-8.4.6.tgz",
@@ -11518,6 +11562,16 @@
         "domelementtype": "1"
       }
     },
+    "dotenv": {
+      "version": "16.0.1",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
+      "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ=="
+    },
+    "dotenv-expand": {
+      "version": "8.0.3",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz",
+      "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg=="
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
diff --git a/backend/package.json b/backend/package.json
index 8c71fb3e7ca4c36dbbe8e3a77716bd8be33803db..21cdb97e6e3e69b5129c275f8a811eb986e64a49 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -22,6 +22,7 @@
   },
   "dependencies": {
     "@nestjs/common": "^8.0.0",
+    "@nestjs/config": "^2.1.0",
     "@nestjs/core": "^8.0.0",
     "@nestjs/platform-express": "^8.0.0",
     "jshint": "^2.13.4",
diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts
index 86628031ca2a10fe172fe824f69d1720c44b43ce..89b1b1611b1528bb0d18dd6a58bbba49b3819987 100644
--- a/backend/src/app.module.ts
+++ b/backend/src/app.module.ts
@@ -1,9 +1,14 @@
 import { Module } from '@nestjs/common';
+import { ConfigModule } from '@nestjs/config';
 import { AppController } from './app.controller';
 import { AppService } from './app.service';
 
 @Module({
-  imports: [],
+  imports: [
+    ConfigModule.forRoot({
+      envFilePath: '../.env',
+    }),
+  ],
   controllers: [AppController],
   providers: [AppService],
 })
diff --git a/backend/src/main.ts b/backend/src/main.ts
index 13cad38cff92aa3b3d3ef6232306e450cadf5713..655bf673ce3eddf4938fe6b461853f200630a9a6 100644
--- a/backend/src/main.ts
+++ b/backend/src/main.ts
@@ -1,8 +1,12 @@
 import { NestFactory } from '@nestjs/core';
+import { ConfigService } from '@nestjs/config';
 import { AppModule } from './app.module';
 
-async function bootstrap() {
+async function bootstrap(): Promise<void> {
   const app = await NestFactory.create(AppModule);
-  await app.listen(3000);
+  const configService = new ConfigService();
+  const port = configService.get('SERVER_PORT');
+  console.log(`NestJS server is listening on: http://localhost:${port}`);
+  await app.listen(port);
 }
 bootstrap();
diff --git a/docker-compose.yml b/docker-compose.yml
index a3c568507ecbf46ba016da700befbefada105898..23fb7268e12b60d7e6068ada5c40573cb1ae1141 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -10,7 +10,7 @@ services:
     command: npm run start:debug
     env_file: .env
     ports:
-      - 127.0.0.1:${SERVER_PORT}:3000
+      - 127.0.0.1:${SERVER_PORT}:${SERVER_PORT}
     volumes:
       # changes in host's ./backend directory will be propagated to the container
       - ./backend:/usr/src/app
@@ -50,6 +50,25 @@ services:
     depends_on:
       - postgres
 
+  nginx:
+    container_name: nginx
+    image: nginx:1.21.6-alpine
+    env_file: .env
+    ports:
+      - 127.0.0.1:${NGINX_PORT}:${NGINX_PORT}
+    volumes:
+      - ./nginx/templates:/etc/nginx/templates
+      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
+    networks:
+      - backend-network
+    environment:
+      - NGINX_PORT=${NGINX_PORT}
+      - SERVER_PORT=${SERVER_PORT}
+    restart: always
+    depends_on:
+      - server
+      - postgres
+
   client:
     container_name: client
     image: client:1.0.0
@@ -58,7 +77,7 @@ services:
       dockerfile: Dockerfile
     env_file: .env
     ports:
-      - 127.0.0.1:${CLIENT_PORT}:3000
+      - 127.0.0.1:${CLIENT_PORT}:${CLIENT_PORT}
     volumes:
       # changes in host's ./frontend directory will be propagated to the container
       - ./frontend:/usr/src/app
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 7dd2bb0cb606862a8044b4015c16064166110c44..0747bbc18c58164ae373286a8a06917b5b92f180 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -8,6 +8,7 @@
       "name": "frontend",
       "version": "0.0.0",
       "dependencies": {
+        "@types/node": "^17.0.42",
         "react": "^18.0.0",
         "react-dom": "^18.0.0"
       },
@@ -484,6 +485,11 @@
         "node": ">= 8.0.0"
       }
     },
+    "node_modules/@types/node": {
+      "version": "17.0.42",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.42.tgz",
+      "integrity": "sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ=="
+    },
     "node_modules/@types/prop-types": {
       "version": "15.7.5",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
@@ -1745,6 +1751,11 @@
         "picomatch": "^2.2.2"
       }
     },
+    "@types/node": {
+      "version": "17.0.42",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.42.tgz",
+      "integrity": "sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ=="
+    },
     "@types/prop-types": {
       "version": "15.7.5",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index fb6322e2217ffe07934a324a00c8ba60960d5a7a..c15fdb4f74699a1277e8eb5d177cbf27580a6707 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -8,6 +8,7 @@
     "preview": "vite preview"
   },
   "dependencies": {
+    "@types/node": "^17.0.42",
     "react": "^18.0.0",
     "react-dom": "^18.0.0"
   },
@@ -18,4 +19,4 @@
     "typescript": "^4.6.3",
     "vite": "^2.9.9"
   }
-}
\ No newline at end of file
+}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 0b85ee5e9480eff7fc43e870e19373455966af98..0bceb31594a0513b2adff102b2ad05b655f1f160 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -1,12 +1,17 @@
-import { defineConfig } from 'vite'
+import { defineConfig, loadEnv } from 'vite'
 import react from '@vitejs/plugin-react'
 
 // https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [react()],
-  server: {
-    watch: {
-      usePolling: true
+export default ({ mode }) => {
+  process.env = {...process.env, ...loadEnv(mode, `../${process.cwd()}`, '')};
+
+  return defineConfig({
+    plugins: [react()],
+    server: {
+      watch: {
+        usePolling: true
+      },
+      port: +process.env.CLIENT_PORT
     }
-  }
-})
+  });
+}
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
new file mode 100644
index 0000000000000000000000000000000000000000..e39c4ff5b869d5eb4278e325c3b90e6c1e78bb1e
--- /dev/null
+++ b/nginx/nginx.conf
@@ -0,0 +1,28 @@
+user nginx;
+worker_processes  auto;
+
+error_log  /var/log/nginx/error.log;
+pid        /var/run/nginx.pid;
+
+events {
+  worker_connections  1024;
+}
+
+http {
+  include       /etc/nginx/mime.types;
+  default_type  application/octet-stream;
+
+  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                    '$status $body_bytes_sent "$http_referer" '
+                    '"$http_user_agent" "$http_x_forwarded_for"';
+
+  # TODO: logging does not work
+  access_log  /var/log/nginx/access.log;
+
+  sendfile on;
+
+  keepalive_timeout 65;
+
+  # template files in /etc/nginx/templates/*.template are outputed as a result of executing envsubst to the /etc/nginx/conf.d folder
+  include /etc/nginx/conf.d/*.conf;
+}
diff --git a/nginx/templates/default.conf.template b/nginx/templates/default.conf.template
new file mode 100644
index 0000000000000000000000000000000000000000..831ce45a67c5df1ce253e15555ad05d032767c40
--- /dev/null
+++ b/nginx/templates/default.conf.template
@@ -0,0 +1,26 @@
+upstream nestjs_server {
+  server server:${SERVER_PORT};
+}
+
+server {
+  # IPv4
+  listen      ${NGINX_PORT} default_server;
+  # IPv6
+  listen      [::]:${NGINX_PORT} default_server;
+
+  location / {
+    proxy_http_version 1.1;
+    proxy_cache_bypass $http_upgrade;
+
+    #proxy_buffering off;
+
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection 'upgrade';
+    proxy_set_header Host $host;
+    proxy_set_header X-Real-IP $remote_addr;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header X-Forwarded-Proto $scheme;
+
+    proxy_pass http://nestjs_server;
+  }
+}