@lenne.tech/cli 0.0.79 → 0.0.80

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.
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const path_1 = require("path");
13
+ /**
14
+ * Create a new server module
15
+ */
16
+ const NewCommand = {
17
+ name: 'create',
18
+ alias: ['dc'],
19
+ description: 'Creates a new deployment for mono repository',
20
+ hidden: false,
21
+ run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
22
+ // Retrieve the tools we need
23
+ const { filesystem, helper, parameters, print: { info, spin, success }, strings: { kebabCase, pascalCase, camelCase }, prompt: { confirm }, system, template, } = toolbox;
24
+ // Start timer
25
+ const timer = system.startTimer();
26
+ // Info
27
+ info('Create a new deployment');
28
+ // Get name
29
+ const name = yield helper.getInput(parameters.first, {
30
+ name: 'project name',
31
+ });
32
+ if (!name) {
33
+ return;
34
+ }
35
+ // Get url
36
+ const url = yield helper.getInput(parameters.second, {
37
+ name: 'url for deployment',
38
+ });
39
+ if (!name) {
40
+ return;
41
+ }
42
+ const gitHub = yield confirm(`Add GitHub pipeline?`);
43
+ const gitLab = yield confirm(`Add GitLab pipeline?`);
44
+ // Set up initial props (to pass into templates)
45
+ const nameCamel = camelCase(name);
46
+ const nameKebab = kebabCase(name);
47
+ const namePascal = pascalCase(name);
48
+ // Check if directory
49
+ const cwd = filesystem.cwd();
50
+ const generateSpinner = spin('Generate files');
51
+ yield template.generate({
52
+ template: 'deployment/scripts/build-push.sh.ejs',
53
+ target: (0, path_1.join)(cwd, 'scripts', 'build-push.sh'),
54
+ props: { nameCamel, nameKebab, namePascal },
55
+ });
56
+ yield template.generate({
57
+ template: 'deployment/scripts/deploy.sh.ejs',
58
+ target: (0, path_1.join)(cwd, 'scripts', 'deploy.sh'),
59
+ props: { nameCamel, nameKebab, namePascal },
60
+ });
61
+ yield template.generate({
62
+ template: 'deployment/Dockerfile.ejs',
63
+ target: (0, path_1.join)(cwd, 'Dockerfile'),
64
+ props: { nameCamel, nameKebab, namePascal },
65
+ });
66
+ yield template.generate({
67
+ template: 'deployment/Dockerfile.app.ejs',
68
+ target: (0, path_1.join)(cwd, 'Dockerfile.app'),
69
+ props: { nameCamel, nameKebab, namePascal },
70
+ });
71
+ yield template.generate({
72
+ template: 'deployment/docker-compose.develop.yml.ejs',
73
+ target: (0, path_1.join)(cwd, 'docker-compose.develop.yml'),
74
+ props: { nameCamel, nameKebab, namePascal },
75
+ });
76
+ yield template.generate({
77
+ template: 'deployment/docker-compose.test.yml.ejs',
78
+ target: (0, path_1.join)(cwd, 'docker-compose.test.yml'),
79
+ props: { nameCamel, nameKebab, namePascal },
80
+ });
81
+ yield template.generate({
82
+ template: 'deployment/docker-compose.prod.yml.ejs',
83
+ target: (0, path_1.join)(cwd, 'docker-compose.prod.yml'),
84
+ props: { nameCamel, nameKebab, namePascal },
85
+ });
86
+ if (gitHub) {
87
+ yield template.generate({
88
+ template: 'deployment/.github/workflows/pre-release.yml.ejs',
89
+ target: (0, path_1.join)(cwd, '.github', 'workflows', 'pre-release.yml'),
90
+ props: { nameCamel, nameKebab, namePascal, url },
91
+ });
92
+ yield template.generate({
93
+ template: 'deployment/.github/workflows/release.yml.ejs',
94
+ target: (0, path_1.join)(cwd, '.github', 'workflows', 'release.yml'),
95
+ props: { nameCamel, nameKebab, namePascal, url },
96
+ });
97
+ }
98
+ if (gitLab) {
99
+ yield template.generate({
100
+ template: 'deployment/.gitlab-ci.yml.ejs',
101
+ target: (0, path_1.join)(cwd, '.gitlab-ci.yml'),
102
+ props: { nameCamel, nameKebab, namePascal, url },
103
+ });
104
+ }
105
+ generateSpinner.succeed('Files generated');
106
+ // We're done, so show what to do next
107
+ info(``);
108
+ success(`Generated deployment for ${namePascal} in ${helper.msToMinutesAndSeconds(timer())}m.`);
109
+ info(``);
110
+ if (!toolbox.parameters.options.fromGluegunMenu) {
111
+ process.exit();
112
+ }
113
+ // For tests
114
+ return `new deployment ${name}`;
115
+ }),
116
+ };
117
+ exports.default = NewCommand;
118
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2RlcGxveW1lbnQvY3JlYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQ0EsK0JBQTRCO0FBRzVCOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEdBQW1CO0lBQ2pDLElBQUksRUFBRSxRQUFRO0lBQ2QsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDO0lBQ2IsV0FBVyxFQUFFLDhDQUE4QztJQUMzRCxNQUFNLEVBQUUsS0FBSztJQUNiLEdBQUcsRUFBRSxDQUFPLE9BQStCLEVBQUUsRUFBRTtRQUM3Qyw2QkFBNkI7UUFDN0IsTUFBTSxFQUNKLFVBQVUsRUFDVixNQUFNLEVBQ04sVUFBVSxFQUNWLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEVBQzlCLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQzdDLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUNuQixNQUFNLEVBQ04sUUFBUSxHQUNULEdBQUcsT0FBTyxDQUFDO1FBRVosY0FBYztRQUNkLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVsQyxPQUFPO1FBQ1AsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFaEMsV0FBVztRQUNYLE1BQU0sSUFBSSxHQUFHLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFO1lBQ25ELElBQUksRUFBRSxjQUFjO1NBQ3JCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDVCxPQUFPO1NBQ1I7UUFFRCxVQUFVO1FBQ1YsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7WUFDbkQsSUFBSSxFQUFFLG9CQUFvQjtTQUMzQixDQUFD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
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ /**
13
+ * Deployment commands
14
+ */
15
+ module.exports = {
16
+ name: 'deployment',
17
+ alias: ['d'],
18
+ description: 'Server commands',
19
+ hidden: true,
20
+ run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
21
+ yield toolbox.helper.showMenu('deployment');
22
+ return 'deployment';
23
+ }),
24
+ };
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9kZXBsb3ltZW50L2RlcGxveW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFFQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxPQUFPLEdBQUc7SUFDZixJQUFJLEVBQUUsWUFBWTtJQUNsQixLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUM7SUFDWixXQUFXLEVBQUUsaUJBQWlCO0lBQzlCLE1BQU0sRUFBRSxJQUFJO0lBQ1osR0FBRyxFQUFFLENBQU8sT0FBK0IsRUFBRSxFQUFFO1FBQzdDLE1BQU0sT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDNUMsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQyxDQUFBO0NBQ0YsQ0FBQyJ9
@@ -0,0 +1,41 @@
1
+ name: Deploy
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - prereleased
7
+
8
+ env:
9
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
10
+
11
+ jobs:
12
+ deploy:
13
+ runs-on: [self-hosted, docker-live]
14
+ env:
15
+ STACK_NAME: <%= props.nameCamel %>
16
+ APP_URL: test.<%= props.url %>
17
+ CI_REGISTRY_IMAGE: localhost:5000/<%= props.nameCamel %>
18
+ FILE_NAME: docker-compose.test.yml
19
+ steps:
20
+ - uses: actions/checkout@v1
21
+ - name: Use Node.js 18
22
+ uses: actions/setup-node@v1
23
+ with:
24
+ node-version: 18
25
+ - name: Install
26
+ run: npm run init
27
+ - name: Build app
28
+ run: npm run build:test
29
+ - name: Build docker
30
+ run: STACK_NAME=${{env.STACK_NAME}} APP_URL=${{env.APP_URL}} IMAGE_TAG=test CI_REGISTRY_IMAGE=${{env.CI_REGISTRY_IMAGE}} sh build-push.sh
31
+ - name: Deploy
32
+ run: FILE_NAME=${{env.FILE_NAME}} STACK_NAME=${{env.STACK_NAME}} APP_URL=${{env.APP_URL}} IMAGE_TAG=test CI_REGISTRY_IMAGE=${{env.CI_REGISTRY_IMAGE}} sh deploy.sh
33
+ - name: Deploy notification
34
+ if: always()
35
+ uses: adamkdean/simple-slack-notify@master
36
+ with:
37
+ channel: "#deployments"
38
+ status: ${{ job.status }}
39
+ success_text: "Version (#${{ github.event.release.tag_name }}) von <%= props.nameCamel %> wurde erfolgreich auf *Test* deployed."
40
+ failure_text: "Testversion (#${{ github.event.release.tag_name }}) von <%= props.nameCamel %> ist fehlgeschlagen."
41
+ cancelled_text: "Testversion (#${{ github.event.release.tag_name }}) von <%= props.nameCamel %> wurde abgebrochen."
@@ -0,0 +1,41 @@
1
+ name: Deploy
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - released
7
+
8
+ env:
9
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
10
+
11
+ jobs:
12
+ deploy:
13
+ runs-on: [self-hosted, docker-live-swaktiv]
14
+ env:
15
+ STACK_NAME: <%= props.nameCamel %>
16
+ APP_URL: <%= props.url %>
17
+ CI_REGISTRY_IMAGE: localhost:5000/<%= props.nameCamel %>
18
+ FILE_NAME: docker-compose.prod.yml
19
+ steps:
20
+ - uses: actions/checkout@v1
21
+ - name: Use Node.js 18
22
+ uses: actions/setup-node@v1
23
+ with:
24
+ node-version: 18
25
+ - name: Install
26
+ run: npm run init
27
+ - name: Build app
28
+ run: npm run build
29
+ - name: Build docker
30
+ run: STACK_NAME=${{env.STACK_NAME}} APP_URL=${{env.APP_URL}} IMAGE_TAG=latest CI_REGISTRY_IMAGE=${{env.CI_REGISTRY_IMAGE}} sh build-push.sh
31
+ - name: Deploy
32
+ run: FILE_NAME=${{env.FILE_NAME}} STACK_NAME=${{env.STACK_NAME}} APP_URL=${{env.APP_URL}} IMAGE_TAG=latest CI_REGISTRY_IMAGE=${{env.CI_REGISTRY_IMAGE}} sh deploy.sh
33
+ - name: Deploy notification
34
+ if: always()
35
+ uses: adamkdean/simple-slack-notify@master
36
+ with:
37
+ channel: "#deployments"
38
+ status: ${{ job.status }}
39
+ success_text: "Version (#${{ github.event.release.tag_name }}) von <%= props.nameCamel %> wurde erfolgreich auf *Live* deployed."
40
+ failure_text: "Release (#${{ github.event.release.tag_name }}) von <%= props.nameCamel %> ist fehlgeschlagen."
41
+ cancelled_text: "Release (#${{ github.event.release.tag_name }}) von <%= props.nameCamel %> wurde abgebrochen."
@@ -0,0 +1,187 @@
1
+ image: node:18-alpine
2
+
3
+ stages:
4
+ - install_dependencies
5
+ # - version_number
6
+ - build
7
+ - package
8
+ - deploy
9
+
10
+ variables:
11
+ APP_URL_PROD: <%= props.url %>
12
+ APP_URL_TEST: test.<%= props.url %>
13
+ STACK_NAME: $CI_PROJECT_NAME
14
+ FILE_NAME_PROD: docker-compose.prod.yml
15
+ FILE_NAME_TEST: docker-compose.test.yml
16
+ CI_NAME: 'gitlab'
17
+ CI_EMAIL: 'gitlab-ci@example.com'
18
+
19
+ install_dependencies:
20
+ stage: install_dependencies
21
+ cache:
22
+ key: $CI_PROJECT_DIR
23
+ paths:
24
+ - node_modules/
25
+ policy: push
26
+ script:
27
+ - npm ci
28
+ only:
29
+ refs:
30
+ - develop
31
+ - test
32
+ - release
33
+ - preview
34
+ - main
35
+ changes:
36
+ - package-lock.json
37
+
38
+ build_review:
39
+ stage: build
40
+ cache:
41
+ key: $CI_PROJECT_DIR
42
+ paths:
43
+ - node_modules/
44
+ policy: pull
45
+ artifacts:
46
+ paths:
47
+ - projects/api/dist/
48
+ - projects/app/dist/
49
+ expire_in: 5 minutes
50
+ script:
51
+ - npm run init
52
+ - npm run build
53
+ rules:
54
+ - if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "test" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "release" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "preview" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != "main"
55
+
56
+ build:prod:
57
+ stage: build
58
+ cache:
59
+ key: $CI_PROJECT_DIR
60
+ paths:
61
+ - node_modules/
62
+ policy: pull
63
+ artifacts:
64
+ paths:
65
+ - projects/api/dist/
66
+ - projects/app/dist/
67
+ expire_in: 5 minutes
68
+ script:
69
+ - npm run init
70
+ - npm run build
71
+ only:
72
+ - main
73
+
74
+ build:test:
75
+ stage: build
76
+ image: tarampampam/node:16-alpine
77
+ cache:
78
+ key: $CI_PROJECT_DIR
79
+ paths:
80
+ - node_modules/
81
+ policy: pull
82
+ artifacts:
83
+ paths:
84
+ - projects/api/dist/
85
+ - projects/app/dist/
86
+ expire_in: 5 minutes
87
+ script:
88
+ - git config --global user.email $CI_EMAIL
89
+ - git config --global user.name $CI_NAME
90
+ - git config http.sslVerify "false"
91
+ - git config receive.advertisePushOptions true
92
+ - git fetch
93
+ - git pull https://${CI_USER}:${CI_ACCESS_TOKEN}@gitlab.lenne.tech/products/akademie/master-minds.git test:test
94
+ - npm run init
95
+ - npm run build:test
96
+ only:
97
+ - test
98
+
99
+ build:develop:
100
+ stage: build
101
+ cache:
102
+ key: $CI_PROJECT_DIR
103
+ paths:
104
+ - node_modules/
105
+ policy: pull
106
+ artifacts:
107
+ paths:
108
+ - projects/api/dist/
109
+ - projects/app/dist/
110
+ expire_in: 5 minutes
111
+ script:
112
+ - npm run init
113
+ - npm run build:develop
114
+ only:
115
+ - develop
116
+
117
+ #version_number:
118
+ # stage: version_number
119
+ # image: tarampampam/node:alpine
120
+ # script:
121
+ # - git config --global user.email $CI_EMAIL
122
+ # - git config --global user.name $CI_NAME
123
+ # - git config http.sslVerify "false"
124
+ # - npm install
125
+ # - git config receive.advertisePushOptions true
126
+ # - git checkout -B "$CI_COMMIT_REF_NAME" "$CI_COMMIT_SHA"
127
+ # - npm run release
128
+ # - git push -o ci.skip --no-verify https://${CI_USER}:${CI_ACCESS_TOKEN}@gitlab.lenne.tech/products/akademie/master-minds.git --follow-tags test:test
129
+ # - git fetch && git checkout develop
130
+ # - git merge test
131
+ # - git push -o ci.skip --no-verify https://${CI_USER}:${CI_ACCESS_TOKEN}@gitlab.lenne.tech/products/akademie/master-minds.git --follow-tags develop:develop
132
+ # only:
133
+ # - test
134
+
135
+ docker_build_push_test:
136
+ stage: package
137
+ image: tiangolo/docker-with-compose
138
+ services:
139
+ - docker:dind
140
+ before_script:
141
+ - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
142
+ script:
143
+ - FILE_NAME=$FILE_NAME_TEST STACK_NAME=$STACK_NAME APP_URL=$APP_URL_TEST IMAGE_TAG=test CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE sh build-push.sh
144
+ only:
145
+ - test
146
+
147
+ deploy_test:
148
+ stage: deploy
149
+ image: tiangolo/docker-with-compose
150
+ tags:
151
+ - docker-swarm
152
+ before_script:
153
+ - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
154
+ script:
155
+ - FILE_NAME=$FILE_NAME_TEST STACK_NAME=$STACK_NAME APP_URL=$APP_URL_TEST IMAGE_TAG=test CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE sh deploy.sh
156
+ environment:
157
+ name: test
158
+ url: https://$APP_URL_TEST
159
+ only:
160
+ - test
161
+
162
+ docker_build_push_prod:
163
+ stage: package
164
+ image: tiangolo/docker-with-compose
165
+ dependencies:
166
+ - build:prod
167
+ before_script:
168
+ - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
169
+ script:
170
+ - FILE_NAME=$FILE_NAME_PROD STACK_NAME=$STACK_NAME APP_URL=$APP_URL_PROD IMAGE_TAG=production CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE sh build-push.sh
171
+ only:
172
+ - main
173
+
174
+ deploy_prod:
175
+ stage: deploy
176
+ image: tiangolo/docker-with-compose
177
+ tags:
178
+ - docker-live
179
+ before_script:
180
+ - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
181
+ script:
182
+ - FILE_NAME=$FILE_NAME_PROD STACK_NAME=$STACK_NAME APP_URL=$APP_URL_PROD IMAGE_TAG=production CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE sh deploy.sh
183
+ environment:
184
+ name: production
185
+ url: https://$APP_URL_PROD
186
+ only:
187
+ - main
@@ -0,0 +1,13 @@
1
+ FROM mhart/alpine-node:16
2
+
3
+ RUN mkdir -p /var/www
4
+
5
+ RUN apk --no-cache add curl
6
+
7
+ COPY ./projects/app/dist/app ./var/www
8
+
9
+ HEALTHCHECK CMD curl --fail http://localhost:4000/ || exit 1
10
+
11
+ WORKDIR /var/www/server
12
+
13
+ EXPOSE 4000
@@ -0,0 +1,18 @@
1
+ FROM mhart/alpine-node:16.4.2
2
+
3
+ RUN mkdir -p /var/www/api
4
+
5
+ RUN apk --no-cache add curl
6
+
7
+ ADD ./projects/api/package.json /var/www/api/package.json
8
+ ADD ./projects/api/package-lock.json /var/www/api/package-lock.json
9
+
10
+ COPY ./projects/api/dist ./var/www/api
11
+
12
+ RUN cd /var/www/api && npm install && npm cache clean --force
13
+
14
+ HEALTHCHECK --interval=60s --retries=5 CMD curl --fail http://localhost:3000/meta/ || exit 1
15
+
16
+ WORKDIR /var/www/api
17
+
18
+ EXPOSE 3000
@@ -0,0 +1,99 @@
1
+ version: "3.7"
2
+
3
+ networks:
4
+ traefik-public:
5
+ external: true
6
+ overlay_mongo:
7
+ external: true
8
+
9
+ services:
10
+ api:
11
+ build:
12
+ context: .
13
+ dockerfile: Dockerfile
14
+ image: ${CI_REGISTRY_IMAGE?Variable not set}/api:${IMAGE_TAG?Variable not set}
15
+ restart: unless-stopped
16
+ container_name: swaktiv-api-${IMAGE_TAG?Variable not set}
17
+ networks:
18
+ - traefik-public
19
+ - overlay_mongo
20
+ deploy:
21
+ placement:
22
+ constraints:
23
+ - node.labels.traefik-public.traefik-public-certificates == true
24
+ update_config:
25
+ order: start-first
26
+ failure_action: rollback
27
+ delay: 10s
28
+ rollback_config:
29
+ parallelism: 0
30
+ order: stop-first
31
+ restart_policy:
32
+ condition: any
33
+ delay: 5s
34
+ max_attempts: 3
35
+ window: 120s
36
+ labels:
37
+ - traefik.enable=true
38
+ - traefik.docker.network=traefik-public
39
+ - traefik.constraint-label=traefik-public
40
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.rule=Host(`api.${APP_URL?Variable not set}`)
41
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.entrypoints=http
42
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.middlewares=https-redirect
43
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.rule=Host(`api.${APP_URL?Variable not set}`)
44
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.entrypoints=https
45
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.tls=true
46
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.tls.certresolver=le
47
+ - traefik.http.services.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api.loadbalancer.server.port=3000
48
+ entrypoint: ["/bin/sh", "-c"]
49
+ command:
50
+ - |
51
+ npm run migrate:develop:up
52
+ NODE_ENV=develop node ./src/main.js
53
+
54
+ app:
55
+ build:
56
+ context: .
57
+ dockerfile: Dockerfile.app
58
+ image: ${CI_REGISTRY_IMAGE?Variable not set}/app-ssr:${IMAGE_TAG?Variable not set}
59
+ restart: unless-stopped
60
+ container_name: swaktiv-app-${IMAGE_TAG?Variable not set}
61
+ entrypoint: ["/bin/sh", "-c"]
62
+ networks:
63
+ - traefik-public
64
+ deploy:
65
+ placement:
66
+ constraints:
67
+ - node.labels.traefik-public.traefik-public-certificates == true
68
+ update_config:
69
+ order: start-first
70
+ failure_action: rollback
71
+ delay: 10s
72
+ rollback_config:
73
+ parallelism: 0
74
+ order: stop-first
75
+ restart_policy:
76
+ condition: any
77
+ delay: 5s
78
+ max_attempts: 3
79
+ window: 120s
80
+ labels:
81
+ - traefik.enable=true
82
+ - traefik.docker.network=traefik-public
83
+ - traefik.constraint-label=traefik-public
84
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.rule=Host(`${APP_URL?Variable not set}`, `www.${APP_URL?Variable not set}`)
85
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.entrypoints=http
86
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.middlewares=https-redirect
87
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.rule=Host(`${APP_URL?Variable not set}`, `www.${APP_URL?Variable not set}`)
88
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.entrypoints=https
89
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.tls=true
90
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.tls.certresolver=le
91
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.regex=^https?://www.${APP_URL}/(.*)
92
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.replacement=https://${APP_URL}/$${1}
93
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.permanent=true
94
+ - traefik.http.services.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app.loadbalancer.server.port=4000
95
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.middlewares=${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect
96
+
97
+ command:
98
+ - |
99
+ NODE_ENV=develop node main.js
@@ -0,0 +1,92 @@
1
+ version: "3.7"
2
+
3
+ networks:
4
+ traefik-public:
5
+ external: true
6
+ overlay_mongo:
7
+ external: true
8
+
9
+ services:
10
+ api:
11
+ build:
12
+ context: .
13
+ dockerfile: Dockerfile
14
+ image: ${CI_REGISTRY_IMAGE?Variable not set}/api:${IMAGE_TAG?Variable not set}
15
+ restart: unless-stopped
16
+ container_name: <%= props.nameCamel %>-api-${IMAGE_TAG?Variable not set}
17
+ networks:
18
+ - traefik-public
19
+ - overlay_mongo
20
+ deploy:
21
+ update_config:
22
+ order: start-first
23
+ failure_action: rollback
24
+ delay: 10s
25
+ rollback_config:
26
+ parallelism: 0
27
+ order: stop-first
28
+ restart_policy:
29
+ condition: any
30
+ delay: 5s
31
+ max_attempts: 3
32
+ window: 120s
33
+ labels:
34
+ - traefik.enable=true
35
+ - traefik.docker.network=traefik-public
36
+ - traefik.constraint-label=traefik-public
37
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.rule=Host(`api.${APP_URL?Variable not set}`)
38
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.entrypoints=http
39
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.middlewares=https-redirect
40
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.rule=Host(`api.${APP_URL?Variable not set}`)
41
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.entrypoints=https
42
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.tls=true
43
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.tls.certresolver=le
44
+ - traefik.http.services.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api.loadbalancer.server.port=3000
45
+ entrypoint: ["/bin/sh", "-c"]
46
+ command:
47
+ - |
48
+ npm run migrate:prod:up
49
+ NODE_ENV=production node ./src/main.js
50
+
51
+ app:
52
+ build:
53
+ context: .
54
+ dockerfile: Dockerfile.app
55
+ image: ${CI_REGISTRY_IMAGE?Variable not set}/app-ssr:${IMAGE_TAG?Variable not set}
56
+ restart: unless-stopped
57
+ container_name: <%= props.nameCamel %>-app-${IMAGE_TAG?Variable not set}
58
+ entrypoint: ["/bin/sh", "-c"]
59
+ networks:
60
+ - traefik-public
61
+ deploy:
62
+ update_config:
63
+ order: start-first
64
+ failure_action: rollback
65
+ delay: 10s
66
+ rollback_config:
67
+ parallelism: 0
68
+ order: stop-first
69
+ restart_policy:
70
+ condition: any
71
+ delay: 5s
72
+ max_attempts: 3
73
+ window: 120s
74
+ labels:
75
+ - traefik.enable=true
76
+ - traefik.docker.network=traefik-public
77
+ - traefik.constraint-label=traefik-public
78
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.rule=Host(`${APP_URL?Variable not set}`, `www.${APP_URL?Variable not set}`)
79
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.entrypoints=http
80
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.middlewares=https-redirect
81
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.rule=Host(`${APP_URL?Variable not set}`, `www.${APP_URL?Variable not set}`)
82
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.entrypoints=https
83
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.tls=true
84
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.tls.certresolver=le
85
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.regex=^https?://www.${APP_URL}/(.*)
86
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.replacement=https://${APP_URL}/$${1}
87
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.permanent=true
88
+ - traefik.http.services.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app.loadbalancer.server.port=4000
89
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.middlewares=${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect
90
+ command:
91
+ - |
92
+ NODE_ENV="production" node main.js
@@ -0,0 +1,98 @@
1
+ version: "3.7"
2
+
3
+ networks:
4
+ traefik-public:
5
+ external: true
6
+ overlay_mongo:
7
+ external: true
8
+
9
+ services:
10
+ api:
11
+ build:
12
+ context: .
13
+ dockerfile: Dockerfile
14
+ image: ${CI_REGISTRY_IMAGE?Variable not set}/api:${IMAGE_TAG?Variable not set}
15
+ restart: unless-stopped
16
+ container_name: <%= props.nameCamel %>-api-${IMAGE_TAG?Variable not set}
17
+ networks:
18
+ - traefik-public
19
+ - overlay_mongo
20
+ deploy:
21
+ placement:
22
+ constraints:
23
+ - node.labels.traefik-public.traefik-public-certificates == true
24
+ update_config:
25
+ order: start-first
26
+ failure_action: rollback
27
+ delay: 10s
28
+ rollback_config:
29
+ parallelism: 0
30
+ order: stop-first
31
+ restart_policy:
32
+ condition: any
33
+ delay: 5s
34
+ max_attempts: 3
35
+ window: 120s
36
+ labels:
37
+ - traefik.enable=true
38
+ - traefik.docker.network=traefik-public
39
+ - traefik.constraint-label=traefik-public
40
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.rule=Host(`api.${APP_URL?Variable not set}`)
41
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.entrypoints=http
42
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-http.middlewares=https-redirect
43
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.rule=Host(`api.${APP_URL?Variable not set}`)
44
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.entrypoints=https
45
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.tls=true
46
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api-https.tls.certresolver=le
47
+ - traefik.http.services.${STACK_NAME?Variable not set}-${IMAGE_TAG}-api.loadbalancer.server.port=3000
48
+ entrypoint: ["/bin/sh", "-c"]
49
+ command:
50
+ - |
51
+ npm run migrate:test:up
52
+ NODE_ENV=test node ./src/main.js
53
+
54
+ app:
55
+ build:
56
+ context: .
57
+ dockerfile: Dockerfile.app
58
+ image: ${CI_REGISTRY_IMAGE?Variable not set}/app-ssr:${IMAGE_TAG?Variable not set}
59
+ restart: unless-stopped
60
+ container_name: <%= props.nameCamel %>-app-${IMAGE_TAG?Variable not set}
61
+ entrypoint: ["/bin/sh", "-c"]
62
+ networks:
63
+ - traefik-public
64
+ deploy:
65
+ placement:
66
+ constraints:
67
+ - node.labels.traefik-public.traefik-public-certificates == true
68
+ update_config:
69
+ order: start-first
70
+ failure_action: rollback
71
+ delay: 10s
72
+ rollback_config:
73
+ parallelism: 0
74
+ order: stop-first
75
+ restart_policy:
76
+ condition: any
77
+ delay: 5s
78
+ max_attempts: 3
79
+ window: 120s
80
+ labels:
81
+ - traefik.enable=true
82
+ - traefik.docker.network=traefik-public
83
+ - traefik.constraint-label=traefik-public
84
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.rule=Host(`${APP_URL?Variable not set}`, `www.${APP_URL?Variable not set}`)
85
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.entrypoints=http
86
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-http.middlewares=https-redirect
87
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.rule=Host(`${APP_URL?Variable not set}`, `www.${APP_URL?Variable not set}`)
88
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.entrypoints=https
89
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.tls=true
90
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.tls.certresolver=le
91
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.regex=^https?://www.${APP_URL}/(.*)
92
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.replacement=https://${APP_URL}/$${1}
93
+ - traefik.http.middlewares.${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect.redirectregex.permanent=true
94
+ - traefik.http.services.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app.loadbalancer.server.port=4000
95
+ - traefik.http.routers.${STACK_NAME?Variable not set}-${IMAGE_TAG}-app-https.middlewares=${STACK_NAME?Variable not set}-${IMAGE_TAG}-redirect
96
+ command:
97
+ - |
98
+ NODE_ENV=test node main.js
@@ -0,0 +1,20 @@
1
+ #! /usr/bin/env sh
2
+
3
+ # Exit in case of error
4
+ set -e
5
+
6
+ STACK_NAME=${STACK_NAME?Variable not set} \
7
+ APP_URL=${APP_URL?Variable not set} \
8
+ IMAGE_TAG=${IMAGE_TAG?Variable not set} \
9
+ CI_REGISTRY_IMAGE=${CI_REGISTRY_IMAGE?Variable not set} \
10
+ docker compose \
11
+ -f ${FILE_NAME?Variable not set} \
12
+ build
13
+
14
+ STACK_NAME=${STACK_NAME?Variable not set} \
15
+ APP_URL=${APP_URL?Variable not set} \
16
+ IMAGE_TAG=${IMAGE_TAG?Variable not set} \
17
+ CI_REGISTRY_IMAGE=${CI_REGISTRY_IMAGE?Variable not set} \
18
+ docker compose \
19
+ -f ${FILE_NAME?Variable not set} \
20
+ push
@@ -0,0 +1,7 @@
1
+ #! /usr/bin/env sh
2
+
3
+ # Exit in case of error
4
+ set -e
5
+
6
+ docker stack deploy -c ${FILE_NAME?Variable not set} --with-registry-auth ${STACK_NAME?Variable not set}-${IMAGE_TAG}
7
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/cli",
3
- "version": "0.0.79",
3
+ "version": "0.0.80",
4
4
  "description": "lenne.Tech CLI: lt",
5
5
  "keywords": [
6
6
  "lenne.Tech",