Files
SkyArtShop/Sky_Art_shop/LINUX_MIGRATION_GUIDE.md
Local Server 703ab57984 Fix admin route access and backend configuration
- Added /admin redirect to login page in nginx config
- Fixed backend server.js route ordering for proper admin handling
- Updated authentication middleware and routes
- Added user management routes
- Configured PostgreSQL integration
- Updated environment configuration
2025-12-13 22:34:11 -06:00

16 KiB

Sky Art Shop - Linux Server Migration Guide

Migration: Windows IIS → Linux with Nginx + Systemd
Goal: Zero-downtime deployments, better stability, auto-reload on file changes


🎯 Why Linux?

Zero-downtime deployments - Systemd can reload without dropping connections
Better stability - No port conflicts, no Default Web Site issues
Auto-reload - File changes auto-reload without manual restarts
Lower resource usage - More efficient than IIS
Industry standard - Most .NET Core production apps run on Linux


📋 Part 1: Linux Server Setup

Option A: Local Ubuntu Server (Recommended for you)

  • Use Ubuntu 22.04 LTS Server
  • Can run on same Windows PC using WSL2 or separate machine
  • Free and full control

Option B: Cloud VPS

  • DigitalOcean: $6/month
  • Linode: $5/month
  • Vultr: $6/month

Step 1: Install Ubuntu Server

If using WSL2 on Windows:

# In Windows PowerShell (Admin)
wsl --install -d Ubuntu-22.04

# Launch Ubuntu
wsl -d Ubuntu-22.04

If using separate Linux machine:


📦 Part 2: Install Required Software on Linux

Update System

sudo apt update && sudo apt upgrade -y

Install .NET 8.0 Runtime

# Add Microsoft package repository
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

# Install .NET Runtime and SDK
sudo apt update
sudo apt install -y dotnet-sdk-8.0 aspnetcore-runtime-8.0

# Verify installation
dotnet --version

Install MongoDB on Linux

# Import MongoDB public GPG key
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | \
   sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

# Add MongoDB repository
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
   sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Install MongoDB
sudo apt update
sudo apt install -y mongodb-org

# Start MongoDB
sudo systemctl start mongod
sudo systemctl enable mongod

# Verify MongoDB is running
sudo systemctl status mongod
mongosh --eval "db.version()"

Install Nginx (Web Server / Reverse Proxy)

sudo apt install -y nginx

# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# Verify Nginx is running
sudo systemctl status nginx

📤 Part 3: Export Data from Windows MongoDB

On Windows

# Create export directory
New-Item -ItemType Directory -Path "E:\mongodb_backup" -Force

# Export MongoDB database (run in PowerShell)
$mongoExport = "C:\Program Files\MongoDB\Server\8.0\bin\mongodump.exe"
if (Test-Path $mongoExport) {
    & $mongoExport --db SkyArtShopDB --out "E:\mongodb_backup"
    Write-Host "✅ MongoDB data exported to E:\mongodb_backup"
} else {
    # Alternative: Use mongodump from command line
    mongodump --db SkyArtShopDB --out "E:\mongodb_backup"
}

# Export SQLite Identity database
Copy-Item "E:\Documents\Website Projects\Sky_Art_Shop\identity.db" "E:\mongodb_backup\identity.db"

# Export uploaded images
Copy-Item "E:\Documents\Website Projects\Sky_Art_Shop\wwwroot\uploads\images\*" "E:\mongodb_backup\images\" -Recurse

Write-Host "✅ All data exported successfully"
#
# Transfer files to Ubuntu VM using SCP (PuTTY/PSCP)
# Make sure you have PSCP.exe from PuTTY installed
# Example (replace with your actual username and IP):
pscp -pw PTBelize@3030! -r "E:\mongodb_backup" PTS@192.168.10.129:/home/PTS/

📁 Part 4: Transfer Files to Linux

Method 1: Using SCP (if Linux is separate machine)

# On Windows, transfer files
scp -r "E:\mongodb_backup" username@linux-server-ip:/home/username/
scp -r "E:\Documents\Website Projects\Sky_Art_Shop" username@linux-server-ip:/home/username/skyartshop

Method 2: Using WSL2 (if running on same Windows machine)

# Files are accessible at /mnt/e/ in WSL
# In WSL terminal:
# Copy files to Linux home directory
cp -r /mnt/e/mongodb_backup ~/mongodb_backup
cp -r "/mnt/e/Documents/Website Projects/Sky_Art_Shop" ~/skyartshop

📥 Part 5: Import Data to Linux MongoDB

# Navigate to backup directory
cd ~/mongodb_backup

# Import MongoDB data
mongorestore --db SkyArtShopDB ./SkyArtShopDB

# Verify data imported
mongosh --eval "use SkyArtShopDB; db.Products.countDocuments()"

