首頁 >資料庫 >mysql教程 >使用 Docker 和 MySQL 設定新的 Rails 應用程式

使用 Docker 和 MySQL 設定新的 Rails 應用程式

Barbara Streisand
Barbara Streisand原創
2025-01-04 18:36:44212瀏覽

我是一家中型技術和數據公司的高級軟體工程師。從歷史上看,我曾擔任過很多職務:我建立了客戶獲取流程,完成了資料庫管理,複雜的React 工作,為內部使用精心設計了功能齊全的CMS,從頭開始構建了面向公眾的Golang API 微服務,精心設計了API 身份驗證系統,交付了各種B2B 和B2C 產品,(同時)擔任多個團隊的技術主管等等。目前,我對於從頭開始建立新的 Rails 應用程式還缺乏實踐。所以我想我應該嘗試一下!

這是一個非常基本的教程,但我發現缺乏實用指南。話雖這麼說,我確實想大聲說出我在寫這篇文章時大量借用的兩個教程——將其視為這些帖子加上我個人喜好的綜合:Tallan Groberg 和 Nicolas Iensen。我們將避開很多細節,以便直接進入。我使用全新的 M4 Macbook Pro 來撰寫本文,但基礎知識應該適用於大多數 Mac 或 Linux 環境。

我們將建立一個簡單的Ruby 應用程序,它使用Rails 作為主框架,使用MySQL 作為資料庫(部分是因為它的功能,部分是為了增加我在這篇文章中的目標的複雜性),以及Docker用於虛擬化和跨平台相容性。在本教程中,我們不會建立任何模型或控制器:這都是關於設定的。在本教程結束時,您將擁有一個非常經典的 Hello World 應用程式。您應該能夠掌握這個基本概念並將其應用到您正在建立的任何應用程式中。

入門

首先,這假設您對終端機和基於 Unix 的電腦有一定的熟悉。如果這在某種程度上有意義,那麼您將需要安裝 Docker 和 Homebrew(假設您使用的是 Mac)。如果您執行 zsh 作為主 shell(現在大多數 Mac 都是預設的),您可能需要將以下內容新增至 ~/.zshrc 檔案中以便能夠執行 brew 命令:

path+=/opt/homebrew/bin

儲存檔案後,執行 source ~/.zshrc 就可以了!

小提示:以 $ 為前綴的命令表示在本地 shell(最有可能是 zsh 或 bash)中運行的命令,而以 # 為前綴的命令在 Docker 容器內運行。在所有情況下,不應複製前綴,它只是新行提示的視覺指示符。

首先要事

許多開發人員將所有編碼專案放入一個目錄中(我的專案是「下載」和「文件」目錄的同級目錄,我創造性地將其稱為「程式碼」)。在終端機中,導航到等效目錄並鍵入以下命令:

$ mkdir my-app
$ cd my-app

在這個新目錄中,我們需要一些新檔案。使用以下命令創建它們:

path+=/opt/homebrew/bin

首先,Dockerfile.dev 將創建您的基礎Docker 映像,在現有映像的基礎上構建,該映像安裝了我們將用於此專案的Ruby 版本(撰寫本文時最新版本為3.3.6)並進行設定關於該圖像應如何表現的一些小細節。檔案名稱的 .dev 部分錶示該 Dockerfile 僅在本機使用,而不是在生產環境中使用。我們在本教程後面運行的命令實際上將為我們建立一個更強大的生產就緒 Dockerfile,我希望能夠區分這兩者。鑑於本教程的範圍,我們並不擔心這些細節。將以下行加入該文件:

$ mkdir my-app
$ cd my-app

接下來是docker-compose.yml 檔案:它的目的是將多個Docker 容器協調在一起,以確保我們正在建置的Web 應用程式的所有組成部分都可以一起通訊:Web 伺服器、資料庫、潛在的Redis 伺服器,也許是Elasticsearch 伺服器等。所有這些不同的元素都將存在於它們自己的「虛擬電腦」中,並且需要以模仿生產環境的方式進行連接以相互通訊。理論知識已經足夠了,重要的是我們需要在 docker-compose.yml 檔案中添加一些設定碼:

