diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000000000000000000000000000000000000..f8209f46d40bb5947e16d98f126b6f2a634ed246
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,13 @@
+# SERVER
+SERVER_PORT=4000
+
+# DATABASE
+DB_USER=admin
+DB_PASSWORD=password
+DB_NAME=film-db
+
+# ADMINER
+ADMINER_PORT=8080
+
+# CLIENT
+CLIENT_PORT=3000
diff --git a/.gitignore b/.gitignore
index 5600c620dcc9e5c44f524cf6980398beb14b932a..6ee69d07071012e1d6c3dc09e75e27033a89bca0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,6 @@ node_modules/
 
 # .env files
 .env
+
+# Database
+database-storage
diff --git a/README.md b/README.md
index ccc3ec4e4d06d9d067b0da7dcfae5928c1bb2e71..fce1fba00a9ca389e049a02e84bda8f7d41aa188 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,16 @@ UI:
 -Mantis
 
 
+## Usage
+### Docker
+Firstly, run Docker daemon.
+
+Navigate into the project root directory `pb138-film-database-group-project`.
+
+Then in the root directory run `docker-compose up -d` to build, (re)create, start, and attach to containers for a service (optional flag `-d` runs containers in the background).
+
+When you are finished, run `docker-compose down` to stop and remove containers, networks and images created by `up`.
+
 ## TODO
 
 More TBA as features are implemented.
diff --git a/backend/.dockerignore b/backend/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..bb13753e8c3a8274c213c824aa382bdd7bede0a4
--- /dev/null
+++ b/backend/.dockerignore
@@ -0,0 +1,12 @@
+# Node modules folder
+node_modules
+
+# Git
+.gitignore
+
+# Database storage folder
+database-storage
+
+# Docker files
+Dockerfile
+.dockerignore
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..8a7677e8a56c23cec88f6d8e5ebeaa8e86ed6933
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,13 @@
+FROM node:16-alpine
+
+WORKDIR /usr/src
+
+COPY ["package.json", "package-lock.json*", "./"]
+RUN npm install
+ENV PATH=/usr/src/node_modules/.bin:$PATH
+
+WORKDIR /usr/src/app
+
+COPY . .
+
+CMD ["npm", "run", "build"]
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8c513cce4dd1263b30022d08a31719173de0de3d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,73 @@
+version: '3.8'
+
+services:
+  server:
+    container_name: server
+    image: server:1.0.0
+    build:
+      context: ./backend
+      dockerfile: Dockerfile
+    command: npm run start:debug
+    env_file: .env
+    ports:
+      - 127.0.0.1:${SERVER_PORT}:3000
+    volumes:
+      # changes in host's ./backend directory will be propagated to the container
+      - ./backend:/usr/src/app
+      # this prevents our host files from overriding container's node_modules
+      - exclude-server:/usr/src/app/node_modules/
+    networks:
+      - backend-network
+    restart: always
+    depends_on:
+      - postgres
+
+  postgres:
+    container_name: postgres
+    image: postgres:14.3-alpine
+    env_file: .env
+    volumes:
+      - ./backend/database-storage:/var/lib/postgresql/data
+    networks:
+      - backend-network
+    environment:
+      POSTGRES_USER: ${DB_USER}
+      POSTGRES_PASSWORD: ${DB_PASSWORD}
+      POSTGRES_DB: ${DB_NAME}
+    restart: always
+
+  adminer:
+    container_name: adminer
+    image: adminer:4.8.1
+    env_file: .env
+    ports:
+      - 127.0.0.1:${ADMINER_PORT}:${ADMINER_PORT}
+    environment:
+      ADMINER_DESIGN: nette
+    restart: always
+    depends_on:
+      - postgres
+
+  client:
+    container_name: client
+    image: client:1.0.0
+    build:
+      context: ./frontend
+      dockerfile: Dockerfile
+    env_file: .env
+    ports:
+      - 127.0.0.1:${CLIENT_PORT}:3000
+    volumes:
+      # changes in host's ./frontend directory will be propagated to the container
+      - ./frontend:/usr/src/app
+      # this prevents our host files from overriding container's node_modules
+      - exclude-client:/usr/src/app/node_modules/
+    restart: always
+
+volumes:
+  database-storage:
+  exclude-server:
+  exclude-client:
+
+networks:
+  backend-network:
diff --git a/frontend/.dockerignore b/frontend/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..ca399854d76119a511bbdc811c030208ec7db75f
--- /dev/null
+++ b/frontend/.dockerignore
@@ -0,0 +1,9 @@
+# Node modules folder
+node_modules
+
+# Git
+.gitignore
+
+# Docker files
+Dockerfile
+.dockerignore
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..3776f627b4bbdf1a921f9e13008cf7fc06315715
--- /dev/null
+++ b/frontend/Dockerfile
@@ -0,0 +1,13 @@
+FROM node:16-alpine
+
+WORKDIR /usr/src
+
+COPY ["package.json", "package-lock.json*", "./"]
+RUN npm install
+ENV PATH=/usr/src/node_modules/.bin:$PATH
+
+WORKDIR /usr/src/app
+
+COPY . .
+
+CMD ["npm", "run", "dev"]
diff --git a/frontend/package.json b/frontend/package.json
index d465e2c1ec70728334b9d8f0ae15bbb162c97aaf..fb6322e2217ffe07934a324a00c8ba60960d5a7a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -3,7 +3,7 @@
   "private": true,
   "version": "0.0.0",
   "scripts": {
-    "dev": "vite",
+    "dev": "vite --host",
     "build": "tsc && vite build",
     "preview": "vite preview"
   },
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index b1b5f91e5ffd7f66fc94356a571e3c60a689c4e5..0b85ee5e9480eff7fc43e870e19373455966af98 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -3,5 +3,10 @@ import react from '@vitejs/plugin-react'
 
 // https://vitejs.dev/config/
 export default defineConfig({
-  plugins: [react()]
+  plugins: [react()],
+  server: {
+    watch: {
+      usePolling: true
+    }
+  }
 })