Deploy Next.js Supabase App to Cloud Run using Artifact Registry and Secrets Manager

Table of Contents Introduction Step 1: Set Up Your Google Cloud Project Create a Google Cloud Project Install Google Cloud SDK Enable the following APIs Step 2: Store Secrets in Google Secret Manager Use the gcloud CLI to create secrets Grant the Cloud Run service account access to the secrets Step 3: Set Up Artifact Registry Create a Docker repository Artifact Registry Repository Authenticate Docker to Artifact Registry Step 4: Dockerize Your Next.js App Create a Dockerfile in the root of your Next.js project Test the Docker Image Locally Step 5: Push Docker Image to Artifact Registry Build the Docker Image Push the Docker Image Step 6: Deploy to Cloud Run Caution Verify Docker Authentication Next Step Introduction Artifact Registry is a service on Google Cloud for storing and managing container images and other artifacts. While there is a similar service called Container Registry, it is deprecated as of June 26, 2024, and will be shut down on March 18, 2025. Therefore, it is recommended to use Artifact Registry. Step 1: Set Up Your Google Cloud Project Create a Google Cloud Project Go to the Google Cloud Console. Click on the project dropdown and select New Project. Give your project a name and click Create. Install Google Cloud SDK Install the Google Cloud SDK on your local machine. Authenticate and set your project gcloud auth login gcloud config set project YOUR_PROJECT_ID Enable the following APIs Cloud Run API Secret Manager API Artifact Registry API gcloud services enable run.googleapis.com secretmanager.googleapis.com artifactregistry.googleapis.com Step 2: Store Secrets in Google Secret Manager Use the gcloud CLI to create secrets for each environment variable echo -n "your-supabase-url" | gcloud secrets create NEXT_PUBLIC_SUPABASE_URL --data-file=- echo -n "your-anon-key" | gcloud secrets create NEXT_PUBLIC_SUPABASE_ANON_KEY --data-file=- echo -n "your-service-role-key" | gcloud secrets create SUPABASE_SERVICE_ROLE_KEY --data-file=- Grant the Cloud Run service account access to the secrets gcloud secrets add-iam-policy-binding NEXT_PUBLIC_SUPABASE_URL \ --member=serviceAccount:YOUR_PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role=roles/secretmanager.secretAccessor Repeat for all secrets, replacing NEXT_PUBLIC_SUPABASE_URL with the respective secret name. Step 3: Set Up Artifact Registry Create a Docker repository Artifact Registry Repository gcloud artifacts repositories create YOUR_PROJECT_REPOSITORY_NAME \ --repository-format=docker \ --location=YOUR_REGION \ // e.g. us-central1 --description="Docker repository for Next.js app" Authenticate Docker to Artifact Registry gcloud auth configure-docker YOUR_REGION-docker.pkg.dev Step 4: Dockerize Your Next.js App Create a Dockerfile in the root of your Next.js project # Use the official Node.js image FROM node:18-alpine AS builder # Set the working directory WORKDIR /app # Copy package.json and package-lock.json COPY package*.json ./ # Install dependencies RUN npm install # Copy the rest of the application code COPY . . # Build the application RUN npm run build # Use a smaller image for the final stage FROM node:18-alpine # Set the working directory WORKDIR /app # Copy built files from the builder stage COPY --from=builder /app/.next ./.next COPY --from=builder /app/public ./public COPY --from=builder /app/package*.json ./ COPY --from=builder /app/node_modules ./node_modules # Expose the port EXPOSE 3000 # Start the app CMD ["npm", "start"] Test the Docker Image Locally Build and run the Docker image docker build -t YOUR_PROJECT_NAME . docker run -p 3000:3000 YOUR_PROJECT_NAME Verify the app runs correctly at http://localhost:3000. Step 5: Push Docker Image to Artifact Registry Build the Docker Image docker build -t YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest . // If you are using M1 Mac docker build --platform linux/amd64 -t YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest . Push the Docker Image docker push YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest Step 6: Deploy to Cloud Run gcloud run deployYOUR_PROJECT_IMAGE_NAME \ --image YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest \ --platform managed \ --region YOUR_REGION \ --allow-unauthenticated \ --update-secrets=\ NEXT_PUBLIC_SUPABASE_URL=NEXT_PUBLIC_SUPABASE_URL:latest, NEXT_PUBLIC_SUPABASE_ANON_KEY=NEXT_PUBLIC_SUPABASE_ANON_KEY:latest, SUPABASE_SERVICE_ROLE_KEY=SUPABASE_SERVICE_ROLE_KEY:latest, Caution Since you're encountering the P

Feb 9, 2025 - 07:37
 0
Deploy Next.js Supabase App to Cloud Run using Artifact Registry and Secrets Manager

