1. Übersicht
Cloud Run ist eine vollständig verwaltete Plattform, mit der Sie Ihren Code direkt auf der skalierbaren Infrastruktur von Google ausführen können. In diesem Codelab wird gezeigt, wie Sie eine Next.js-Anwendung in Cloud Run mithilfe des Node.js Admin SDK mit einer Firestore-Datenbank verbinden.
Aufgaben in diesem Lab:
- Firestore-Datenbank erstellen
- Anwendung in Cloud Run bereitstellen, die eine Verbindung zu Ihrer Firestore-Datenbank herstellt
2. Vorbereitung
- Wenn Sie noch kein Google-Konto haben, müssen Sie ein Google-Konto erstellen.
- Sie verwenden ein privates Konto anstelle eines Arbeits- oder Schulkontos. Für geschäftliche und schulische Konten gelten möglicherweise Einschränkungen, die Sie daran hindern, die für dieses Lab erforderlichen APIs zu aktivieren.
3. Projekt einrichten
- Melden Sie sich in der Google Cloud Console an.
- Aktivieren Sie die Abrechnung in der Cloud Console.
- Die Kosten für die Durchführung dieses Labs sollten unter 1 $liegen.
- Sie können die Schritte am Ende dieses Labs ausführen, um Ressourcen zu löschen und weitere Kosten zu vermeiden.
- Neue Nutzer können das kostenlose Testabo mit einem Guthaben von 300$ nutzen.
- Erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes.
4. Cloud Shell-Editor öffnen
- Rufen Sie den Cloud Shell-Editor auf.
- Wenn das Terminal nicht unten auf dem Bildschirm angezeigt wird, öffnen Sie es:
- Klicke auf das Dreistrich-Menü
.
- Klicken Sie auf Terminal.
- Klicken Sie auf Neues Terminal
.
- Klicke auf das Dreistrich-Menü
- Legen Sie das Projekt im Terminal mit diesem Befehl fest:
- Format:
gcloud config set project [PROJECT_ID]
- Beispiel:
gcloud config set project lab-project-id-example
- Wenn Sie sich Ihre Projekt-ID nicht merken können:
- So listen Sie alle Ihre Projekt-IDs auf:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- So listen Sie alle Ihre Projekt-IDs auf:
- Format:
- Wenn Sie dazu aufgefordert werden, klicken Sie auf Autorisieren, um fortzufahren.
- Es sollte folgende Meldung angezeigt werden:
Wenn du die MeldungUpdated property [core/project].
WARNING
und die FrageDo you want to continue (Y/N)?
siehst, hast du wahrscheinlich die Projekt-ID falsch eingegeben. Drücken SieN
,Enter
und versuchen Sie noch einmal, den Befehlgcloud config set project
auszuführen.
5. APIs aktivieren
Aktivieren Sie im Terminal die APIs:
gcloud services enable \
firestore.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
Wenn Sie dazu aufgefordert werden, klicken Sie auf Autorisieren, um fortzufahren.
Die Verarbeitung dieses Befehls kann einige Minuten dauern. Sie sollten aber schließlich eine Meldung ähnlich der folgenden erhalten:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
6. Firestore-Datenbank erstellen
- Befehl
gcloud firestore databases create
ausführen, um eine Firestore-Datenbank zu erstellengcloud firestore databases create --location=nam5
7. Anwendung vorbereiten
Bereiten Sie eine Next.js-Anwendung vor, die auf HTTP-Anfragen reagiert.
- Verwenden Sie den folgenden Befehl, um ein neues Next.js-Projekt mit dem Namen
task-app
zu erstellen:npx --yes create-next-app@15.2.4 task-app \ --ts \ --eslint \ --tailwind \ --no-src-dir \ --turbopack \ --app \ --no-import-alias
- Ändern Sie das Verzeichnis in
task-app
:cd task-app
- Installieren Sie
firebase-admin
, um mit der Firestore-Datenbank zu interagieren.npm install firebase-admin
- Öffnen Sie die Datei
actions.ts
im Cloud Shell-Editor: Oben auf dem Bildschirm sollte jetzt eine leere Datei angezeigt werden. Hier können Sie die Dateicloudshell edit app/actions.ts
actions.ts
bearbeiten. - Kopieren Sie den folgenden Code und fügen Sie ihn in die geöffnete
actions.ts
-Datei ein:'use server' import { initializeApp, applicationDefault, getApps } from 'firebase-admin/app'; import { getFirestore } from 'firebase-admin/firestore'; const credential = applicationDefault(); // Only initialize app if it does not already exist if (getApps().length === 0) { initializeApp({ credential }); } const db = getFirestore(); const tasksRef = db.collection('tasks'); type Task = { id: string; title: string; status: 'IN_PROGRESS' | 'COMPLETE'; createdAt: number; }; // CREATE export async function addNewTaskToDatabase(newTask: string) { await tasksRef.doc().create({ title: newTask, status: 'IN_PROGRESS', createdAt: Date.now(), }); return; } // READ export async function getTasksFromDatabase() { const snapshot = await tasksRef.orderBy('createdAt', 'desc').limit(100).get(); const tasks = await snapshot.docs.map(doc => ({ id: doc.id, title: doc.data().title, status: doc.data().status, createdAt: doc.data().createdAt, })); return tasks; } // UPDATE export async function updateTaskInDatabase(task: Task) { await tasksRef.doc(task.id).set(task); return; } // DELETE export async function deleteTaskFromDatabase(taskId: string) { await tasksRef.doc(taskId).delete(); return; }
- Öffnen Sie die Datei
page.tsx
im Cloud Shell-Editor: Oben auf dem Bildschirm sollte jetzt eine vorhandene Datei angezeigt werden. Hier können Sie die Dateicloudshell edit app/page.tsx
page.tsx
bearbeiten. - Löschen Sie den vorhandenen Inhalt der Datei
page.tsx
. - Kopieren Sie den folgenden Code und fügen Sie ihn in die geöffnete
page.tsx
-Datei ein:'use client' import React, { useEffect, useState } from "react"; import { addNewTaskToDatabase, getTasksFromDatabase, deleteTaskFromDatabase, updateTaskInDatabase } from "./actions"; type Task = { id: string; title: string; status: 'IN_PROGRESS' | 'COMPLETE'; createdAt: number; }; export default function Home() { const [newTaskTitle, setNewTaskTitle] = useState(''); const [tasks, setTasks] = useState<Task[]>([]); async function getTasks() { const updatedListOfTasks = await getTasksFromDatabase(); setTasks(updatedListOfTasks); } useEffect(() => { getTasks(); }, []); async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); await addNewTaskToDatabase(newTaskTitle); await getTasks(); setNewTaskTitle(''); }; async function updateTask(task: Task, newTaskValues: Partial<Task>) { await updateTaskInDatabase({ ...task, ...newTaskValues }); await getTasks(); } async function deleteTask(taskId: string) { await deleteTaskFromDatabase(taskId); await getTasks(); } return ( <main className="p-4"> <h2 className="text-2xl font-bold mb-4">To Do List</h2> <div className="flex mb-4"> <form onSubmit={handleSubmit} className="flex mb-8"> <input type="text" placeholder="New Task Title" value={newTaskTitle} onChange={(e) => setNewTaskTitle(e.target.value)} className="flex-grow border border-gray-400 rounded px-3 py-2 mr-2 bg-inherit" /> <button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-nowrap" > Add New Task </button> </form> </div> <table className="w-full"> <tbody> {tasks.map(function (task) { const isComplete = task.status === 'COMPLETE'; return ( <tr key={task.id} className="border-b border-gray-200"> <td className="py-2 px-4"> <input type="checkbox" checked={isComplete} onChange={() => updateTask(task, { status: isComplete ? 'IN_PROGRESS' : 'COMPLETE' })} className="transition-transform duration-300 ease-in-out transform scale-100 checked:scale-125 checked:bg-green-500" /> </td> <td className="py-2 px-4"> <span className={`transition-all duration-300 ease-in-out ${isComplete ? 'line-through text-gray-400 opacity-50' : 'opacity-100'}`} > {task.title} </span> </td> <td className="py-2 px-4"> <button onClick={() => deleteTask(task.id)} className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded float-right" > Delete </button> </td> </tr> ); })} </tbody> </table> </main> ); }
Die Anwendung kann jetzt bereitgestellt werden.
8. Anwendung in Cloud Run bereitstellen
- Führen Sie den folgenden Befehl aus, um die Anwendung in Cloud Run bereitzustellen:
gcloud run deploy helloworld \ --region=us-central1 \ --source=.
- Wenn Sie dazu aufgefordert werden, drücken Sie
Y
undEnter
, um zu bestätigen, dass Sie fortfahren möchten:Do you want to continue (Y/n)? Y
Nach einigen Minuten sollte die Anwendung eine URL anzeigen, die Sie aufrufen können.
Rufen Sie die URL auf, um Ihre Anwendung in Aktion zu sehen. Jedes Mal, wenn Sie die URL aufrufen oder die Seite aktualisieren, wird die Aufgaben-App angezeigt.
9. Glückwunsch
In diesem Lab haben Sie Folgendes gelernt:
- Cloud SQL for PostgreSQL-Instanz erstellen
- Anwendung in Cloud Run bereitstellen, die eine Verbindung zu Ihrer Cloud SQL-Datenbank herstellt
Bereinigen
Cloud SQL ist nicht kostenlos. Wenn Sie die Plattform weiter nutzen, werden Ihnen Kosten in Rechnung gestellt. Sie können Ihr Cloud-Projekt löschen, um zusätzliche Kosten zu vermeiden.
Für Cloud Run fallen keine Kosten an, wenn der Dienst nicht verwendet wird. Allerdings können für das Speichern des Container-Images in Artifact Registry Gebühren berechnet werden. Wenn Sie Ihr Cloud-Projekt löschen, wird die Abrechnung für alle in diesem Projekt verwendeten Ressourcen beendet.
Sie können das Projekt löschen:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Sie können auch unnötige Ressourcen von Ihrem CloudShell-Laufwerk löschen. Sie haben folgende Möglichkeiten:
- Löschen Sie das Codelab-Projektverzeichnis:
rm -rf ~/task-app
- Warnung! Diese nächste Aktion kann nicht rückgängig gemacht werden. Wenn Sie alles in Cloud Shell löschen möchten, um Speicherplatz freizugeben, können Sie Ihr ganzes Basisverzeichnis löschen. Achten Sie darauf, dass alles, was Sie behalten möchten, an einem anderen Ort gespeichert ist.
sudo rm -rf $HOME
Weiter lernen
- Full-Stack-Next.js-Anwendung mit Cloud SQL for PostgreSQL und dem Cloud SQL Node.js-Connector in Cloud Run bereitstellen
- Full-Stack-Angular-Anwendung mit Cloud SQL for PostgreSQL und dem Cloud SQL Node.js-Connector in Cloud Run bereitstellen
- Full-Stack-Angular-Anwendung mit dem Node.js Admin SDK in Cloud Run mit Firestore bereitstellen
- Full-Stack-Next.js-Anwendung mit dem Node.js Admin SDK in Cloud Run mit Firestore bereitstellen