Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[93] New Docker command to generate DockerFiles of specified services #34

Merged
merged 25 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a96f268
feat: docker command to generate dockerfiles of services
Savio629 Jun 20, 2024
1c4c7da
fix: updated monitor to monitoring
Savio629 Jun 20, 2024
44ce5bd
fix: updated nest collection
Savio629 Jun 20, 2024
d86d060
feat: updated the stencil docker command
Savio629 Jun 23, 2024
a045390
fix: switched to generate command structure
Savio629 Jun 25, 2024
a22ef10
fix: console table when wrong command is sent
Savio629 Jun 25, 2024
84574c2
fix: updated existing unit test and implemented e2e test
Savio629 Jun 27, 2024
e796548
fix: updated test
Savio629 Jun 28, 2024
c849706
feat: Added support for path for A la carte setup
Savio629 Jul 9, 2024
acbae1d
fix: added the docker command for temporal
Savio629 Jul 14, 2024
0da5d4a
fix: fixed docker flag
Savio629 Jul 14, 2024
f51d251
fix: updated test cases for docker command
Savio629 Jul 19, 2024
6f92ab0
fix: updated docker e2e test
Savio629 Jul 20, 2024
42550ed
fix: removed logging flags and command
Savio629 Jul 20, 2024
9c55524
fix: updated docker command e2e test
Savio629 Jul 20, 2024
7786357
feat: Added Docker command readme
Savio629 Jul 20, 2024
220edc6
fix: added minio and fusionauth
Savio629 Aug 23, 2024
4d0c128
fix: fix the e2e test
Savio629 Aug 24, 2024
5851057
fix: increased the timeout
Savio629 Aug 24, 2024
874297c
fix: updated the docs
Savio629 Aug 24, 2024
ae9c4f3
fix: removed comments of logging
Savio629 Aug 24, 2024
6a446fc
fix: updated readme
Savio629 Sep 14, 2024
459f28f
fix: for generation of docker using spec
Savio629 Sep 14, 2024
b28d8c7
fix: updated time for test
Savio629 Sep 19, 2024
16f23b1
Merge branch 'dev' into docker-command
techsavvyash Sep 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions Docker-readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## Docker Command

```
stencil docker <services...> [options]
stencil do <services...> [options]
```
**Description**

Creates a docker service/container for given command.
- Tooling specific setup
- Creates a folder with the given `<service>` inside docker directory
- À la Carte setup / Adhoc setup
- Creates a docker compose or updates existing docker compose with desired `<service>`

**Arguments**

| Argument | Description |
|-----------|--------------|
| `<service>` | The name of the new project |

**Options**

| Option | Description |
|-----------|--------------|
| `--path [path]` | The path where the docker compose will be generated |


Note: Docker command supports multiple services at a time.

**Services**

- Tooling specific setup


| Name | Alias | Description |
|---|---|---|
| `logging` | `lg` | Generates a docker service for logging |
| `monitoringService` |`ms` | Generates a docker service for monitoring |
| `temporal` | `tp` | Generates a docker service for temporal |

- À la Carte setup / Adhoc setup


| Name | Alias | Description |
|---|---|---|
| `postgres` | `pg` | Generate a docker compose for postgres |
| `hasura` |`hs` | Generate a docker compose for hasura |
| `minio` |`mi` | Generate a docker compose for minio |
| `fusionauth` |`fa` | Generate a docker compose for fusionauth |


## How to include new docker services ?

**Stencil-cli**

1. Include the docker service in `lib/schematics/nest.collection.ts` with its name, alias and description.

**Schematics**
1. Create a folder inside of **schematics** package under `src/lib/docker/nameOfDockerService`
2. If the dockerService is a tooling setup then refer existing tooling setups such as temporal,monitoringService, logging.
- Create `src/lib/docker/files/ts/nameOfDockerService` and paste all the necessary files needed to be generated when the service is called.
- Create factory file, schema file and interface of the dockerService inside `src/lib/docker/nameOfDockerService` by refering existing tooling setup.
3. If the dockerService is a adhoc setup then refer existing adhoc setup such as postgres, hasura.
- Create factory file, schema file and interface of the dockerService inside `src/lib/docker/nameOfDockerService` by refering existing adhoc setup.
- Paste the `docker-compose` and `.env` content inside of factory file refering existing adhoc setup.