Table of Contents

  1. Introduction
  2. Step 1: Set Up Your Google Cloud Project
    • Create a Google Cloud Project
    • Install Google Cloud SDK
    • Enable the following APIs
  3. Step 2: Store Secrets in Google Secret Manager
    • Use the gcloud CLI to create secrets
    • Grant the Cloud Run service account access to the secrets
  4. Step 3: Set Up Artifact Registry
    • Create a Docker repository Artifact Registry Repository
    • Authenticate Docker to Artifact Registry
  5. Step 4: Dockerize Your Next.js App
    • Create a Dockerfile in the root of your Next.js project
    • Test the Docker Image Locally
  6. Step 5: Push Docker Image to Artifact Registry

    • Build the Docker Image
    • Push the Docker Image
  7. Step 6: Deploy to Cloud Run

  8. Caution

    • Verify Docker Authentication
  9. Next Step

Introduction

Artifact Registry is a service on Google Cloud for storing and managing container images and other artifacts. While there is a similar service called Container Registry, it is deprecated as of June 26, 2024, and will be shut down on March 18, 2025. Therefore, it is recommended to use Artifact Registry.

Step 1: Set Up Your Google Cloud Project

  1. Create a Google Cloud Project

    • Go to the Google Cloud Console.
    • Click on the project dropdown and select New Project.
    • Give your project a name and click Create.
  2. Install Google Cloud SDK

    • Install the Google Cloud SDK on your local machine.
    • Authenticate and set your project
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
  1. Enable the following APIs
    • Cloud Run API
    • Secret Manager API
    • Artifact Registry API
gcloud services enable run.googleapis.com secretmanager.googleapis.com artifactregistry.googleapis.com

Step 2: Store Secrets in Google Secret Manager

  1. Use the gcloud CLI to create secrets for each environment variable
echo -n "your-supabase-url" | gcloud secrets create NEXT_PUBLIC_SUPABASE_URL --data-file=-
echo -n "your-anon-key" | gcloud secrets create NEXT_PUBLIC_SUPABASE_ANON_KEY --data-file=-
echo -n "your-service-role-key" | gcloud secrets create SUPABASE_SERVICE_ROLE_KEY --data-file=-
  1. Grant the Cloud Run service account access to the secrets
gcloud secrets add-iam-policy-binding NEXT_PUBLIC_SUPABASE_URL \
    --member=serviceAccount:YOUR_PROJECT_NUMBER-compute@developer.gserviceaccount.com \
    --role=roles/secretmanager.secretAccessor

Repeat for all secrets, replacing NEXT_PUBLIC_SUPABASE_URL with the respective secret name.

Step 3: Set Up Artifact Registry

  1. Create a Docker repository Artifact Registry Repository
gcloud artifacts repositories create YOUR_PROJECT_REPOSITORY_NAME \
    --repository-format=docker \
    --location=YOUR_REGION \      // e.g. us-central1
    --description="Docker repository for Next.js app"
  1. Authenticate Docker to Artifact Registry
gcloud auth configure-docker YOUR_REGION-docker.pkg.dev

Step 4: Dockerize Your Next.js App

  1. Create a Dockerfile in the root of your Next.js project
# Use the official Node.js image
FROM node:18-alpine AS builder

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Use a smaller image for the final stage
FROM node:18-alpine

# Set the working directory
WORKDIR /app

# Copy built files from the builder stage
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules

# Expose the port
EXPOSE 3000

# Start the app
CMD ["npm", "start"]
  1. Test the Docker Image Locally
    • Build and run the Docker image
 docker build -t YOUR_PROJECT_NAME .
 docker run -p 3000:3000 YOUR_PROJECT_NAME
  • Verify the app runs correctly at http://localhost:3000.

Step 5: Push Docker Image to Artifact Registry

  1. Build the Docker Image
docker build -t YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest .

// If you are using M1 Mac
docker build --platform linux/amd64 -t YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest .
  1. Push the Docker Image
docker push YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest

Step 6: Deploy to Cloud Run

gcloud run deployYOUR_PROJECT_IMAGE_NAME \
  --image YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_PROJECT_REPOSITORY_NAME/YOUR_PROJECT_IMAGE_NAME:latest \
  --platform managed \
  --region YOUR_REGION \
  --allow-unauthenticated \
  --update-secrets=\
NEXT_PUBLIC_SUPABASE_URL=NEXT_PUBLIC_SUPABASE_URL:latest,
NEXT_PUBLIC_SUPABASE_ANON_KEY=NEXT_PUBLIC_SUPABASE_ANON_KEY:latest,
SUPABASE_SERVICE_ROLE_KEY=SUPABASE_SERVICE_ROLE_KEY:latest,

Caution

Since you're encountering the Permission "artifactregistry.repositories.uploadArtifacts" deniederror despite having the correct IAM roles and repository setup, make sure Verify Docker Authentication to run this code:

cat ~/.docker/config.json

The output should include:

{
  "credHelpers": {
    "[YOUR_REGION]-docker.pkg.dev": "gcloud"
  }
}

Next Step

This article summarizes the process of setting up a Google Cloud Project, storing secrets in Google Secret Manager, configuring Artifact Registry, and deploying a Dockerized Next.js application.
If you want to do this deployment process automatically, consider CI/CD pipelines using tools like Cloud Build or GitHub Actions.