iT邦幫忙

2025 iThome 鐵人賽

DAY 30
0
Rust

大家一起跟Rust當好朋友吧!系列 第 30

Day 30: 總結、打包 (Docker)

  • 分享至 

  • xImage
  •  

嗨嗨!大家好!歡迎來到 Rust 三十天挑戰的第三十天,也是我們這趟學習旅程的最終章!

三十天的 Rust 學習之旅即將圓滿落幕!從第一天寫下 "Hello, world!" 到今天完成一個功能完整的部落格後端 API,我們一起走過了從零基礎到實戰應用的完整歷程。

今天,我們將為這個專案加上最後的部署配置,讓它真正可以在生產環境中運行,並回顧這一路上的收穫與成長。


🐳 容器化我們的應用程式

現代軟體開發離不開容器化技術。Docker 讓我們可以將應用程式及其運行環境打包成一個輕量、可移植的容器,確保在任何地方都能穩定運行。

建立生產就緒的 Dockerfile

# Multi-stage build for Rust backend
FROM rustlang/rust:nightly-alpine AS builder

# Install build dependencies (cached layer)
RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static pkgconfig curl

# Create app directory
WORKDIR /app

# Copy manifest files first (for dependency caching)
COPY Cargo.toml Cargo.lock ./
COPY migration/Cargo.toml migration/Cargo.lock ./migration/

# Create dummy source files to cache dependencies
RUN mkdir -p src migration/src && \
    echo "fn main() {}" > src/main.rs && \
    echo "fn main() {}" > migration/src/main.rs

# Build dependencies (this layer will be cached)
RUN cargo build --release
RUN rm -rf src migration/src

# Copy real source code
COPY src ./src
COPY migration/src ./migration/src

# Build the application (only app code, dependencies are cached)
RUN touch src/main.rs migration/src/main.rs && \
    cargo build --release

# Runtime stage
FROM alpine:3.19

# Install runtime dependencies
RUN apk add --no-cache ca-certificates openssl wget

# Create non-root user
RUN addgroup -g 1001 -S appgroup && \
    adduser -S appuser -u 1001 -G appgroup

# Create app directory
WORKDIR /app

# Copy the binary from builder stage
COPY --from=builder /app/target/release/blog .

# Change ownership to non-root user
RUN chown -R appuser:appgroup /app
USER appuser

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

# Start the application
CMD ["./blog"]

建立 .dockerignore 檔案

