Skip to content

Commit

Permalink
feat(system-server): add app service docker driver;
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow committed Sep 3, 2021
1 parent 1b45164 commit adfb27d
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions packages/system-server/src/lib/service-driver/container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import * as Docker from 'dockerode'
import { ApplicationStruct, getApplicationDbUri } from '../../api/application'
import Config from '../../config'
import { logger } from '../logger'


export class DockerContainerServiceDriver {
docker: Docker

constructor(options?: Docker.DockerOptions) {
this.docker = new Docker(options)
}

/**
* Create application service
* @param app
* @returns
*/
async createService(app: ApplicationStruct) {
const uri = getApplicationDbUri(app)

const container = await this.docker.createContainer({
Image: 'lessx/laf-app-server:latest',
Cmd: ['npm', 'run', 'init-start'],
name: `app_${app.appid}`,
Env: [
`DB=${app.config.db_name}`,
`DB_URI=${uri}`,
`LOG_LEVEL=debug`,
`ENABLE_CLOUD_FUNCTION_LOG=always`,
`SERVER_SECRET_SALT=${app.config.server_secret_salt}`
],
ExposedPorts: {
"8000/tcp": {}
},
HostConfig: {
}
})

logger.debug(`create container ${container.id} of app ${app.appid}`)

// add the the app network
const net = await this.getSharedNetwork()
await net.connect({ Container: container.id })

return container
}

/**
* Start application service
* @param app
* @returns the container id
*/
async startService(app: ApplicationStruct) {
let container = this.getContainer(app)
const info = await this.info(app)
if (!info) {
container = await this.createService(app)
}

if (info?.State?.Running || info?.State?.Restarting) {
return container.id
}

await container.start()
logger.debug(`start container ${container.id} of app ${app.appid}`)

return container.id
}

/**
* Remove application service
* @param app
*/
async removeService(app: ApplicationStruct) {
const info = await this.info(app)
if (!info) {
return
}

const container = this.getContainer(app)
if (info.State.Running) {
await container.stop()
}

if (info.State.Restarting) {
await container.stop()
}

await container.remove()
logger.debug(`remove container ${container.id} of app ${app.appid}`)

return container.id
}

/**
* Get container info
* @param container
* @returns return null if container not exists
*/
async info(app: ApplicationStruct): Promise<Docker.ContainerInspectInfo> {
try {
const container = this.getContainer(app)
const info = await container.inspect()
return info
} catch (error) {
if (error.reason === 'no such container') {
return null
}
throw error
}
}

getContainer(app: ApplicationStruct) {
return this.docker.getContainer(`app_${app.appid}`)
}

/**
* Get or create the shared network
* @returns
*/
async getSharedNetwork() {
const name = Config.SHARED_NETWORK
let net = this.docker.getNetwork(name)
const info = await net.inspect()
if (!info) {
net = await this.docker.createNetwork({
Name: name,
Driver: 'bridge'
})
}

return net
}
}
Empty file.
Empty file.

0 comments on commit adfb27d

Please sign in to comment.