Informationen zu diesem Codelab
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 mit dem Cloud SQL Node.js-Connector eine Next.js-Anwendung in Cloud Run mit einer Cloud SQL for PostgreSQL-Datenbank verbinden.
Aufgaben in diesem Lab:
- Cloud SQL for PostgreSQL-Instanz erstellen
- Anwendung in Cloud Run bereitstellen, die eine Verbindung zu Ihrer Cloud SQL-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 \
sqladmin.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. Dienstkonto einrichten
Erstellen und konfigurieren Sie ein Google Cloud-Dienstkonto, das von Cloud Run verwendet werden soll, damit es die richtigen Berechtigungen zum Herstellen einer Verbindung zu Cloud SQL hat.
- Führen Sie den Befehl
gcloud iam service-accounts create
so aus, um ein neues Dienstkonto zu erstellen:gcloud iam service-accounts create quickstart-service-account \
--display-name="Quickstart Service Account" - Führen Sie den Befehl „gcloud projects add-iam-policy-binding“ wie unten beschrieben aus, um dem Google Cloud-Dienstkonto, das Sie gerade erstellt haben, die Rolle Cloud SQL-Client hinzuzufügen.
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/cloudsql.client" - Führen Sie den Befehl „gcloud projects add-iam-policy-binding“ wie unten beschrieben aus, um dem Google Cloud-Dienstkonto, das Sie gerade erstellt haben, die Rolle Cloud SQL-Instanznutzer hinzuzufügen.
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/cloudsql.instanceUser" - Führen Sie den Befehl „gcloud projects add-iam-policy-binding“ wie unten beschrieben aus, um dem gerade erstellten Google Cloud-Dienstkonto die Rolle Logautor hinzuzufügen.
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/logging.logWriter"
7. Cloud SQL-Datenbank erstellen
- Befehl
gcloud sql instances create
ausführen, um eine Cloud SQL-Instanz zu erstellengcloud sql instances create quickstart-instance \
--database-version=POSTGRES_14 \
--cpu=4 \
--memory=16GB \
--region=us-central1 \
--database-flags=cloudsql.iam_authentication=on
Die Verarbeitung dieses Befehls kann einige Minuten dauern.
- Führen Sie den Befehl
gcloud sql databases create
aus, um eine Cloud SQL-Datenbank in derquickstart-instance
zu erstellen.gcloud sql databases create quickstart_db \
--instance=quickstart-instance - Erstellen Sie einen PostgreSQL-Datenbanknutzer für das zuvor erstellte Dienstkonto, um auf die Datenbank zuzugreifen.
gcloud sql users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
--instance=quickstart-instance \
--type=cloud_iam_service_account
8. 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
pg
und die Cloud SQL Node.js-Connector-Bibliothek, um mit der PostgreSQL-Datenbank zu interagieren.npm install pg @google-cloud/cloud-sql-connector google-auth-library
- Installieren Sie
@types/pg
als Entwicklungsabhängigkeit, um eine TypeScript Next.js-Anwendung zu verwenden.npm install --save-dev @types/pg
- Ö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 pg from 'pg';
import { AuthTypes, Connector } from '@google-cloud/cloud-sql-connector';
import { GoogleAuth } from 'google-auth-library';
const auth = new GoogleAuth();
const { Pool } = pg;
type Task = {
id: string;
title: string;
status: 'IN_PROGRESS' | 'COMPLETE';
};
const projectId = await auth.getProjectId();
const connector = new Connector();
const clientOpts = await connector.getOptions({
instanceConnectionName: `${projectId}:us-central1:quickstart-instance`,
authType: AuthTypes.IAM,
});
const pool = new Pool({
...clientOpts,
user: `quickstart-service-account@${projectId}.iam`,
database: 'quickstart_db',
});
const tableCreationIfDoesNotExist = async () => {
await pool.query(`CREATE TABLE IF NOT EXISTS tasks (
id SERIAL NOT NULL,
created_at timestamp NOT NULL,
status VARCHAR(255) NOT NULL default 'IN_PROGRESS',
title VARCHAR(1024) NOT NULL,
PRIMARY KEY (id)
);`);
}
// CREATE
export async function addNewTaskToDatabase(newTask: string) {
await tableCreationIfDoesNotExist();
await pool.query(`INSERT INTO tasks(created_at, status, title) VALUES(NOW(), 'IN_PROGRESS', $1)`, [newTask]);
return;
}
// READ
export async function getTasksFromDatabase() {
await tableCreationIfDoesNotExist();
const { rows } = await pool.query(`SELECT id, created_at, status, title FROM tasks ORDER BY created_at DESC LIMIT 100`);
return rows;
}
// UPDATE
export async function updateTaskInDatabase(task: Task) {
await tableCreationIfDoesNotExist();
await pool.query(
`UPDATE tasks SET status = $1, title = $2 WHERE id = $3`,
[task.status, task.title, task.id]
);
return;
}
// DELETE
export async function deleteTaskFromDatabase(taskId: string) {
await tableCreationIfDoesNotExist();
await pool.query(`DELETE FROM tasks WHERE id = $1`, [taskId]);
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.
9. Anwendung in Cloud Run bereitstellen
- Führen Sie den folgenden Befehl aus, um die Anwendung in Cloud Run bereitzustellen:
gcloud run deploy to-do-tracker \
--region=us-central1 \
--source=. \
--service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--allow-unauthenticated - 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.
10. 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