@lazycatcloud/lzc-cli 1.3.13 → 2.0.0-pre.0

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.
Files changed (104) hide show
  1. package/README.md +30 -5
  2. package/changelog.md +16 -0
  3. package/lib/app/index.js +174 -58
  4. package/lib/app/lpk_build.js +197 -18
  5. package/lib/app/lpk_build_images.js +728 -0
  6. package/lib/app/lpk_create.js +96 -23
  7. package/lib/app/lpk_create_generator.js +150 -12
  8. package/lib/app/lpk_devshell.js +35 -21
  9. package/lib/app/lpk_embed_images.js +257 -0
  10. package/lib/app/lpk_installer.js +15 -7
  11. package/lib/app/project_cp.js +64 -0
  12. package/lib/app/project_deploy.js +33 -0
  13. package/lib/app/project_exec.js +45 -0
  14. package/lib/app/project_info.js +106 -0
  15. package/lib/app/project_log.js +67 -0
  16. package/lib/app/project_runtime.js +261 -0
  17. package/lib/app/project_start.js +100 -0
  18. package/lib/appstore/index.js +56 -16
  19. package/lib/appstore/publish.js +16 -13
  20. package/lib/box/index.js +103 -6
  21. package/lib/box/ssh_remote.js +259 -0
  22. package/lib/build_remote.js +22 -0
  23. package/lib/config/index.js +4 -3
  24. package/lib/debug_bridge.js +837 -44
  25. package/lib/docker/index.js +30 -10
  26. package/lib/i18n/index.js +1 -0
  27. package/lib/i18n/locales/en/translation.json +263 -250
  28. package/lib/i18n/locales/zh/translation.json +57 -44
  29. package/lib/lpk/core.js +487 -0
  30. package/lib/lpk/index.js +210 -0
  31. package/lib/shellapi.js +5 -5
  32. package/lib/sig/core.js +254 -0
  33. package/lib/sig/index.js +88 -0
  34. package/lib/utils.js +17 -12
  35. package/package.json +4 -3
  36. package/scripts/cli.js +4 -0
  37. package/template/_lpk/README.md +11 -3
  38. package/template/_lpk/gui-vnc.manifest.yml.in +27 -0
  39. package/template/_lpk/manifest.yml.in +4 -2
  40. package/template/_lpk/todolist-golang.manifest.yml.in +16 -0
  41. package/template/_lpk/todolist-java.manifest.yml.in +15 -0
  42. package/template/_lpk/todolist-python.manifest.yml.in +15 -0
  43. package/template/_lpk/vue.lzc-build.yml.in +0 -44
  44. package/template/blank/_gitignore +1 -0
  45. package/template/blank/lzc-build.yml +25 -40
  46. package/template/blank/lzc-manifest.yml +14 -7
  47. package/template/golang/Dockerfile +19 -0
  48. package/template/golang/README.md +33 -0
  49. package/template/golang/_gitignore +3 -0
  50. package/template/golang/go.mod +3 -0
  51. package/template/golang/lzc-build.yml +21 -0
  52. package/template/golang/lzc-icon.png +0 -0
  53. package/template/golang/main.go +252 -0
  54. package/template/golang/run.sh +3 -0
  55. package/template/golang/web/index.html +238 -0
  56. package/template/gui-vnc/README.md +19 -0
  57. package/template/gui-vnc/_gitignore +2 -0
  58. package/template/gui-vnc/images/Dockerfile +30 -0
  59. package/template/gui-vnc/images/kasmvnc.yaml +33 -0
  60. package/template/gui-vnc/images/startup-script.desktop +9 -0
  61. package/template/gui-vnc/images/startup-script.sh +6 -0
  62. package/template/gui-vnc/lzc-build.yml +23 -0
  63. package/template/gui-vnc/lzc-icon.png +0 -0
  64. package/template/python/Dockerfile +15 -0
  65. package/template/python/README.md +33 -0
  66. package/template/python/_gitignore +3 -0
  67. package/template/python/app.py +110 -0
  68. package/template/python/lzc-build.yml +21 -0
  69. package/template/python/lzc-icon.png +0 -0
  70. package/template/python/requirements.txt +1 -0
  71. package/template/python/run.sh +3 -0
  72. package/template/python/web/index.html +238 -0
  73. package/template/springboot/Dockerfile +20 -0
  74. package/template/springboot/README.md +33 -0
  75. package/template/springboot/_gitignore +3 -0
  76. package/template/springboot/lzc-build.yml +21 -0
  77. package/template/springboot/lzc-icon.png +0 -0
  78. package/template/springboot/pom.xml +38 -0
  79. package/template/springboot/run.sh +3 -0
  80. package/template/springboot/src/main/java/cloud/lazycat/app/Application.java +132 -0
  81. package/template/springboot/src/main/resources/application.properties +1 -0
  82. package/template/springboot/src/main/resources/static/index.html +238 -0
  83. package/template/vue/README.md +17 -7
  84. package/template/vue/_gitignore +1 -0
  85. package/template/vue/lzc-build.yml +31 -42
  86. package/template/vue/src/App.vue +36 -25
  87. package/template/vue/src/style.css +106 -49
  88. package/template/vue-minidb/README.md +34 -0
  89. package/template/vue-minidb/_gitignore +26 -0
  90. package/template/vue-minidb/index.html +13 -0
  91. package/template/vue-minidb/lzc-build.yml +48 -0
  92. package/template/vue-minidb/lzc-icon.png +0 -0
  93. package/template/vue-minidb/package.json +21 -0
  94. package/template/vue-minidb/public/vite.svg +1 -0
  95. package/template/vue-minidb/src/App.vue +206 -0
  96. package/template/vue-minidb/src/assets/vue.svg +1 -0
  97. package/template/vue-minidb/src/main.ts +5 -0
  98. package/template/vue-minidb/src/style.css +136 -0
  99. package/template/vue-minidb/src/vite-env.d.ts +1 -0
  100. package/template/vue-minidb/tsconfig.app.json +24 -0
  101. package/template/vue-minidb/tsconfig.json +7 -0
  102. package/template/vue-minidb/tsconfig.node.json +22 -0
  103. package/template/vue-minidb/vite.config.ts +10 -0
  104. /package/template/{vue → vue-minidb}/src/components/HelloWorld.vue +0 -0