# Rust build artifacts
target/
**/*.rs.bk

# IDE files
.vscode/
.idea/
*.swp
*.swo

# Environment files
.env*

# Git
.git/
.gitignore

# Documentation
README.md
*.md

# Docker files
Dockerfile*
docker-compose*
.dockerignore

# OS files
.DS_Store
Thumbs.db

# Logs
*.log

🚀 使用 Docker Compose 統一管理服務

為了簡化開發與部署,我們建立一個完整的 Docker Compose 配置:

services:
  # PostgreSQL Database
  postgres:
    image: postgres:16-alpine
    container_name: blog-postgres
    environment:
      POSTGRES_DB: personal_blog
      POSTGRES_USER: blog_user
      POSTGRES_PASSWORD: blog_password
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - blog-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U blog_user -d personal_blog"]
      interval: 10s
      timeout: 5s
      retries: 5
    command: >
      postgres
      -c log_statement=all
      -c log_min_duration_statement=0
      -c shared_preload_libraries=pg_stat_statements

  # Rust Backend
  backend:
    build:
      context: ./blog-backend
      dockerfile: Dockerfile
    container_name: blog-backend
    env_file:
      - ./blog-backend/.env
    environment:
      - HOST=0.0.0.0
      - PORT=3000
      - PROTOCOL=http
      - BLOG_NAME=我的個人技術部落格
      - BLOG_DESCRIPTION=分享程式設計學習心得與生活感悟
      - BLOG_AUTHOR=哈囉你好嗎
      - DATABASE_URL=postgres://blog_user:blog_password@postgres:5432/personal_blog
      - DATABASE_MAX_CONNECTIONS=10
      - RUST_LOG=info
      - CORS_ORIGIN=http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://localhost
      - JWT_SECRET=blog_secret_key
      - JWT_EXPIRY_HOURS=24
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=admin123
      - CORS_ORIGINS=http://localhost,http://localhost:80,http://localhost:3000,http://localhost:5173,http://localhost:5174,http://127.0.0.1:3000
      - ENVIRONMENT=production
    ports:
      - "3000:3000"
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - blog-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3

  # React Frontend
  frontend:
    build:
      context: ./blog-frontend
      dockerfile: Dockerfile
    container_name: blog-frontend
    ports:
      - "80:80"
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - blog-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  postgres_data:
    external: true
    name: blog-backend_postgres_data

networks:
  blog-network:
    driver: bridge

💡 前端小提示!!!
這個前端是我用 Lovable來簡單生成的,大家也可以來生成自己喜歡的樣式歐!!
他每天都有一定的免費額度,大家一起來做自己喜歡的Blog吧!!!

環境變數配置

建立 .env.example 作為範本:

HOST=0.0.0.0
PORT=3000
PROTOCOL=http

# 部落格資訊
BLOG_NAME=我的個人技術部落格
BLOG_DESCRIPTION=分享程式設計學習心得與生活感悟
BLOG_AUTHOR=哈囉你好嗎

# 🆕 資料庫設定
DATABASE_URL=postgres://blog_user:blog_password@localhost:5432/personal_blog
DATABASE_MAX_CONNECTIONS=10

# 日誌設定
RUST_LOG=info
CORS_ORIGIN=http://localhost:3000,http://127.0.0.1:3000

# JWT 配置
JWT_SECRET=blog_secret_key
JWT_EXPIRY_HOURS=24

# 管理員帳號
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123

# CORS 配置
CORS_ORIGINS=http://localhost:3000,https://yourdomain.com
ENVIRONMENT=development

📈 三十天學習成果回顧

技能成長軌跡

第一週:Rust 基礎奠基

  • ✅ 掌握 Rust 語法與型別系統
  • ✅ 理解所有權、借用與生命週期
  • ✅ 學會使用結構和列舉
  • ✅ 熟練 Cargo 工具鏈

第二週:核心概念深化

  • ✅ 掌握集合型別與錯誤處理
  • ✅ 學會泛型與特徵的應用
  • ✅ 深入理解生命週期標記
  • ✅ 理解智慧指標與記憶體管理

第三週:現代化開發技術

  • ✅ 掌握函數式程式設計思維
  • ✅ 學會併發與非同步程式設計
  • ✅ 理解模組系統與專案組織
  • ✅ 完成專案架構設計

第四週:實戰項目開發

  • ✅ 建構完整的 Web API 服務
  • ✅ 整合資料庫與 ORM
  • ✅ 實現認證與授權機制
  • ✅ 掌握容器化與部署流程

專案技術成就

我們成功建構的部落格後端具備:

核心功能

  • 📝 完整的文章 CRUD 操作
  • 🏷️ 靈活的標籤分類系統
  • 💬 互動式留言功能
  • 👤 安全的用戶認證機制

技術特色

  • ⚡ 基於 Tokio 的高效能非同步處理
  • 🛡️ 型別安全的資料庫操作
  • 🚀 零成本抽象與記憶體安全
  • 🐳 容器化的部署解決方案

🎉 三十天挑戰學習Rust並完成一個個人Blog慶祝

最終成果展示

我們成功完成了:

技術成就

  • 🦀 從零開始掌握 Rust 程式語言
  • 🌐 建構了功能完整的 Web API 服務
  • 🏗️ 學會了現代軟體開發的最佳實務

學習里程碑

  • Week 1:Rust 基礎與所有權系統
  • Week 2:進階概念與型別系統
  • Week 3:現代開發技術與生態系
  • Week 4:實戰專案與部署

持續學習的心態

程式設計是一個永無止境的學習過程。Rust 雖然有一定的學習門檻,但它提供了獨特的價值:

記憶體安全 + 高效能 + 現代語言特性


今天就先到此結束拉!主要的內容大致上都講得差不多了,我們明天來不務正業一下,講個我覺得很有趣,看起來很瞎趴的東西 TUI (terminal UI)!!

有興趣的我們明天見!!


上一篇
Day 29: 簡單的安全防護 - 保護你的創作平台
系列文
大家一起跟Rust當好朋友吧!30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言