Skip to content

Commit 0b31e36

Browse files
authored
Merge pull request #60 from saving-satoshi/kill-unused-container
Cron Job to klll and remove unused containers every 10 minutes
2 parents cf44221 + 68f75d2 commit 0b31e36

File tree

7 files changed

+292
-133
lines changed

7 files changed

+292
-133
lines changed

.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ PORT=8000
33
SECRET=12345678
44
WHITELIST=http://localhost:3000
55
MAX_SCRIPT_EXECUTION_TIME=30000
6-
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
6+
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
7+
CONTAINER_TERMINATION_SCHEDULE= 10 # Scheduled Time to clear your container in minutes 1<=59

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
.env
33
dist
4+
logs

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"dependencies": {
3333
"@prisma/client": "5.2.0",
3434
"@types/dockerode": "^3.3.31",
35+
"@types/node-cron": "^3.0.11",
3536
"@types/uuid": "^10.0.0",
3637
"ansi-to-html": "^0.7.2",
3738
"body-parser": "^1.20.1",
@@ -44,6 +45,7 @@
4445
"jsonwebtoken": "^9.0.0",
4546
"lodash": "^4.17.21",
4647
"module-alias": "^2.2.2",
48+
"node-cron": "^3.0.3",
4749
"pg": "^8.9.0",
4850
"uuid": "^9.0.0",
4951
"winston": "^3.16.0",

src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import path from 'path'
22

33
export const SUPPORTED_LANGUAGES = ['javascript', 'python', 'go', 'rust', 'cpp']
4+
export const CONTAINERS_TO_KEEP_ON = ['/saving-satoshi']
5+
export const CONTAINERS_SCHEDULE = parseInt(process.env.CONTAINER_TERMINATION_SCHEDULE || "10")
46
export const LANG_PATH = path.join(__dirname, 'languages')

src/index.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ import * as http from 'http'
77
import * as WebSocket from 'ws'
88
import * as repl from 'lib/repl'
99
import logger from 'lib/logger'
10+
import cron from 'node-cron'
1011

1112
import { v1 } from './routes'
1213

1314
import { JobManager } from './lib/jobManager'
14-
15-
const jobManager = new JobManager()
15+
import { killContainers } from 'lib/docker'
16+
import { CONTAINERS_SCHEDULE } from 'config'
1617

1718
const port = process.env.PORT
1819

19-
const JOBS = {}
2020
const WHITELIST = process.env.WHITELIST.split(',').map((a) => a.trim())
2121

2222
function isAllowedOrigin(origin: string): boolean {
@@ -38,6 +38,24 @@ async function run() {
3838
const server = http.createServer(app)
3939
const wss = new WebSocket.Server({ server })
4040

41+
// Cron Job Wrapper
42+
function scheduleRemovalOfContainers(
43+
expression: string,
44+
fn: () => Promise<void>,
45+
options = {}
46+
) {
47+
cron.schedule(
48+
expression,
49+
() => fn().catch((e) => logger.error(e)),
50+
options
51+
)
52+
}
53+
54+
// Cron job to run every specified minutes
55+
scheduleRemovalOfContainers(`*/${CONTAINERS_SCHEDULE} * * * *`, async () => {
56+
await killContainers()
57+
})
58+
4159
// WebSocket connection handler
4260
wss.on(
4361
'connection',

src/lib/docker.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Docker from 'dockerode'
33
import type { Container } from 'dockerode'
44
import logger from './logger'
55
import { JobManager } from './jobManager'
6+
import { CONTAINERS_SCHEDULE, CONTAINERS_TO_KEEP_ON } from 'config'
67

78
export const docker = new Docker()
89

@@ -67,6 +68,31 @@ async function buildImage(
6768
}
6869
}
6970

71+
export async function killContainers() {
72+
const allContainers = await docker.listContainers()
73+
let containersKilled = 0
74+
for (let container of allContainers) {
75+
if (container.Status) {
76+
const stringTime = parseInt(container.Status.split(' ')[1])
77+
const minutes = container.Status.split(' ')[2]
78+
if (minutes === 'minutes' && stringTime >= CONTAINERS_SCHEDULE) {
79+
const isSafeContainer = CONTAINERS_TO_KEEP_ON.includes(
80+
container.Names[0]
81+
)
82+
// So our database migration doesn't get killed
83+
if (!isSafeContainer) {
84+
await docker.getContainer(container.Id).kill()
85+
await docker.getContainer(container.Id).remove()
86+
containersKilled++
87+
}
88+
}
89+
}
90+
}
91+
if (containersKilled) {
92+
logger.info(`${containersKilled} containers were killed`)
93+
}
94+
}
95+
7096
function sanitizeContainerId(id: string): string {
7197
return id.slice(0, 8)
7298
}

0 commit comments

Comments
 (0)