DEV Community

Cover image for Serverless e-commerce: Vendure on Google Cloud Run
Martijn
Martijn

Posted on • Originally published at vendure.io

Serverless e-commerce: Vendure on Google Cloud Run

Google’s Cloud Run is a scalable, containerized, fully managed serverless platform. It’s cheap and handles infrastructure and scaling for us. Sounds perfect to run a headless Vendure instance on, right?

Here is what we need to do. Don’t worry, for most of these you can use a plugin:

  • Create a database
  • Use Cloud Storage for assets
  • Use Cloud Tasks to process worker jobs
  • Dockerize Vendure
  • Build image and deploy to Google Cloud Run

We assume you already have:

Create a database for Vendure

Vendure requires a database to store its products, orders, customers etc. In this tutorial, we will use Google’s Cloud SQL: a managed database platform.

  1. Enable Cloud SQL in your dashboard and create a database.
  2. For this example, 1vcpu and 10 GB SSD is sufficient. PostgreSQL or MySQL is up to you. Make sure to write down the password you entered.
  3. Create a database named vendure
  4. Click on your instance, and go to connection > add network. Create a new network with IP range 0.0.0.0/0. Careful with production environments, this will make your SQL instance publicly available!

Configure Vendure to use the new database:

// vendure-config.ts
dbConnectionOptions: {
    type: 'mysql',
    synchronize: true, // Disable this after first startup
    logging: false,
    username: 'root', // Don't use this in production
    password: 'your-password',
    host: '192.56.298.3', // The public IP of your SQL instance
    database: 'vendure',
},
Enter fullscreen mode Exit fullscreen mode

Setup Cloud Storage

Cloud run instances are stateless, which also means you shouldn’t use its local file system. Instead, we will use Google Cloud Storage.

Create a storage bucket and make it publicly accessible,
so that the images can be used in a storefront. You can use this plugin
to connect Vendure to the bucket.

// vendure-config.ts
AssetServerPlugin.init({
    storageStrategyFactory: () => new GoogleStorageStrategy({bucketName: 'your-bucket-name'}),
    route: 'assets',
    assetUploadDir: '/tmp/vendure/assets',
})
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can implement the AssetStorageStrategy yourself.

Setup Cloud Tasks

Cloud run allows no processing outside request context. As soon as your server returned a response,
there is no guarantee that any leftover processes will be finished. Because of this, we need some way to wrap the Vendure worker Jobs in a request.
We can do that with this plugin.

This plugin puts jobs in a queue and Cloud Tasks posts the messages back to a publicly available endpoint in your Vendure application.

// vendure-config.ts
CloudTasksPlugin.init({
  taskHandlerHost: 'https://your-instance-sds34vbs-ew.a.run.app', // This endpoint needs to be accesible by Google Cloud Tasks
  projectId: 'your-projectId',
  location: 'europe-west1',
  authSecret: 'some-secret',
})
Enter fullscreen mode Exit fullscreen mode

For simplicity, we will start the worker in the same instance as the application:

// index.ts
bootstrap(config)
    .then(app => app.get(JobQueueService).start())
    .catch(err => {
        console.log(err);
        process.exit(1);
    });
Enter fullscreen mode Exit fullscreen mode

This is not recommended for production! Read more about the worker here.

Alternatively, you could implement the JobQueueStrategy yourself.

Dockerize Vendure

Cloud Run requires Vendure to be Dockerized. We can simply create a Dockerfile in the root of the project:

FROM node:16
WORKDIR /usr/src/app
COPY . .
RUN yarn install --production
RUN yarn build
CMD [ "node", "dist/index.js" ]
Enter fullscreen mode Exit fullscreen mode

Deploy

First we need to build an image and push it to Google's container registry:

  1. Install docker
  2. Execute these commands in the root of your project:
docker build -t eu.gcr.io/your-projectId/vendure .
# Configure docker to use Google authentication
gcloud auth configure-docker -q
docker push eu.gcr.io/your-projectId/vendure
Enter fullscreen mode Exit fullscreen mode

Now all that's left is deploying the image to Google Cloud Run:

# This sets all your secrets from a .env file in a variable, so we can pass it to Cloud Run
export ENV_VARS=$(paste -sd, .env)
gcloud run deploy shops-test \
            --quiet \
            --image "eu.gcr.io/your-projectId/vendure:latest" \
            --region "europe-west1" \
            --platform "managed" \
            --allow-unauthenticated \
            --memory=1G \
            --project=your-projectId \
            --set-env-vars=$ENV_VARS 
Enter fullscreen mode Exit fullscreen mode

Go to https://console.cloud.google.com/run to view your public URL. It should look something like https://your-instance-sds34vbs-ew.a.run.app.
Make sure to also set this URL as taskHandlerHost in the Cloud Tasks plugin if you haven't already.

  1. Go to https://your-instance-sds34vbs-ew.a.run.app/admin and login with your super admin user
  2. Go to products and create a new product
  3. Add an image to the product
  4. Save the product and go back to the overview
  5. Your product should appear in the product overview in the admin
  6. Congratulations, this means everything works as expected!

Make sure you set synchronize: false after the database has been populated!

Some optional improvements:

  1. Set up a separate worker instance
  2. Restrict access to your database to specific IP's.
  3. Use Unix sockets for database access

Thats it!

Discussion (0)