Introduction
When operating software in production, you need to run some on-off scripts or migrations to consult or perform some manual tasks until they are automated somehow.
To make this possible and safe we made some improvements in our codebase.
.env.stg
When we need to run a script in staging, we have a special environment variable ENV_FILE, that let us customize what .env file to load:
ENV_FILE='.env.stg' yarn w path/to/script.ts
yarn w
is how we run our scripts, it uses webpack to bundle the script and run it using node.
Here is the implementation of ENV_FILE
import dotenvSafe from 'dotenv-safe';
import path from 'path';
import pkg from '../package.json';
const cwd = process.cwd();
const root = path.join.bind(cwd);
const getEnvFile = () => {
if (process.env.ENV_FILE !== undefined) {
return process.env.ENV_FILE;
}
return '.env';
};
const envFile = getEnvFile();
dotenvSafe.config({
path: root(envFile),
sample: root('.env.example'),
});
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line
console.log('.env: ', path.join(cwd, envFile));
}
It will also console.log
what .env file it was loaded
Script Run Confirmation
Before running the script, we show some environment variables and ask to confirm
let rl: Interface | null = null;
export const ask = (question: string): Promise<string> => {
if (!rl) {
rl = readline.createInterface({ input, output });
}
return new Promise((resolve) => {
rl.question(question, (answer) => resolve(answer));
});
};
export const prompt = async () => {
// eslint-disable-next-line
console.log({
MONGO_URI: config.MONGO_URI,
REDIS_HOST: config.REDIS_HOST,
APP_ENV: config.APP_ENV,
});
if (process.env.CONFIRM_PROMPT !== 'true') {
return;
}
const answer = await ask('Run ? (y/n)');
if (answer?.toLowerCase() !== 'y') {
throw new Error('Aborted');
}
};
onlyLocalhost
We also have a function onlyLocalhost
that we use in some scripts like seed or drop database that should never being run against staging or production environment.
export const onlyLocalhost = () => {
if (
config.MONGO_URI !== 'mongodb://localhost/woovi' &&
config.MONGO_URI !==
'mongodb://mongo1:27017,mongo2:27017/woovi?replicaSet=rs0'
) {
throw new Error(`MONGO_URI is not localhost: ${config.MONGO_URI}`);
}
}
If we try to run a script with onlyLocalhost()
against staging or production it will break the script from running.
In Short
Sometimes you can't avoid running a script in production to provide a quick fix for some unexpected behavior.
If you need to make this, try to add this tooling to make it fast, and avoid running DROP DATABASE
in production.
Woovi
Woovi is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.
If you want to work with us, we are hiring!
Top comments (0)