diff --git a/server-configuration/staging.md b/server-configuration/staging.md
new file mode 100644
index 0000000..5065aa8
--- /dev/null
+++ b/server-configuration/staging.md
@@ -0,0 +1,217 @@
+# Server configuration of the staging server
+
+Staging server has `51.161.134.20` IP address and `staging.cellar.social` DNS record associated with it.
+
+`otto` user has sudo rights at staging server, all operations that require sudo rights will be performed under this user.
+
+## Fail2ban
+
+Install `fail2ban` to scan the log files for too many failed login attempts and block the IP address which is showing malicious signs.
+
+```bash
+sudo apt-get install fail2ban
+```
+
+## Nginx
+
+Under `otto` user:
+
+```bash
+# Update packages
+sudo apt update
+
+# Install Nginx
+sudo apt install nginx
+
+# List the application configurations that ufw knows how to work with
+sudo ufw app list
+
+# Activate firewall
+sudo ufw enable
+
+# Allow ssh connections
+sudo ufw allow 'OpenSSH'
+
+# Allow HTTPS traffic
+sudo ufw allow 'Nginx HTTPS'
+
+# Allow HTTP traffic (HTTP traffic should be allowed to equire SSL certificate and will be disabled later)
+sudo ufw allow 'Nginx HTTP'
+
+# Check ufw status
+sudo ufw status
+
+# Check Nginx status
+systemctl status nginx
+
+# Create the directory for `api` domain
+sudo mkdir -p /var/www/api/html
+
+# Assign ownership of the directory to the `api` user
+sudo chown -R api:api /var/www/api/html
+
+# Adjust permissions
+sudo chmod -R 755 /var/www/api
+
+# Install certbot
+sudo apt install certbot python3-certbot-nginx
+
+# Fetch a certificate from Let's Encrypt and follow the prompts
+sudo certbot --nginx -d staging.cellar.social
+
+# Verify that certificate renewal is on
+sudo systemctl status certbot.timer
+
+# Create a configuration file for api subdomain
+sudo nano /etc/nginx/sites-available/api
+```
+
+Paste into `/etc/nginx/sites-available/api`:
+
+```bash
+server {
+    listen 80;
+    listen [::]:80;
+
+    root /var/www/html;
+    index index.html index.htm index.nginx-debian.html;
+
+    # Put your domain name here
+    server_name staging.cellar.social;
+
+    # Needed for Let's Encrypt verification
+    location ~ /.well-known/acme-challenge {
+	    allow all;
+    }
+
+    # Force HTTP to HTTPS
+    location / {
+	    return 301 https://$http_host$request_uri;
+    }
+}
+
+server {
+    listen 443 ssl http2;
+
+    ssl on;
+
+    # SSL certificate by Let's Encrypt in this Nginx
+    ssl_certificate      /etc/letsencrypt/live/staging.cellar.social/fullchain.pem;
+    ssl_certificate_key  /etc/letsencrypt/live/staging.cellar.social/privkey.pem;
+
+    # root /var/www/html;
+    # index index.html index.htm index.nginx-debian.html;
+
+    # domain name here
+    server_name staging.cellar.social;
+
+    location /api {
+	proxy_pass http://127.0.0.1:3000/;
+
+	proxy_set_header Host $http_host;
+	proxy_set_header X-Forwarded-Proto $scheme;
+	proxy_set_header X-Real-IP $remote_addr;
+	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+	proxy_set_header Upgrade $http_upgrade;
+    }
+
+    # Needed for Let's Encrypt verification
+    location ~ /.well-known/acme-challenge {
+	allow all;
+    }
+}
+```
+
+Next:
+
+```bash
+# Enable the file by creating a link from it to the sites-enabled directory, which Nginx reads from during startup
+sudo ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/
+
+# Restart Nginx
+sudo systemctl restart nginx
+
+# Check Nginx status
+systemctl status nginx
+
+# Check firewall status
+sudo ufw status
+
+# Deny HTTP traffic
+sudo ufw deny 'Nginx HTTP'
+
+# Check firewall status
+sudo ufw status
+```
+
+## Install Node and NPM
+
+```bash
+# Update packages
+sudo apt update
+
+# Install nvm (node version manager)
+curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
+
+# Install Node v20
+nvm install 20.12.2
+
+# Set 20.12.2 as a default version of Node
+nvm alias default 20.12.2
+
+# Use default Node version
+nvm use default
+```
+
+## API user
+
+`api` user doesn't have sudo rights and will be used to run `cellar-api` and all related processes.
+
+Under `otto` user:
+
+```bash
+# Create api user
+sudo adduser api
+
+# Switch to api user
+su api
+```
+
+Under `api` user:
+
+```bash
+# Generate SSH keys.
+# These keys will be used by CI/CD pipeline.
+ssh-keygen
+
+# Change to ssh directory
+cd .ssh/
+
+# Create authorized_keys file
+touch authorized_keys
+
+# Copy public key from `id_ed25519.pub` and paste into `authorized_keys` file
+# Private key is stored in SSH_STAGING_PRIVATE_KEY variable of the CI/CD pipeline.
+
+# Install PM2 package globally
+npm i -g pm2
+
+# Clone cellar/cs-backend repository
+git clone ssh://git@git.nostrdev.com:29418/cellar/cs-backend.git
+
+# Change to cs-backend directory
+cd cs-backend
+
+# Install dependencies
+npm ci
+
+# Build API app
+npm run build
+
+# Start API app
+npm run start
+
+# Verify that cellar-api process is running
+pm2 list
+```