## Which files will be changed/updated?

**Tooling setup**
- Basically whenever tooling setup is generated eg. `stencil docker temporal` , `docker/temporal` will be created.

**Adhoc Setup**
- Whenever adhoc setup is generated eg. `stencil docker postgres` , then` docker-compose`, `.env` and `docker-start.sh` is generated/updated.
96 changes: 96 additions & 0 deletions actions/docker.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
AbstractPackageManager,
PackageManagerFactory,
} from '../lib/package-managers';
import { AbstractCollection, Collection, CollectionFactory, SchematicOption,} from '../lib/schematics';
import { AbstractAction } from './abstract.action';
import { Input } from '../commands';
import * as chalk from 'chalk';
import * as fs from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

export class DockerAction extends AbstractAction {
private manager!: AbstractPackageManager;
public async handle(commandInputs: Input[],options: Input[]) {
this.manager = await PackageManagerFactory.find();

const serviceName = commandInputs[0].value as string;

const specFilePath = await this.getSpecFilePath();

if (specFilePath) {
await this.updateSpecFile(specFilePath, serviceName);
}

const collection: AbstractCollection = CollectionFactory.create(
Collection.NESTJS,
);
const schematicOptions: SchematicOption[] = this.mapSchematicOptions(commandInputs);
schematicOptions.push(
new SchematicOption('language', 'ts'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why have we hardcoded to ts

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was already present with new command
It is the default language which is pushed if no language is given by the user

);
const path = options.find((option) => option.name === 'path')!.value as string;
schematicOptions.push(new SchematicOption('path', path));
try {
await collection.execute(commandInputs[0].value as string, schematicOptions,'docker');
}catch(error){
if (error && error.message) {
console.error(chalk.red(error.message));
}
}
}
private async getSpecFilePath(): Promise<string | null> {
try {
const nestCliConfig = await fs.promises.readFile('nest-cli.json', 'utf-8');
const config = JSON.parse(nestCliConfig);
if (config.specFile) {
return config.specFile;
} else {
return null;
}
} catch (error) {
console.error(chalk.red('Error reading nest-cli.json'), error);
return null;
}
}

private async updateSpecFile(specFilePath: string, serviceName: string): Promise<boolean> {
try {
const specFileFullPath = join(process.cwd(), specFilePath);
const specFileContent = await fs.promises.readFile(specFileFullPath, 'utf-8');
const spec = yaml.load(specFileContent) as any;

if (!spec.docker) {
spec.docker = [];
}

let updated = false;
if (!spec.docker.includes(serviceName)) {
spec.docker.push(serviceName);
updated = true;
}

if (updated) {
const updatedYaml = yaml.dump(spec);
await fs.promises.writeFile(specFileFullPath, updatedYaml, 'utf-8');
}

return updated;
} catch (error) {
console.error(chalk.red('Error reading or updating spec.yaml'), error);
return false;
}
}

private mapSchematicOptions = (inputs: Input[]): SchematicOption[] => {
const excludedInputNames = ['path','schematic', 'spec', 'flat', 'specFileSuffix'];
const options: SchematicOption[] = [];
inputs.forEach((input) => {
if (!excludedInputNames.includes(input.name) && input.value !== undefined) {
options.push(new SchematicOption(input.name, input.value));
}
});
return options;
};
}
2 changes: 1 addition & 1 deletion actions/generate.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const generateFiles = async (inputs: Input[]) => {
if (!schematicInput) {
throw new Error('Unable to find a schematic for this configuration');
}
await collection.execute(schematicInput.value as string, schematicOptions);
await collection.execute(schematicInput.value as string, schematicOptions, 'schematic');
} catch (error) {
if (error && error.message) {
console.error(chalk.red(error.message));
Expand Down
1 change: 1 addition & 0 deletions actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './list.action';
export * from './new.action';
export * from './start.action';
export * from './add.action';
export * from './docker.action';
Loading