auto-deploy-sh 2.1.3 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,7 +24,7 @@ npm install auto-deploy-sh -D
24
24
  }
25
25
  ```
26
26
 
27
- 2. Execute in terminal:
27
+ - Execute in terminal:
28
28
 
29
29
  ```bash
30
30
  npm run deploy
@@ -79,7 +79,12 @@ The configuration file is **fixed as `deploy-config.json`**. If missing, the too
79
79
  - `always`: The container **will always restart automatically** if it stops. It will also start automatically after Docker or system restarts.Even if the container is manually stopped, it will be restarted again after Docker restarts.
80
80
  - `unless-stopped`(recommended): The container will automatically restart on failure and start after Docker or system restarts.**If the container is manually stopped, it will not be restarted again**, making it suitable for long-running production services.
81
81
  - `on-failure`: The container **will restart only if it exits with a non-zero status code**. It will not restart on normal exits (exit code 0).
82
+ - `afterLaunch` (optional): **Post-start commands** (array of strings) to execute on the remote server after the container starts. Commands run from `/tmp/www/app/<containerName>` and are chained with `&&`, so if one command fails, the following commands are skipped and the deployment is marked as failed (e.g., `["docker ps", "curl -f http://localhost/health"]`).
83
+ - `customRunOptions` (optional): Custom content appended to the end of the `docker run` command after the image tag. It can be used to pass a custom container startup command or arguments (e.g., `"--env-file ./env.list"`).
82
84
  - `Options`: **Optional** advanced settings (all sub-properties are optional)
85
+ - `permission`: Build-time user/group settings. During deployment, they are converted to `docker build --build-arg UID=<uid> --build-arg GID=<gid>`. The Dockerfile must declare and use `ARG UID` and `ARG GID` for these values to take effect.
86
+ - `uid`: User ID passed as the `UID` build arg.
87
+ - `gid`: Group ID passed as the `GID` build arg.
83
88
  - `volumes`: Volume mappings (array of strings), formatted as `[host-path/volume-name]:[container-path]:[optional-flags]` (e.g., `["/host/data:/container/data:ro"]`).
84
89
  - `networks`: Connect the container to a custom Docker network (created via `docker network create <network-name>`) for inter-container communication.
85
90
  - `logging`: Docker log management configuration. During deployment, it is converted to Docker `--log-driver` and `--log-opt` arguments. Before starting the container, the tool checks the logging drivers supported by the remote Docker daemon. If the configured `driver` is not supported, deployment stops and prints the current default driver and supported driver list.
@@ -104,7 +109,13 @@ The configuration file is **fixed as `deploy-config.json`**. If missing, the too
104
109
  "containerName": "string",
105
110
  "BindPorts": "string",
106
111
  "restart": "'no' | 'always' | 'unless-stopped' | 'on-failure'",
