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:
- A Vendure project set up locally. If not, checkout these steps
-
gcloud
cli installed and authorized
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.
- Enable Cloud SQL in your dashboard and create a database.
- 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.
- Create a database named
vendure
- 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',
},
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',
})
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',
})
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);
});
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" ]
Deploy
First we need to build an image and push it to Google's container registry:
- Install docker
- 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
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
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.
- Go to
https://your-instance-sds34vbs-ew.a.run.app/admin
and login with your super admin user - Go to products and create a new product
- Add an image to the product
- Save the product and go back to the overview
- Your product should appear in the product overview in the admin
- Congratulations, this means everything works as expected!
Make sure you set synchronize: false
after the database has been populated!
Some optional improvements:
- Set up a separate worker instance
- Restrict access to your database to specific IP's.
- Use Unix sockets for database access
Thats it!
Top comments (0)