# Create MongoDB user for security (optional but recommended)
mongosh <<EOF
use admin
db.createUser({
  user: "skyartshop",
  pwd: "YourSecurePassword123!",
  roles: [{ role: "readWrite", db: "SkyArtShopDB" }]
})
exit
EOF

🚀 Part 6: Deploy Application on Linux

Create Application Directory

# Create directory for application
sudo mkdir -p /var/www/skyartshop
sudo chown -R $USER:$USER /var/www/skyartshop

# Copy application files
cp -r ~/skyartshop/* /var/www/skyartshop/

# Copy identity database
cp ~/mongodb_backup/identity.db /var/www/skyartshop/

# Create uploads directory and copy images
mkdir -p /var/www/skyartshop/wwwroot/uploads/images
cp ~/mongodb_backup/images/* /var/www/skyartshop/wwwroot/uploads/images/

# Set permissions
sudo chown -R www-data:www-data /var/www/skyartshop
sudo chmod -R 755 /var/www/skyartshop

Update Connection Strings (if using MongoDB authentication)

nano /var/www/skyartshop/appsettings.json

Update MongoDB connection:

{
  "MongoDB": {
    "ConnectionString": "mongodb://skyartshop:YourSecurePassword123!@localhost:27017",
    "DatabaseName": "SkyArtShopDB"
  }
}

Publish Application for Linux

cd /var/www/skyartshop
dotnet publish SkyArtShop.csproj -c Release -o ./publish

⚙️ Part 7: Create Systemd Service (Auto-start & Management)

Create Service File

sudo nano /etc/systemd/system/skyartshop.service

Add this content:

[Unit]
Description=Sky Art Shop ASP.NET Core Application
After=network.target

[Service]
WorkingDirectory=/var/www/skyartshop/publish
ExecStart=/usr/bin/dotnet /var/www/skyartshop/publish/SkyArtShop.dll
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=skyartshop
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

Enable and Start Service

# Reload systemd
sudo systemctl daemon-reload

# Enable service to start on boot
sudo systemctl enable skyartshop

# Start the service
sudo systemctl start skyartshop

# Check status
sudo systemctl status skyartshop

# View logs
sudo journalctl -u skyartshop -f

🌐 Part 8: Configure Nginx as Reverse Proxy

Create Nginx Configuration

sudo nano /etc/nginx/sites-available/skyartshop

Add this configuration:

server {
    listen 80;
    server_name skyarts.ddns.net localhost;

    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Timeouts
        proxy_connect_timeout 600;
        proxy_send_timeout 600;
        proxy_read_timeout 600;
        send_timeout 600;
    }

    # Static files
    location /uploads/ {
        alias /var/www/skyartshop/publish/wwwroot/uploads/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location /assets/ {
        alias /var/www/skyartshop/publish/wwwroot/assets/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Max upload size
    client_max_body_size 20M;
}

Enable Site

# Create symbolic link
sudo ln -s /etc/nginx/sites-available/skyartshop /etc/nginx/sites-enabled/

# Remove default site
sudo rm /etc/nginx/sites-enabled/default

# Test configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

🔥 Part 9: Configure Firewall

# Allow SSH (if remote server)
sudo ufw allow 22/tcp

# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status

🔄 Part 10: Zero-Downtime Deployment Script

Create deployment script for future updates:

nano ~/deploy.sh

Add this content:

#!/bin/bash

echo "🚀 Starting deployment..."

# Navigate to source directory
cd ~/skyartshop

# Pull latest changes (if using git)
# git pull origin main

# Build application
echo "📦 Building application..."
dotnet publish SkyArtShop.csproj -c Release -o /tmp/skyartshop_new

# Stop old service gracefully
echo "⏸️  Stopping service..."
sudo systemctl stop skyartshop

# Backup current version
echo "💾 Backing up current version..."
sudo mv /var/www/skyartshop/publish /var/www/skyartshop/publish_backup_$(date +%Y%m%d_%H%M%S)

# Deploy new version
echo "📤 Deploying new version..."
sudo mv /tmp/skyartshop_new /var/www/skyartshop/publish

# Ensure correct permissions
sudo chown -R www-data:www-data /var/www/skyartshop/publish
sudo chmod -R 755 /var/www/skyartshop/publish

# Start service
echo "▶️  Starting service..."
sudo systemctl start skyartshop

# Check if service started successfully
sleep 2
if sudo systemctl is-active --quiet skyartshop; then
    echo "✅ Deployment successful!"
    echo "🌐 Site is live at http://skyarts.ddns.net"
else
    echo "❌ Service failed to start. Rolling back..."
    sudo systemctl stop skyartshop
    latest_backup=$(ls -t /var/www/skyartshop/ | grep publish_backup | head -1)
    sudo mv /var/www/skyartshop/publish /var/www/skyartshop/publish_failed
    sudo mv /var/www/skyartshop/$latest_backup /var/www/skyartshop/publish
    sudo systemctl start skyartshop
    echo "⚠️  Rolled back to previous version"
fi

# View logs
sudo journalctl -u skyartshop -n 20

Make script executable:

chmod +x ~/deploy.sh

🌐 Part 11: Network Configuration

Update Router Port Forwarding

  • Forward port 80 (HTTP) to your Linux server's IP (not Windows anymore)
  • If WSL2, forward to Windows IP (WSL2 uses NAT)

Update No-IP DUC

  • Install No-IP DUC on Linux:
cd /usr/local/src
sudo wget http://www.noip.com/client/linux/noip-duc-linux.tar.gz
sudo tar xzf noip-duc-linux.tar.gz
cd noip-2.1.9-1
sudo make
sudo make install

# Configure
sudo noip2 -C

# Start service
sudo noip2

# Install Certbot
sudo apt install -y certbot python3-certbot-nginx

# Get SSL certificate
sudo certbot --nginx -d skyarts.ddns.net

# Auto-renewal is configured automatically
sudo certbot renew --dry-run

📊 Part 13: Monitoring & Management

Useful Commands

# View application logs
sudo journalctl -u skyartshop -f

# Restart application
sudo systemctl restart skyartshop

# Stop application
sudo systemctl stop skyartshop

# Start application
sudo systemctl start skyartshop

# Check application status
sudo systemctl status skyartshop

# View Nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# Check MongoDB status
sudo systemctl status mongod

# Check disk space
df -h

# Check memory usage
free -h

# Check CPU usage
top

🔄 Daily Workflow: Making Changes

Option 1: Edit Locally, Deploy

# 1. Edit files on Windows in VS Code
# 2. Transfer to Linux
scp -r "E:\Documents\Website Projects\Sky_Art_Shop\*" username@linux:/home/username/skyartshop/

# 3. Run deployment script
ssh username@linux
./deploy.sh
# SSH into Linux server
ssh username@linux

# Navigate to source
cd ~/skyartshop

# Edit files with nano or vim
nano Views/Shared/_AdminLayout.cshtml

# Deploy changes
./deploy.sh

Option 3: Use Git (Best Practice)

# On Windows, commit changes
git add .
git commit -m "Updated admin sidebar"
git push origin main

# On Linux, pull and deploy
ssh username@linux
cd ~/skyartshop
git pull origin main
./deploy.sh

🎯 Advantages Over Windows/IIS

Feature Windows/IIS Linux/Nginx
Zero-downtime Requires restart Seamless reload
Port conflicts Common issue No conflicts
Resource usage ⚠️ Higher Lower
Deployment ⚠️ Manual, downtime Scripted, automated
File changes ⚠️ Requires restart Auto-reload
Stability ⚠️ Default site issues Very stable
Cost 💰 Windows Server license Free
Performance ⚠️ Good Excellent

🆘 Troubleshooting

Service won't start

# Check logs
sudo journalctl -u skyartshop -n 50

# Check if port 5000 is available
sudo netstat -tulpn | grep 5000

# Test application manually
cd /var/www/skyartshop/publish
dotnet SkyArtShop.dll

MongoDB connection issues

# Check MongoDB is running
sudo systemctl status mongod

# Check connection
mongosh --eval "db.adminCommand('ping')"

# View MongoDB logs
sudo tail -f /var/log/mongodb/mongod.log

Nginx issues

# Check Nginx configuration
sudo nginx -t

# View error logs
sudo tail -f /var/log/nginx/error.log

# Restart Nginx
sudo systemctl restart nginx

📝 Migration Checklist

  • Ubuntu Server 22.04 installed
  • .NET 8.0 SDK/Runtime installed
  • MongoDB installed and running
  • Nginx installed and configured
  • MongoDB data exported from Windows
  • SQLite identity.db copied
  • Images copied to Linux
  • MongoDB data imported to Linux
  • Application deployed to /var/www/skyartshop
  • Systemd service created and running
  • Nginx reverse proxy configured
  • Firewall configured
  • Router port forwarding updated
  • No-IP DUC configured on Linux
  • Site accessible at skyarts.ddns.net
  • Admin login working
  • Images displaying correctly
  • Deployment script tested
  • HTTPS configured (optional)

🎉 Success

Once completed, your site will be:

  • Running on stable Linux infrastructure
  • Auto-reloading on file changes
  • Zero-downtime deployments
  • Better performance
  • No more IIS headaches!

Your site: http://skyarts.ddns.net
Admin panel: http://skyarts.ddns.net/admin


📞 Need Help?

Common resources:


Ready to migrate? Start with Part 1! 🚀