112
+ "afterLaunch": "string[]",
113
+ "customRunOptions": "string",
107
114
  "Options": {
115
+ "permission": {
116
+ "uid": "string",
117
+ "gid": "string"
118
+ },
108
119
  "volumes": "string[]",
109
120
  "networks": "string[]",
110
121
  "logging": {
@@ -134,7 +145,13 @@ The configuration file is **fixed as `deploy-config.json`**. If missing, the too
134
145
  "containerName": "my-app-container",
135
146
  "BindPorts": "80:80",
136
147
  "restart": "unless-stopped",
148
+ "afterLaunch": ["docker ps", "curl -f http://localhost/health"],
149
+ "customRunOptions": "npm run start:prod",
137
150
  "Options": {
151
+ "permission": {
152
+ "uid": "1000",
153
+ "gid": "1000"
154
+ },
138
155
  "volumes": ["/host/logs:/app/logs:rw"],
139
156
  "networks": ["my-custom-network", "my-custom-network-1"],
140
157
  "logging": {
@@ -69,8 +69,42 @@ const configMethod = {
69
69
  },
70
70
  ],
71
71
  },
72
+ afterLaunch: {
73
+ type: 'input',
74
+ message: 'After launch (multiple commands separated by , ): ',
75
+ handleFn: (value) => value.split(','),
76
+ },
77
+ customRunOptions: {
78
+ type: 'input',
79
+ message: 'Custom run options (optional): eg: --env-file ./env.list',
80
+ },
72
81
  };
73
82
  const optionsMethod = {
83
+ permission: {
84
+ type: 'confirm',
85
+ message: 'Do you want to set the container user permissions?',
86
+ default: false,
87
+ handleFn: async (value) => {
88
+ if (!value)
89
+ return {};
90
+ const gid = await inquirer.invoke({
91
+ type: 'input',
92
+ message: 'GID (Group ID): ',
93
+ });
94
+ const uid = await inquirer.invoke({
95
+ type: 'input',
96
+ message: 'UID (User ID): ',
97
+ });
98
+ if (!gid && !uid)
99
+ return {};
100
+ const options = {};
101
+ if (gid)
102
+ options.gid = gid;
103
+ if (uid)
104
+ options.uid = uid;
105
+ return options;
106
+ },
107
+ },
74
108
  volumes: {
75
109
  type: 'input',
76
110
  message: 'Multiple volumes are divided into by , : ',
@@ -211,6 +211,15 @@ export class Deploy {
211
211
  `);
212
212
  await this.buildDocker(ssh, IMAGE_TAG, REMOTEAPPPATH, TARGET_DIR, CONTAINER_NAME);
213
213
  await this.runDocker(ssh, CONTAINER_NAME);
214
+ if (this.config.afterLaunch && Array.isArray(this.config.afterLaunch)) {
215
+ await this.execCommand(ssh, {
216
+ startMsg: 'Start executing afterLaunch commands....',
217
+ succMsg: 'afterLaunch commands completed.',
218
+ }, `
219
+ cd "${REMOTEAPPPATH}/${CONTAINER_NAME}"
220
+ ${this.config.afterLaunch.join(' && ')}
221
+ `);
222
+ }
214
223
  log.done('✔ Deployment completed.');
215
224
  }
216
225
  catch {
@@ -221,12 +230,18 @@ export class Deploy {
221
230
  }
222
231
  }
223
232
  async buildDocker(ssh, IMAGE_TAG, REMOTEAPPPATH, TARGET_DIR, CONTAINER_NAME) {
233
+ const options = this.config.Options || {};
234
+ const gid = options.permission?.gid || '';
235
+ const uid = options.permission?.uid || '';
236
+ const buildArgs = [uid ? `--build-arg UID=${uid}` : '', gid ? `--build-arg GID=${gid}` : '']
237
+ .filter(Boolean)
238
+ .join(' ');
224
239
  await this.execCommand(ssh, {
225
240
  startMsg: `🐳 Build image: ${IMAGE_TAG}...`,
226
241
  succMsg: `🐳 Build image: ${IMAGE_TAG} success.`,
227
242
  }, `
228
243
  cd "${REMOTEAPPPATH}"
229
- docker build -t ${IMAGE_TAG} ${TARGET_DIR}
244
+ docker build ${buildArgs} -t ${IMAGE_TAG} ${TARGET_DIR}
230
245
  `);
231
246
  await this.execCommand(ssh, {
232
247
  startMsg: `🔄 Stop and clean the old container.: ${CONTAINER_NAME}...`,
@@ -309,7 +324,7 @@ export class Deploy {
309
324
  startMsg: `🐳 Start container: ${CONTAINER_NAME}...`,
310
325
  succMsg: `🐳 Container started successfully.`,
311
326
  }, `
312
- docker run -d ${optionsCLI}
327
+ docker run -d ${optionsCLI} ${this.config.customRunOptions || ''}
313
328
  `);
314
329
  }
315
330
  async judgeNetwork(ssh, networks) {
@@ -11,7 +11,12 @@ export type sshConfig = {
11
11
  containerName: string;
12
12
  BindPorts: string;
13
13
  restart?: 'no' | 'always' | 'on-failure' | 'unless-stopped';
14
+ afterLaunch?: string[];
14
15
  Options: {
16
+ permission?: {
17
+ gid?: string;
18
+ uid?: string;
19
+ };
15
20
  volumes: string[];
16
21
  networks: string[];
17
22
  logging: {
@@ -23,6 +28,7 @@ export type sshConfig = {
23
28
  };
24
29
  };
25
30
  };
31
+ customRunOptions?: string;
26
32
  };
27
33
  export type fileData = string | NodeJS.ArrayBufferView;
28
34
  import type { promises } from 'fs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auto-deploy-sh",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "Automated Docker deployment tool",
5
5
  "bin": {
6
6
  "auto-deploy-sh": "./dist/cli/index.js"