Ich bin leitender Softwareentwickler bei einem mittelständischen Technologie- und Datenunternehmen. In der Vergangenheit habe ich viele Aufgaben übernommen: Ich habe Abläufe zur Kundenakquise erstellt, Datenbankverwaltung durchgeführt, komplexe React-Arbeiten durchgeführt, ein CMS mit vollem Funktionsumfang für den internen Gebrauch erstellt, öffentlich zugängliche Golang-API-Microservices von Grund auf erstellt und API-Authentifizierungssysteme erstellt. Ich habe an einer Vielzahl von B2B- und B2C-Produkten mitgewirkt, war technischer Leiter für mehrere Teams (gleichzeitig) und mehr. Außerdem bin ich derzeit ziemlich außer Übung, wenn es darum geht, neue Rails-Anwendungen von Grund auf zu erstellen. Also dachte ich mir, ich probiere es mal!
Dies ist ein ziemlich einfaches Tutorial, aber ich habe einen Mangel an praktischen Anleitungen dafür gefunden. Abgesehen davon möchte ich zwei Tutorials hervorheben, die ich beim Schreiben stark genutzt habe – betrachten Sie dies als eine Synthese dieser Beiträge und einiger meiner persönlichen Vorlieben: Tallan Groberg und Nícolas Iensen. Wir werden auf viele Details verzichten und stattdessen direkt einsteigen. Ich schreibe dies mit einem brandneuen M4 Macbook Pro, aber die Grundlagen sollten auf die meisten Mac- oder Linux-Umgebungen übertragen werden.
Wir werden eine einfache Ruby-Anwendung erstellen, die Rails als Hauptframework, MySQL als Datenbank (teils wegen seiner Funktionen, teils um die Komplexität dessen zu erhöhen, was ich mit diesem Beitrag anstrebe) und Docker verwendet für Virtualisierung und plattformübergreifende Kompatibilität. In diesem Tutorial bauen wir keine Modelle oder Controller: Es geht nur um die Einrichtung. Am Ende des Tutorials haben Sie eine ziemlich klassische Hello World-App. Sie sollten in der Lage sein, dieses Grundkonzept auf jede Anwendung anzuwenden, die Sie erstellen.
Das Wichtigste zuerst: Dies setzt eine gewisse Vertrautheit mit dem Terminal und Unix-basierten Computern voraus. Wenn das einigermaßen sinnvoll ist, müssen Sie Docker und Homebrew installieren (vorausgesetzt, Sie verwenden einen Mac). Wenn Sie zsh als Ihre primäre Shell ausführen (heutzutage ist dies bei den meisten Macs standardmäßig der Fall), müssen Sie möglicherweise Folgendes zu Ihrer ~/.zshrc-Datei hinzufügen, um Brew-Befehle ausführen zu können:
path+=/opt/homebrew/bin
Sobald Sie die Datei gespeichert haben, führen Sie source ~/.zshrc aus und Sie sollten gut sein!
Eine kleine Anmerkung: Befehle mit dem Präfix „$“ weisen auf Befehle hin, die in Ihrer lokalen Shell (höchstwahrscheinlich zsh oder bash) ausgeführt werden, während Befehle mit dem Präfix „#“ im Docker-Container ausgeführt werden. In allen Fällen sollte das Präfix nicht kopiert werden, es ist lediglich ein optischer Hinweis auf eine neue Zeilenaufforderung.
Viele Entwickler legen alle ihre Codierungsprojekte in einem einzigen Verzeichnis ab (meines ist ein Geschwisterverzeichnis der Verzeichnisse „Downloads“ und „Dokumente“ und ich nenne es kreativ Code). Navigieren Sie im Terminal zu Ihrem entsprechenden Verzeichnis und geben Sie die folgenden Befehle ein:
$ mkdir my-app $ cd my-app
In diesem neuen Verzeichnis benötigen wir ein paar neue Dateien. Erstellen Sie sie mit den folgenden Befehlen:
path+=/opt/homebrew/bin
Im ersten Schritt erstellt Dockerfile.dev Ihr Basis-Docker-Image und baut auf einem vorhandenen Image auf, das die Version von Ruby installiert, die wir für dieses Projekt verwenden werden (die aktuellste Version zum Zeitpunkt dieses Schreibens, 3.3.6) und die Einrichtung durchführt einige kleinere Details darüber, wie sich dieses Bild verhalten soll. Der .dev-Teil des Dateinamens gibt an, dass diese Docker-Datei nur lokal und nicht in einer Produktionsumgebung verwendet wird. Ein Befehl, den wir später im Tutorial ausführen, erstellt für uns tatsächlich eine robustere, produktionsbereite Docker-Datei, und ich möchte die beiden unterscheiden können. Angesichts des Umfangs dieses Tutorials machen uns solche Details keine Sorgen. Fügen Sie der Datei die folgenden Zeilen hinzu:
$ mkdir my-app $ cd my-app
Als nächstes kommt die Datei docker-compose.yml: Ihr Zweck besteht darin, eine Reihe von Docker-Containern zu koordinieren, um sicherzustellen, dass in der Webanwendung, die wir erstellen, alle Bestandteile miteinander kommunizieren: der Webserver, möglicherweise eine Datenbank ein Redis-Server, vielleicht ein Elasticsearch-Server usw. Alle diese verschiedenen Elemente würden in ihrem eigenen „virtuellen Computer“ leben und müssten so verkabelt werden, dass sie auf eine Art und Weise miteinander kommunizieren, die eine Produktionsumgebung nachahmt. Genug der theoretischen Dinge, das Wichtigste ist, dass wir der Datei docker-compose.yml etwas Konfigurationscode hinzufügen müssen:
$ touch Dockerfile.dev $ touch docker-compose.yml $ touch Gemfile
Machen Sie sich keine Gedanken über die Details, aber im Grunde heißt es: „Wenn Sie dies ausführen, führen Sie eine Anwendung namens „web“ aus und diese versucht, die Hauptanwendung mit einer Docker-Datei namens „Dockerfile.dev“ zu erstellen ' und ordnet den internen Port 3000 im Netzwerk des Docker-Systems dem Port 3000 des lokalen Computers zu, auf dem es ausgeführt wird. Außerdem wird eine Datenbank erstellt und es ihnen ermöglicht, miteinander zu kommunizieren. Oder so ähnlich. Wenn Sie bereits eine Anwendung auf Port 3000 ausführen, können Sie die Portnummer auf der linken Seite beliebig ändern.
Okay! Jetzt haben wir eine Datei, die ein Image erstellt, und eine andere Datei, die einen Container mit diesem Image ausführt und es in ein kleines Netzwerk einfügt, das es hochfährt. Hübsch! Aber...wie machen wir das?
Um mit der Arbeit zu beginnen, müssen wir tatsächlich in den Container gehen, den wir bauen, um ein paar Dinge zu erledigen. Wir tun das, indem wir Folgendes ausführen:
FROM ruby:3.3.6 WORKDIR /usr/src/app COPY . . RUN bundle install
Jetzt sind wir im Computer. Die Idee ist, dass wir jetzt Befehle in der Umgebung des Containers ausführen können, ohne dass bestimmte Software auf dem von uns verwendeten Computer installiert sein muss. Rails muss beispielsweise nirgendwo auf Ihrem Computer vorhanden sein, um es auf einem Docker-Container ausführen zu können, der auf Ihrem Computer ausgeführt wird. Ziemlich schick.
Okay, jetzt wo wir dabei sind, installieren wir 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
Und jetzt erstellen wir unsere Anwendung! Wir wollten diese Anwendung mit MySQL erstellen. Beachten Sie daher die Spezifikation im folgenden Befehl:
path+=/opt/homebrew/bin
Das wird eine Sekunde dauern. Sie werden gefragt, ob Sie die Gemfile überschreiben möchten. Drücken Sie zur Bestätigung y. Dieselbe Frage wird Ihnen auch für alle anderen Dateien gestellt, die mit diesem Befehl generiert werden. Verwenden Sie entsprechend die Y/N-Tasten, um die neuen Versionen zu überspringen oder zu akzeptieren.
Huzzah! Wir haben das Grundgerüst unserer Bewerbung fertig! Allerdings sind wir noch nicht wirklich fertig. Wir müssen uns mit einem wichtigen Teil befassen, um die Datenbank fertigzustellen. Und dann sollten wir uns idealerweise noch mit einem wichtigen Sicherheitsdetail befassen.
Der erste Teil dieses Abschnitts ist möglicherweise nicht unbedingt notwendig, wenn Sie nur lokal etwas tun und nicht vorhaben, etwas bereitzustellen. Darüber hinaus gibt es hier noch viel mehr zu beachten, und ich denke, es lohnt sich, ein separates Tutorial zu erstellen, um sich mit der DB-Konfiguration und der grundlegenden Repository-Sicherheit zu befassen – insbesondere, wenn Ihr Repository öffentlich ist (keine Sorge, wenn dies der Fall ist, seien Sie einfach vorsichtig da draußen!) .
Mit dem vorherigen Befehl haben wir eine große Anzahl neuer Dateien und Verzeichnisse erhalten. Eine davon ist config/database.yml. Für mich gibt es in Zeile 12 einen Block, der so aussieht:
$ mkdir my-app $ cd my-app
Technisch gesehen funktioniert das oben Gesagte. Daran ist nichts „falsch“. Aber wir können es besser machen. Das größte Problem ist, dass unsere Datenbank kein Passwort hat. Das nächste Problem ist, dass die Datenbank keinen Namen hat. Abschließend ist der Benutzername im Klartext sichtbar. Nicht mein Favorit. Lassen Sie uns das alles wie folgt ändern (das erste der folgenden ist ein neues Feld, die zweiten beiden sollten alle vorhandenen Werte ersetzen):
$ touch Dockerfile.dev $ touch docker-compose.yml $ touch Gemfile
Sie können auch den Stil ENV.fetch("VARIABLE_NAME") { "fallback_value" } verwenden. Der Unterschied zwischen ENV["VARIABLE_NAME"] und ENV.fetch("VARIABLE_NAME") besteht darin, dass ersteres Null zurückgibt, wenn keine Umgebungsvariable mit dem angegebenen Namen gefunden werden kann, während letzteres einige Warnungen oder Fehler auslösen kann (siehe hier). und hier finden Sie weitere Informationen zu ENV.fetch).
Vor diesem Hintergrund und unter der Annahme, dass Sie die Shell nicht verlassen haben (Sie können docker-compose run --service-ports web bash verwenden, um wieder hineinzukommen), müssen wir eine neue Datenbank erstellen. Machen Sie das mit dem folgenden Befehl:
FROM ruby:3.3.6 WORKDIR /usr/src/app COPY . . RUN bundle install
Beenden Sie die Docker-Shell und führen Sie in der lokalen Terminalumgebung die folgenden Befehle aus:
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
Das ist es! Wenn Sie Ihren Browser (oder einen API-Client wie Postman) auf localhost:3000 verweisen, sollte die klassische Rails-Startseite sehen:
Wir haben eine funktionierende Anwendung! Und es verfügt über eine schöne Datenbank, die für den Produktionsbetrieb bereit ist (die von Rails bereitgestellte Standarddatenbank SQLite eignet sich hervorragend zum Zusammenhacken grundlegender Ideen, ist aber nicht für die Produktionsarbeit gedacht und ihr Ersteller ist ein Spinner)! Eine robustere Datenbank bringt jedoch einige zusätzliche Verantwortlichkeiten mit sich.
Wie wir weiter oben in diesem Tutorial gesehen haben, wurden wir mit der Bereitstellung von drei wichtigen Werten beauftragt: dem Namen der Datenbank, einem Benutzernamen und einem Passwort für diesen Benutzer. Ab sofort haben wir eine Abstraktionsebene: Anstatt nur rohe String-Werte an die Datei „database.yml“ zu übergeben, holen wir diese Werte aus der Rails-Umgebung. Woher bekommt die Rails-Umgebung diese Werte? Aus der Datei docker-compose.yml!
Aber ein wichtiges Problem muss noch gelöst werden: Vorausgesetzt, wir verwenden diesen Code in der Produktion, haben wir Informationen direkt in den Code selbst eingefügt, auf die niemand außer den Systemadministratoren Zugriff haben sollte. Das ist nicht toll. Wir sollten eine zusätzliche Abstraktionsebene haben, die alle direkten Verweise auf bestimmte wertvolle, theoretisch umfassende Informationen entfernt.
Jetzt müssen wir tatsächlich GET diese Umgebungsvariablen in unserer Ruby-Umgebung richtig einrichten, wenn sie zum ersten Mal gestartet wird. Wir werden dies in zwei Schritten tun, Sie können es aber auch gerne in einem Schritt tun, wenn Sie möchten. Zuerst müssen wir aufhören, direkt auf die DB-Geheimnisse im Rails-Projekt zu verweisen. Das machen wir. Als nächstes müssen wir sie von Docker in Rails umleiten. Abschließend werden wir es noch weiter abstrahieren, indem wir die geheimen Werte aus einer Datei hinzufügen, die wir vor Git verstecken, um diese Informationen besser vor potenziellen Taugenichtsen zu verbergen.
Wir haben ein paar Optionen, aber mein Ziel ist es, eine Umgebungsdatei zu erstellen, in der diese Werte gespeichert werden. Wenn Sie mit einem Team zusammenarbeiten, können Sie diese Datei mithilfe heimlicher Maßnahmen (die GPG-Verschlüsselung ist ein Klassiker) untereinander austauschen, ohne das Risiko einzugehen, diese Informationen ins öffentliche Internet zu stellen. Wenn Sie sich die .gitignore-Datei ansehen, die wahrscheinlich erstellt wurde, als Sie vor einiger Zeit „Rails New“ ausgeführt haben, werden Sie feststellen, dass es für alle Dateien im Stammverzeichnis des Projekts, die mit „.env“ beginnen, eine Zeile gibt. Genau das wollen wir: eine geheime Datei, die nicht zum Git-Tracking hinzugefügt wird, in der wir aber wichtige, streng geheime Informationen im Klartext speichern können. Lass es uns tun:
path+=/opt/homebrew/bin
Ich habe das Suffix .dev hinzugefügt, nur für den Fall, dass wir am Ende unterschiedliche Umgebungsdateien für Entwicklungs-, Produktions- und Testumgebungen benötigen. Fügen wir in dieser neu erstellten Datei einige Werte hinzu:
$ mkdir my-app $ cd my-app
Wir müssen auch die Datei docker-compose.yml aktualisieren, um die neue Umgebungsdatei tatsächlich verwenden zu können. Fügen Sie unter dem Webdienst Folgendes hinzu:
$ touch Dockerfile.dev $ touch docker-compose.yml $ touch Gemfile
Und das ist es! Starten Sie die Anwendung erneut mit Docker Compose und navigieren Sie zu localhost:3000, um zu bestätigen, dass alles in Ordnung ist.
Das obige ist der detaillierte Inhalt vonEinrichten einer neuen Rails-Anwendung mit Docker & MySQL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!