$ touch Dockerfile.dev
$ touch docker-compose.yml
$ touch Gemfile

不用擔心細節,但它基本上是在說“當你運行這個程式時,你將運行一個名為“web”的應用程序,它將嘗試使用一個名為“Dockerfile.dev”的dockerfile 構建主應用程式' 並將docker 系統網路中的內部連接埠3000 對應到其運行的本機電腦的連接埠3000 哦,而且,啟動資料庫並允許它們相互通訊。如果您已經在連接埠 3000 上執行應用程序,請隨意將左側連接埠號碼變更為您喜歡的任何連接埠號碼。

好的!現在我們有一個檔案將建立一個映像,另一個檔案將使用該映像運行容器並將其彈出到它啟動的小網路中。好的!但是...我們該怎麼做呢?

進入其中

為了開始清理,我們需要實際進入我們正在建造的容器中做一些事情。我們透過執行以下命令來做到這一點:

FROM ruby:3.3.6

WORKDIR /usr/src/app

COPY . .
RUN bundle install

現在我們在電腦中。我們的想法是,現在我們可以在容器的環境中執行命令,而無需在我們正在使用的電腦上安裝某些軟體。例如,Rails 不需要存在於電腦上的任何位置即可在電腦上執行的 Docker 容器上運作。很漂亮。

好吧,現在我們已經開始了,讓我們安裝 Rails:

services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: app
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3307:3306"
  web:
    build:
      context: .
      dockerfile: Dockerfile.dev
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ".:/usr/src/app"
    ports:
      - "3000:3000"
    depends_on:
      - db
    links:
      - db
    environment:
      DB_USER: root
      DB_NAME: app
      DB_PASSWORD: password
      DB_HOST: db

現在讓我們創建我們的應用程式!我們想使用 MySQL 建立此應用程序,因此請在以下命令中記下其規格:

path+=/opt/homebrew/bin

這需要一點時間。系統會詢問您是否要覆寫 Gemfile。按 y 確認。對於此命令產生的任何其他文件,系統都會詢問您相同的問題。相應地使用 y/n 鍵跳過或接受新版本。

萬歲!我們已經完成了應用程式的框架!然而,我們實際上還沒有完成。我們必須解決一個重要問題才能讓資料庫做好準備。然後,理想情況下,我們應該解決一個重要的安全細節。

設定資料庫

