I have a NestJS application deployed in Google Cloud Run and I was able to connect to the Cloud SQL database but I'm having trouble running the TypeORM migrations. Instead of using ormconfig.json, I created a database.config.ts file that exports a TypeORM connection object so that it can be loaded asynchronously with:
import { config } from './config/database.config';
...
imports: [
TypeOrmModule.forRootAsync({
useFactory: () => config,
}),
]
My database.config.ts file contains the following:
import { ConnectionOptions } from 'typeorm';
import 'reflect-metadata';
export const prod = process.env.NODE_ENV === 'production';
export const config: ConnectionOptions = {
name: 'default',
type: 'mysql' as any,
driver: 'mysql',
database: 'test_db',
synchronize: true,
logging: true,
entities: ['dist/**/*.entity{.ts,.js}'],
cli: {
migrationsDir: 'migrations',
},
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
// Production Mode
...(prod && {
extra: {
socketPath: '/cloudsql/{PROJECT_ID}:us-central1:{DB_NAME}',
},
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
synchronize: false,
logging: true,
migrationsRun: false,
migrations: ['dist/migrations/*{.js}'],
cli: { migrationsDir: 'src/migrations' },
}),
};
export default config;
The Dockerfile used to initialize the Cloud Run instance has the following:
# use node 12 image
FROM node:12 as base
# set our working directory
WORKDIR /app
FROM base as development
# copy over dependecy manifests to install
COPY package*.json ./
# install production dependencies and copy them to a temp folder, we will use this for the final build step
RUN npm install --production
RUN cp -R node_modules /tmp/node_modules
# Install all dependcies
RUN npm install
# Copy source code
COPY . ./
# lint, unit test, e2e test and build our app
FROM development as builder
RUN npm run lint
RUN npm run test:cov
RUN npm run test:e2e
RUN npm run build
# release includes bare miniumum to run the app
FROM base as release
COPY --from=builder /tmp/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
# Run the web service on container boot
CMD ["npm", "run", "start:prod"]
And finally, my package.json uses the following script to start the application:
"scripts": {
...
"prod:migration": "npm i -g typeorm && npm run typeorm:migration",
"start:prod": "npm run prod:migration && node dist/src/main",
"typeorm:migration": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run",
"typeorm:revert": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:revert"
...
},
When deploying, I'd get errors saying typeorm/ts-node weren't found. Some minor tweaking would allow the app to deploy successfully but without any migrations run successfully. I was wondering if I was on the right path or if there were any changes I could make in order to have the migrations run successfully on the application startup.