@@ -0,0 +1,238 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Lazycat Golang Todo Template</title>
7
+ <style>
8
+ :root {
9
+ --bg-1: #f8fbff;
10
+ --bg-2: #ecf6ff;
11
+ --card: #ffffff;
12
+ --text: #142033;
13
+ --muted: #4e617b;
14
+ --line: #d8e4f2;
15
+ --brand: #0076d6;
16
+ --brand-2: #00a5a5;
17
+ }
18
+ * { box-sizing: border-box; }
19
+ body {
20
+ margin: 0;
21
+ min-height: 100vh;
22
+ display: grid;
23
+ place-items: center;
24
+ padding: 24px;
25
+ font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
26
+ background: radial-gradient(circle at top right, var(--bg-2), var(--bg-1) 42%);
27
+ color: var(--text);
28
+ }
29
+ .card {
30
+ width: min(920px, 100%);
31
+ background: var(--card);
32
+ border: 1px solid var(--line);
33
+ border-radius: 22px;
34
+ padding: 26px;
35
+ box-shadow: 0 18px 48px rgba(20, 32, 51, 0.08);
36
+ }
37
+ .tag {
38
+ margin: 0;
39
+ color: var(--brand);
40
+ font-weight: 700;
41
+ letter-spacing: .08em;
42
+ text-transform: uppercase;
43
+ font-size: .85rem;
44
+ }
45
+ h1 { margin: 10px 0 12px; font-size: clamp(1.8rem, 3.2vw, 2.7rem); }
46
+ p { margin: 0; color: var(--muted); }
47
+ .btns {
48
+ margin-top: 18px;
49
+ display: flex;
50
+ gap: 10px;
51
+ flex-wrap: wrap;
52
+ }
53
+ a {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ text-decoration: none;
58
+ border-radius: 10px;
59
+ padding: 10px 14px;
60
+ border: 1px solid var(--line);
61
+ color: var(--text);
62
+ font-weight: 600;
63
+ }
64
+ a.primary {
65
+ color: #fff;
66
+ border-color: transparent;
67
+ background: linear-gradient(135deg, var(--brand), var(--brand-2));
68
+ }
69
+ .panel {
70
+ margin-top: 22px;
71
+ border: 1px solid var(--line);
72
+ border-radius: 14px;
73
+ padding: 14px;
74
+ background: #fbfdff;
75
+ }
76
+ .sync-note {
77
+ margin-top: 8px;
78
+ font-size: .92rem;
79
+ }
80
+ .form {
81
+ margin-top: 12px;
82
+ display: flex;
83
+ gap: 10px;
84
+ }
85
+ .form input {
86
+ flex: 1;
87
+ border: 1px solid var(--line);
88
+ border-radius: 10px;
89
+ padding: 10px 12px;
90
+ min-width: 0;
91
+ }
92
+ button {
93
+ border: 1px solid var(--line);
94
+ border-radius: 10px;
95
+ padding: 9px 12px;
96
+ cursor: pointer;
97
+ background: #fff;
98
+ }
99
+ ul {
100
+ margin: 12px 0 0;
101
+ padding: 0;
102
+ list-style: none;
103
+ display: grid;
104
+ gap: 10px;
105
+ }
106
+ li {
107
+ border: 1px solid var(--line);
108
+ border-radius: 10px;
109
+ padding: 10px 12px;
110
+ display: flex;
111
+ justify-content: space-between;
112
+ align-items: center;
113
+ gap: 8px;
114
+ background: #fff;
115
+ }
116
+ label {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 8px;
120
+ }
121
+ .done {
122
+ text-decoration: line-through;
123
+ color: var(--muted);
124
+ }
125
+ .danger {
126
+ color: #a63e37;
127
+ }
128
+ @media (max-width: 640px) {
129
+ .form {
130
+ flex-direction: column;
131
+ }
132
+ li {
133
+ flex-direction: column;
134
+ align-items: flex-start;
135
+ }
136
+ }
137
+ </style>
138
+ </head>
139
+ <body>
140
+ <main class="card">
141
+ <p class="tag">Golang Version</p>
142
+ <h1>Todo demo powered by Go API</h1>
143
+ <p>
144
+ This template includes a Golang backend and a simple Todo app to help you start fast.
145
+ </p>
146
+
147
+ <div class="btns">
148
+ <a class="primary" href="https://lazycat.cloud/" target="_blank" rel="noreferrer">Visit lazycat.cloud</a>
149
+ <a href="https://developer.lazycat.cloud/" target="_blank" rel="noreferrer">Open Developer Docs</a>
150
+ </div>
151
+
152
+ <section class="panel">
153
+ <strong>Todo quick demo</strong>
154
+ <p class="sync-note">Data syncs automatically across devices when opened with the same app account.</p>
155
+ <div class="form">
156
+ <input id="todoInput" placeholder="Add a task for your app kickoff" />
157
+ <button id="addBtn" type="button">Add</button>
158
+ </div>
159
+ <ul id="todoList"></ul>
160
+ </section>
161
+ </main>
162
+ <script>
163
+ const todoInput = document.getElementById('todoInput');
164
+ const addBtn = document.getElementById('addBtn');
165
+ const todoList = document.getElementById('todoList');
166
+
167
+ async function fetchTodos() {
168
+ const resp = await fetch('/api/todos');
169
+ const data = await resp.json();
170
+ return Array.isArray(data.items) ? data.items : [];
171
+ }
172
+
173
+ function renderTodos(items) {
174
+ todoList.innerHTML = '';
175
+ for (const todo of items) {
176
+ const li = document.createElement('li');
177
+
178
+ const label = document.createElement('label');
179
+ const checkbox = document.createElement('input');
180
+ checkbox.type = 'checkbox';
181
+ checkbox.checked = !!todo.done;
182
+ checkbox.addEventListener('change', async () => {
183
+ await fetch(`/api/todos/${todo.id}/toggle`, { method: 'PUT' });
184
+ await refreshTodos();
185
+ });
186
+
187
+ const span = document.createElement('span');
188
+ span.textContent = todo.title;
189
+ if (todo.done) {
190
+ span.className = 'done';
191
+ }
192
+ label.append(checkbox, span);
193
+
194
+ const delBtn = document.createElement('button');
195
+ delBtn.type = 'button';
196
+ delBtn.className = 'danger';
197
+ delBtn.textContent = 'Delete';
198
+ delBtn.addEventListener('click', async () => {
199
+ await fetch(`/api/todos/${todo.id}`, { method: 'DELETE' });
200
+ await refreshTodos();
201
+ });
202
+
203
+ li.append(label, delBtn);
204
+ todoList.appendChild(li);
205
+ }
206
+ }
207
+
208
+ async function refreshTodos() {
209
+ const items = await fetchTodos();
210
+ renderTodos(items);
211
+ }
212
+
213
+ async function addTodo() {
214
+ const title = todoInput.value.trim();
215
+ if (!title) return;
216
+ await fetch('/api/todos', {
217
+ method: 'POST',
218
+ headers: { 'Content-Type': 'application/json' },
219
+ body: JSON.stringify({ title }),
220
+ });
221
+ todoInput.value = '';
222
+ await refreshTodos();
223
+ }
224
+
225
+ addBtn.addEventListener('click', addTodo);
226
+ todoInput.addEventListener('keyup', async (event) => {
227
+ if (event.key === 'Enter') {
228
+ await addTodo();
229
+ }
230
+ });
231
+
232
+ refreshTodos();
233
+ setInterval(refreshTodos, 2500);
234
+ document.addEventListener('visibilitychange', refreshTodos);
235
+ window.addEventListener('focus', refreshTodos);
236
+ </script>
237
+ </body>
238
+ </html>
@@ -0,0 +1,19 @@
1
+ # Lazycat GUI VNC App
2
+
3
+ ## First Deploy
4
+ ```bash
5
+ lzc-cli project deploy
6
+ lzc-cli project info
7
+ ```
8
+
9
+ Then open the app from launcher or browser.
10
+
11
+ ## Build LPK
12
+ ```bash
13
+ lzc-cli project release -f lzc-build.yml -o gui-vnc.lpk
14
+ ```
15
+
16
+ ## Install
17
+ ```bash
18
+ lzc-cli lpk install gui-vnc.lpk
19
+ ```
@@ -0,0 +1,2 @@
1
+ *.lpk
2
+ *.lpk.tar
@@ -0,0 +1,30 @@
1
+ FROM registry.lazycat.cloud/kasm-debian-bookworm:0.0.1
2
+
3
+ USER root
4
+
5
+ RUN usermod -l lazycat kasm-user \
6
+ && echo 'lazycat ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers \
7
+ && sed -i 's/kasm_user/lazycat/g' /dockerstartup/vnc_startup.sh \
8
+ && sed -i '5i sudo chown -R lazycat:kasm-user /home/lazycat/' /dockerstartup/kasm_default_profile.sh
9
+
10
+ RUN apt-get update \
11
+ && apt-get install -y --no-install-recommends x11-apps \
12
+ && rm -rf /var/lib/apt/lists/*
13
+
14
+ RUN chown -R lazycat:kasm-user /home/kasm-default-profile \
15
+ && chmod -R u+rwX,g+rX /home/kasm-default-profile
16
+
17
+ ENV HOME=/home/lazycat
18
+ WORKDIR /home/lazycat
19
+
20
+ COPY --chown=lazycat:kasm-user kasmvnc.yaml /home/lazycat/.vnc/kasmvnc.yaml
21
+ COPY --chown=lazycat:kasm-user startup-script.sh /home/lazycat/.config/autostart/startup-script.sh
22
+ # Uncomment to enable autostart link creation for /lzcapp/documents.
23
+ # COPY --chown=lazycat:kasm-user startup-script.desktop /home/lazycat/.config/autostart/startup-script.desktop
24
+
25
+ RUN chmod +x /home/lazycat/.config/autostart/startup-script.sh
26
+
27
+ ENV VNCOPTIONS="-PreferBandwidth -disableBasicAuth -DynamicQualityMin=4 -DynamicQualityMax=7 -DLP_ClipDelay=0 -sslOnly=0"
28
+ ENV VNC_PW=lazycat
29
+
30
+ USER lazycat
@@ -0,0 +1,33 @@
1
+ network:
2
+ ssl:
3
+ pem_certificate: ${HOME}/.vnc/self.pem
4
+ pem_key: ${HOME}/.vnc/self.pem
5
+ require_ssl: false
6
+ udp:
7
+ public_ip: 127.0.0.1
8
+
9
+ runtime_configuration:
10
+ allow_override_standard_vnc_server_settings: false
11
+ allow_client_to_override_kasm_server_settings: false
12
+ allow_override_list: []
13
+
14
+ encoding:
15
+ max_frame_rate: 60
16
+ full_frame_updates: 60
17
+
18
+ video_encoding_mode:
19
+ jpeg_quality: -1
20
+ webp_quality: -1
21
+ max_resolution:
22
+ width: 1920
23
+ height: 1080
24
+ scaling_algorithm: progressive_bilinear
25
+
26
+ compare_framebuffer: off
27
+ zrle_zlib_level: 0
28
+ hextile_improved_compression: false
29
+
30
+ desktop:
31
+ gpu:
32
+ hw3d: false
33
+ drinode: /dev/dri/renderD128
@@ -0,0 +1,9 @@
1
+ [Desktop Entry]
2
+ Type=Application
3
+ Version=1.0
4
+ Name=Lazycat Startup Links
5
+ Comment=Create desktop links for LPK runtime paths
6
+ Exec=/home/lazycat/.config/autostart/startup-script.sh
7
+ Terminal=false
8
+ X-GNOME-Autostart-enabled=true
9
+ NoDisplay=true
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ mkdir -p /home/lazycat/Desktop
5
+
6
+ ln -svfn /lzcapp/documents "/home/lazycat/Desktop/Documents (ReadWrite)"
@@ -0,0 +1,23 @@
1
+ # 可选基础文件: lzc-build.base.yml(与当前文件同目录,先加载再与当前文件合并)
2
+
3
+ # manifest: 指定 lpk 的 manifest 文件
4
+ manifest: ./lzc-manifest.yml
5
+
6
+ # contentdir: 需要打包进 lpk 的目录
7
+ contentdir: ./
8
+
9
+ # pkgout: lpk 输出目录
10
+ pkgout: ./
11
+
12
+ # icon: 应用图标(png)
13
+ icon: ./lzc-icon.png
14
+
15
+ # images: 构建容器镜像并写入 lpk v2 的 images 目录
16
+ images:
17
+ app-runtime:
18
+ # context: Docker 构建上下文目录
19
+ context: ./images
20
+ # dockerfile: 镜像构建文件
21
+ dockerfile: ./images/Dockerfile
22
+ # upstream-match: 上游镜像前缀,用于层拆分(upstream/embed)
23
+ upstream-match: registry.lazycat.cloud
Binary file
@@ -0,0 +1,15 @@
1
+ FROM registry.lazycat.cloud/lzc/lzcapp:3.20.3
2
+
3
+ RUN apk add --no-cache python3 py3-pip
4
+ WORKDIR /app
5
+
6
+ COPY requirements.txt /app/requirements.txt
7
+ RUN pip3 install --no-cache-dir -r /app/requirements.txt --break-system-packages
8
+
9
+ COPY app.py /app/app.py
10
+ COPY run.sh /app/run.sh
11
+ RUN chmod +x /app/run.sh
12
+ COPY web /lzcapp/pkg/content/web
13
+
14
+ EXPOSE 3000
15
+ CMD ["python3", "/app/app.py"]
@@ -0,0 +1,33 @@
1
+ # Lazycat Python Todo App
2
+
3
+ ## First Deploy
4
+ ```bash
5
+ lzc-cli project deploy
6
+ lzc-cli project info
7
+ ```
8
+
9
+ Then open the app from launcher or browser.
10
+
11
+ ## API
12
+ ```text
13
+ GET /api/health
14
+ GET /api/todos
15
+ POST /api/todos
16
+ PUT /api/todos/{id}/toggle
17
+ DELETE /api/todos/{id}
18
+ ```
19
+
20
+ ## Data Path
21
+ ```text
22
+ /lzcapp/var/todos.json
23
+ ```
24
+
25
+ ## Build LPK
26
+ ```bash
27
+ lzc-cli project build -o python-app.lpk
28
+ ```
29
+
30
+ ## Install
31
+ ```bash
32
+ lzc-cli lpk install python-app.lpk
33
+ ```
@@ -0,0 +1,3 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
@@ -0,0 +1,110 @@
1
+ import json
2
+ import os
3
+ import time
4
+ from flask import Flask, send_from_directory, request
5
+
6
+ app = Flask(__name__, static_folder="/lzcapp/pkg/content/web", static_url_path="")
7
+ DATA_FILE = "/lzcapp/var/todos.json"
8
+ todos = []
9
+ next_id = 1
10
+
11
+
12
+ def now_ms():
13
+ return int(time.time() * 1000)
14
+
15
+ def load_todos():
16
+ global todos, next_id
17
+ os.makedirs(os.path.dirname(DATA_FILE), exist_ok=True)
18
+ if not os.path.exists(DATA_FILE):
19
+ return
20
+ with open(DATA_FILE, "r", encoding="utf-8") as fp:
21
+ raw = fp.read().strip()
22
+ if not raw:
23
+ return
24
+ loaded = json.loads(raw)
25
+ if not isinstance(loaded, list):
26
+ raise ValueError("todos data must be a list")
27
+ todos = loaded
28
+ max_id = 0
29
+ for item in todos:
30
+ if isinstance(item, dict):
31
+ max_id = max(max_id, int(item.get("id", 0)))
32
+ next_id = max_id + 1
33
+
34
+ def save_todos():
35
+ os.makedirs(os.path.dirname(DATA_FILE), exist_ok=True)
36
+ tmp_file = DATA_FILE + ".tmp"
37
+ with open(tmp_file, "w", encoding="utf-8") as fp:
38
+ json.dump(todos, fp, ensure_ascii=False, indent=2)
39
+ os.replace(tmp_file, DATA_FILE)
40
+
41
+ load_todos()
42
+
43
+
44
+ @app.get("/")
45
+ def index():
46
+ return send_from_directory(app.static_folder, "index.html")
47
+
48
+
49
+ @app.get('/api/health')
50
+ def health():
51
+ return {'status': 'ok'}
52
+
53
+
54
+ @app.get("/api/todos")
55
+ def list_todos():
56
+ sorted_todos = sorted(todos, key=lambda item: item["updatedAt"], reverse=True)
57
+ return {"items": sorted_todos}
58
+
59
+
60
+ @app.post("/api/todos")
61
+ def add_todo():
62
+ global next_id
63
+ payload = request.get_json(silent=True) or {}
64
+ title = str(payload.get("title", "")).strip()
65
+ if not title:
66
+ return {"error": "title is required"}, 400
67
+ todo = {
68
+ "id": next_id,
69
+ "title": title,
70
+ "done": False,
71
+ "updatedAt": now_ms(),
72
+ }
73
+ next_id += 1
74
+ todos.append(todo)
75
+ try:
76
+ save_todos()
77
+ except Exception:
78
+ return {"error": "failed to persist todos"}, 500
79
+ return todo
80
+
81
+
82
+ @app.put("/api/todos/<int:todo_id>/toggle")
83
+ def toggle_todo(todo_id):
84
+ for todo in todos:
85
+ if todo["id"] == todo_id:
86
+ todo["done"] = not todo["done"]
87
+ todo["updatedAt"] = now_ms()
88
+ try:
89
+ save_todos()
90
+ except Exception:
91
+ return {"error": "failed to persist todos"}, 500
92
+ return todo
93
+ return {"error": "todo not found"}, 404
94
+
95
+
96
+ @app.delete("/api/todos/<int:todo_id>")
97
+ def delete_todo(todo_id):
98
+ for index, todo in enumerate(todos):
99
+ if todo["id"] == todo_id:
100
+ todos.pop(index)
101
+ try:
102
+ save_todos()
103
+ except Exception:
104
+ return {"error": "failed to persist todos"}, 500
105
+ return {"ok": True}
106
+ return {"error": "todo not found"}, 404
107
+
108
+
109
+ if __name__ == '__main__':
110
+ app.run(host='0.0.0.0', port=3000)
@@ -0,0 +1,21 @@
1
+ # 可选基础文件: lzc-build.base.yml(与当前文件同目录,先加载再与当前文件合并)
2
+
3
+ # manifest: 指定 lpk 的 manifest 文件
4
+ manifest: ./lzc-manifest.yml
5
+
6
+ # contentdir: 需要打包进 lpk 的目录
7
+ contentdir: ./
8
+
9
+ # pkgout: lpk 输出目录
10
+ pkgout: ./
11
+
12
+ # icon: 应用图标(png)
13
+ icon: ./lzc-icon.png
14
+
15
+ # images: 构建容器镜像并写入 lpk v2 的 images 目录
16
+ images:
17
+ app-runtime:
18
+ # context: Docker 构建上下文目录
19
+ context: ./
20
+ # dockerfile: 镜像构建文件
21
+ dockerfile: ./Dockerfile
Binary file
@@ -0,0 +1 @@
1
+ flask==3.0.3
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ set -e
3
+ exec python3 /app/app.py