Search

Linux Server Cho .NET Dev: Setup Từ Zero

Linux Server Cho .NET Dev: Setup Từ Zero

Hồi trước mỗi lần nghe ai nói "deploy lên Linux" là tôi lại thấy hơi ớn. Quen tay với Windows Server, IIS, click-click là xong — giờ đột nhiên phải gõ terminal, không có GUI, không có nút bấm. Nhưng sau vài lần mò mẫm thực tế, thật ra nó không đáng sợ đến vậy. Bài này tôi viết lại toàn bộ quá trình setup từ đầu, theo đúng thứ tự tôi đã làm.

Tại Sao .NET Dev Nên Biết Linux?

Không phải vì trend, không phải vì "mọi người đang làm vậy". Lý do thực tế hơn:

  • Chi phí: VPS Linux rẻ hơn Windows Server đáng kể, đặc biệt khi scale nhiều instance.
  • Docker & container: Hầu hết base image cho .NET đều là Linux. Muốn chạy container production thì không tránh khỏi.
  • CI/CD pipelines: GitHub Actions, Cloud Build, GitLab CI — mặc định chạy trên Linux runner.
  • ASP.NET Core chạy tốt trên Linux: Microsoft đã đầu tư rất nghiêm túc vào cross-platform từ .NET Core. Không có lý do gì phải bám Windows nữa.

Chuẩn Bị

Bài này dùng Ubuntu 22.04 LTS — lý do đơn giản là LTS (Long Term Support), tài liệu nhiều, package repo ổn định. Bạn dùng distro khác thì hầu hết lệnh vẫn tương tự, chỉ khác phần package manager.

Bạn cần:

  • 1 VPS hoặc máy ảo Ubuntu 22.04 (DigitalOcean, Vultr, Hetzner, hay local VM đều được)
  • SSH access với quyền sudo
  • Một project ASP.NET Core để test (nếu chưa có, dùng dotnet new webapi tạm)

Bước 1: Cập Nhật Hệ Thống

Việc đầu tiên khi có server mới — update package list và upgrade toàn bộ package hiện tại:

sudo apt update && sudo apt upgrade -y

Nghe đơn giản nhưng nhiều người bỏ qua. Package cũ = lỗ hổng bảo mật tiềm ẩn.


Bước 2: Cài .NET SDK / Runtime

Microsoft cung cấp package repo riêng cho Ubuntu. Cài theo thứ tự sau:

# Thêm Microsoft package repo
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

# Cài .NET SDK (nếu server này cần build code)
sudo apt update && sudo apt install -y dotnet-sdk-8.0

# Hoặc chỉ cài Runtime nếu chỉ chạy app đã build sẵn
sudo apt install -y aspnetcore-runtime-8.0

Kiểm tra:

dotnet --version
# 8.0.xxx

Lưu ý: Nếu bạn dùng pipeline CI/CD để build rồi đẩy artifact lên server, cài Runtime là đủ. Không cần SDK trên production server — nhẹ hơn, ít attack surface hơn.


Bước 3: Publish App và Upload Lên Server

Trên máy local, publish app trước:

dotnet publish MyApp -c Release -r linux-x64 --self-contained false -o ./publish

Rồi copy lên server bằng scp:

scp -r ./publish/* user@your-server-ip:/var/www/myapp/

Hoặc dùng rsync nếu muốn sync incremental:

rsync -avz ./publish/ user@your-server-ip:/var/www/myapp/

Tạo thư mục đích nếu chưa có:

sudo mkdir -p /var/www/myapp
sudo chown -R $USER:$USER /var/www/myapp

Bước 4: Chạy App Dưới Dạng systemd Service

Đây là phần quan trọng nhất. Không ai chạy app bằng cách dotnet MyApp.dll rồi để terminal mở. Dùng systemd để quản lý process như một service thật sự — tự restart khi crash, tự start khi reboot server.

Tạo file service:

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

Nội dung:

[Unit]
Description=My ASP.NET Core App
After=network.target

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

[Install]
WantedBy=multi-user.target

Kích hoạt và chạy:

sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

# Kiểm tra trạng thái
sudo systemctl status myapp

Xem log realtime:

sudo journalctl -u myapp -f

Bước 5: Cài Nginx Làm Reverse Proxy

ASP.NET Core mặc định chạy Kestrel trên port 5000/5001. Không nên expose thẳng ra ngoài. Dùng Nginx làm reverse proxy — xử lý SSL, rate limiting, và forward request vào Kestrel.

sudo apt install -y nginx

Tạo config cho site:

sudo nano /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name yourdomain.com;

    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_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_cache_bypass $http_upgrade;
    }
}

Enable config và restart Nginx:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t   # kiểm tra syntax trước khi restart
sudo systemctl restart nginx

Bước 6: Cài SSL với Let's Encrypt

HTTPS bây giờ là bắt buộc. Certbot + Let's Encrypt làm việc này miễn phí và tự động gia hạn.

sudo apt install -y certbot python3-certbot-nginx

sudo certbot --nginx -d yourdomain.com

Certbot sẽ tự sửa file Nginx config để thêm SSL. Sau bước này Nginx sẽ listen trên port 443, và redirect HTTP → HTTPS tự động.

Kiểm tra auto-renewal:

sudo certbot renew --dry-run

Bước 7: Firewall Cơ Bản

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

sudo ufw status

Chỉ mở đúng port cần thiết. Port 5000 (Kestrel) không cần expose ra ngoài vì Nginx đã làm proxy.


Một Số Lỗi Hay Gặp

App không start được sau khi deploy: Chạy journalctl -u myapp -n 50 để xem log chi tiết. Thường là lỗi connection string, missing environment variable, hoặc thiếu quyền đọc file.

Nginx 502 Bad Gateway: App chưa start hoặc đang crash. Check systemctl status myapp trước.

Permission denied khi write file: App chạy dưới user www-data — cần cấp quyền write cho thư mục tương ứng:

sudo chown -R www-data:www-data /var/www/myapp

Environment variable không nhận: Nếu dùng appsettings.json thì cần đảm bảo file đã upload lên server. Nếu inject qua systemd service thì thêm dòng Environment=KEY=VALUE trong file .service. Hoặc dùng file /etc/environment cho biến global.


Kết

Setup xong rồi thì thật ra quản lý server Linux không khó như hồi đầu nghĩ. Mấy lệnh hay dùng nhất cũng chỉ xoay quanh systemctl, journalctl, nginx -t, và scp/rsync. Phần mất thời gian nhất thường là lần đầu — sau đó có thể script hóa hoặc nhét vào CI/CD pipeline cho lần sau nhanh hơn.

Nếu bạn đang dùng Docker thay vì deploy thẳng binary, flow sẽ khác một chút — phần đó mình sẽ viết riêng một bài.


W3Dev.vn — Viết cho dev, bởi dev.

Culi Dev

Culi Dev

Enjoy coding, enjoy life!

Leave a comment

Your email address will not be published. Required fields are marked *

Your experience on this site will be improved by allowing cookies Cookie Policy