如果您只是在本地做一些事情並且不打算部署任何內容,那麼本節的第一部分可能不是非常必要。此外,這裡還有很多需要考慮的地方,我認為值得一個單獨的教程來深入研究一些資料庫配置和基本存儲庫安全性- 特別是如果您的存儲庫是公共的(如果是公共的,不用擔心,只要小心即可!

透過前面的指令,我們最後得到了大量的新檔案和目錄。其中之一就是 config/database.yml。對我來說,第 12 行是一個如下圖的區塊:


$ mkdir my-app
$ cd my-app
從技術上講,上述方法是有效的。這沒有什麼「問題」。但我們可以做得更好。最大的問題是我們的資料庫沒有密碼。下一個問題是資料庫沒有名稱。最後,使用者名稱以純文字形式可見。不是我最喜歡的。讓我們用以下內容更改所有內容(以下第一個是新字段,後兩個應替換任何現有值):


$ touch Dockerfile.dev
$ touch docker-compose.yml
$ touch Gemfile
您也可以使用 ENV.fetch("VARIABLE_NAME") { "fallback_value" } 樣式。 ENV["VARIABLE_NAME"] 和ENV.fetch("VARIABLE_NAME") 之間的區別在於,如果前者找不到具有指定名稱的環境變量,則前者將返回nil,而後者可能會引發一些警告或錯誤(請請參閱此有關ENV.fetch 的更多資訊)。

有了這些,假設您還沒有退出 shell(您可以使用 docker-compose run --service-ports web bash 重新進入),我們需要建立一個新的資料庫。使用以下命令執行此操作:


FROM ruby:3.3.6

WORKDIR /usr/src/app

COPY . .
RUN bundle install
退出 Docker shell 並在本機終端機環境中執行以下命令:


services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: app
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3307:3306"
  web:
    build:
      context: .
      dockerfile: Dockerfile.dev
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ".:/usr/src/app"
    ports:
      - "3000:3000"
    depends_on:
      - db
    links:
      - db
    environment:
      DB_USER: root
      DB_NAME: app
      DB_PASSWORD: password
      DB_HOST: db
就是這樣!如果您將瀏覽器(或像 Postman 這樣的 API 用戶端)指向 localhost:3000,您

應該看到經典的 Rails 啟動頁面:

Setting up a new Rails application with Docker & MySQL

添加一些極其簡單的安全性

我們已經有一個可以運行的應用程式了!它配備了一個很好的資料庫,可供生產作業使用(Rails 提供的預設資料庫 SQLite,非常適合將基本想法組合在一起,但它不適合生產工作,而且它的創建者是個怪人)!但更強大的資料庫需要承擔一些額外的責任。

正如我們在本教程前面所看到的,我們的任務是提供三個重要的值:資料庫名稱、使用者名稱和該使用者的密碼。到目前為止,我們有 1 層抽象:我們從 Rails 環境中取得這些值,而不是只將原始字串值傳遞到 database.yml。那麼,Rails 環境從哪裡取得這些值呢?來自 docker-compose.yml 檔案!

但這留下了一個有待解決的重要問題:假設我們要在生產中使用此程式碼,我們已經在程式碼本身中包含了除系統管理員之外任何人都不應有權存取的資訊。那不太好。我們應該有一個額外的抽象層,消除對某些有價值的、理論上包含的資訊的任何直接引用。

現在,我們必須在 Ruby 環境首次啟動時實際 GET 在 Ruby 環境中正確設定這些環境變數。我們將分兩步驟完成此操作,但如果您願意,也可以一步完成。首先,我們需要停止直接引用 Rails 專案中的資料庫機密。我們正在這樣做。接下來我們需要將它們從 Docker 傳輸到 Rails 中。最後,我們將透過添加我們對 Git 隱藏的文件中的秘密值來進一步抽象化它,以更好地掩蓋這些訊息,防止潛在的不善行為。

將環境變數從 Docker 傳送到 Rails

我們有幾個選項,但我的首選是建立一個儲存這些值的環境檔案。如果您與團隊合作,您可以透過更隱密的措施(GPG 加密是經典)在您之間共享此文件,而無需冒將此資訊發佈到公共互聯網上的風險。如果您查看一下可能在不久前運行 Rails new 時創建的 .gitignore 文件,您會注意到專案根目錄中以 .env 開頭的任何文件都有行項目。這正是我們想要的:一個不會添加到 git 追蹤中的秘密文件,但我們可以在其中以純文字形式保存重要的絕密資訊。讓我們開始吧:

path+=/opt/homebrew/bin

我加入了 .dev 後綴,以防萬一我們最終需要不同的環境文件用於開發、生產和測試環境。在新建立的文件中,我們會添加一些值:

$ mkdir my-app
$ cd my-app

我們還需要更新 docker-compose.yml 檔案才能實際使用新的環境檔案。在網路服務下,加入以下內容:

$ touch Dockerfile.dev
$ touch docker-compose.yml
$ touch Gemfile

就是這樣!使用 docker compose up 再次啟動應用程式並導航至 localhost:3000 以確認一切正常。

以上是使用 Docker 和 MySQL 設定新的 Rails 應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn