Skip to content

Commit d5ff6c7

Browse files
committed
Initial content commit
1 parent 5311de1 commit d5ff6c7

20 files changed

Lines changed: 1339 additions & 160 deletions

.claude/commands/labspace-author.md

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ by updating the GitHub Actions publish workflow (`.github/workflows/publish.yml`
154154

155155
```yaml
156156
- name: Publish Labspace
157-
uses: dockersamples/publish-labspace-action@v1
157+
uses: dockersamples/publish-labspace-action@v2
158158
with:
159159
labspace_base_version: latest-sdlc # <-- add this line
160160
target_repo: ${{ env.DOCKERHUB_REPO }}
@@ -170,7 +170,8 @@ by updating the GitHub Actions publish workflow (`.github/workflows/publish.yml`
170170
| Deployed apps | `http://app.dockerlabs.xyz` | routed via Traefik |
171171
| Traefik dashboard | `http://localhost:8080` | — |
172172

173-
**CI/CD secrets automatically available in `moby/demo-app`:**
173+
**CI/CD secrets automatically available in `moby/demo-app` (unless `SKIP_CI_SECRET_SETUP` is set to
174+
`true` on the `workspace` service):**
174175

175176
| Secret | Value |
176177
|--------|-------|
@@ -181,6 +182,10 @@ by updating the GitHub Actions publish workflow (`.github/workflows/publish.yml`
181182
| `DOCKERHUB_PASSWORD` | from user's Docker Desktop |
182183
| `KUBECONFIG` | pre-generated k3s config |
183184

185+
**Note:** If the `SKIP_CI_SECRET_SETUP` environment variable is set on the `workspace` service, all
186+
CI secret setup will be skipped. Ideally, this is set in the lab's own `compose.override.yaml` file.
187+
This is helpful in labs in which the student is going to setup the CI secrets themselves.
188+
184189
The labspace project files are automatically committed to `moby/demo-app` at startup. If the project
185190
contains `.gitea/workflows/`, those workflows will automatically run after the initial push.
186191

@@ -359,7 +364,10 @@ graph TD
359364
1. **Stay focused** — Keep the labspace to 1–2 core takeaways. More content can always be a new
360365
labspace.
361366

362-
2. **Make it fun** — Use an engaging story or sample application. Creative emojis are encouraged!
367+
2. **Make it fun** — Use an engaging story or sample application. Emojis are encouraged, but use
368+
them with taste: a well-placed emoji adds color and personality; too many makes content feel
369+
cluttered and hard to scan. Good uses include section headings, callouts, and key moments of
370+
celebration or warning. Avoid sprinkling them into every sentence or bullet point.
363371

364372
3. **Empower the student** — Use second-person ("you"), never first-person plural ("we", "us",
365373
"let's", "our"):
@@ -387,6 +395,40 @@ graph TD
387395
8. **Verify the environment first** — The first section should always include a simple command
388396
that confirms the environment is working correctly.
389397

398+
9. **Use numbered steps for sequential exercises** — When students must perform a series of
399+
actions, use a numbered list with each code block indented (4 spaces) so it is nested inside
400+
its list item. This keeps the command visually tied to its step and makes progress easy to
401+
track. Never use a wall of text followed by disconnected code blocks for sequential actions.
402+
403+
When a step creates or updates a file, include the filename and intent in the step text so
404+
students have enough context to complete the action even without using the Save button:
405+
406+
- ✓ "Create a file named `compose.yaml` with the following contents:"
407+
- ✓ "Update `compose.yaml` to have the following content:"
408+
- ❌ "Create the file:" *(which file? what is it?)*
409+
410+
````markdown
411+
1. Create a file named `compose.yaml` with the following contents:
412+
413+
```yaml save-as=compose.yaml
414+
services:
415+
app:
416+
image: nginx
417+
```
418+
419+
2. Start it:
420+
421+
```bash
422+
docker compose up -d
423+
```
424+
425+
3. Check that it's running:
426+
427+
```bash
428+
docker ps
429+
```
430+
````
431+
390432
---
391433

392434
## Quality Checklist
@@ -403,6 +445,7 @@ Before finishing, verify:
403445
- [ ] For SDLC: the note about updating `.github/workflows/publish.yml` is communicated to the user
404446
- [ ] `project/` contains realistic starter files appropriate to the topic
405447
- [ ] No instruction or command references `project/` as a path prefix or tells the user to `cd project`
448+
- [ ] Every step that has users create or update a file clearly states the filename and intent (e.g. "Create a file named `compose.yaml` with the following contents:")
406449

407450
---
408451

.github/workflows/publish-labspace.yaml.temp renamed to .github/workflows/publish-labspace.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Package and deploy Labspace
22

33
env:
4-
DOCKERHUB_REPO: your-dockerhub-username/labspace-name
4+
DOCKERHUB_REPO: dockersamples/labspace-containerized-sdlc
55

66
on:
77
push:
@@ -25,4 +25,5 @@ jobs:
2525
- name: Publish Labspace
2626
uses: dockersamples/publish-labspace-action@v2
2727
with:
28+
labspace_base_version: latest-sdlc
2829
target_repo: ${{ env.DOCKERHUB_REPO }}

README.md

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,50 @@
1-
# Labspace starter
1+
# Labspace - Containerized SDLC
22

3-
This repository is intended to server as a template to help bootstrap a new Labspace.
3+
Build a real Node.js API, then containerize every stage of your software development lifecycle — local development, integration testing, CI/CD, and Kubernetes deployment.
44

5-
## Instructions
5+
## Learning objectives
66

7-
1. Create a new repository using this repo as the template ([docs here](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template)).
7+
This Labspace will have you do the following:
88

9-
**NOTE:** After creating the repo, a GHA workflow will run to do some additional bootstrapping. The bootstrapping workflow file will be removed during bootstrapping.
9+
- Set up a containerized development environment
10+
- Use Testcontainers to use containers in integration testing
11+
- Setup a CI/CD pipeline that will run your tests and build your image
12+
- Define Kubernetes manifest files
1013

11-
2. Clone your newly created repo to your local machine
14+
## Launch the Labspace
1215

13-
3. Start the local development mode:
16+
To launch the Labspace, run the following command:
1417

15-
```bash
16-
# On Mac/Linux
17-
CONTENT_PATH=$PWD docker compose up --watch
18+
```bash
19+
docker compose -f oci://dockersamples/labspace-containerized-sdlc up -d
20+
```
1821

19-
# On Windows with PowerShell
20-
$Env:CONTENT_PATH = (Get-Location).Path; docker compose up --watch
21-
```
22-
23-
4. Update the `labspace/labspace.yaml` with your Labspace's title and description
22+
And then open your browser to http://dockerlabs.xyz.
2423

25-
5. Write your Labspace! Being in dev mode, your changes should be visible in the interface without a restart. Feel free to edit either on your host machine or in the Labspace itself!
24+
### Using the Docker Desktop extension
2625

27-
Add any supporting application files or resources directly into the Labspace. This repo will be cloned into the Labspace at startup.
26+
If you have the Labspace extension installed (`docker extension install dockersamples/labspace-extension` if not), you can also [click this link](https://open.docker.com/dashboard/extension-tab?extensionId=dockersamples/labspace-extension&location=dockersamples/labspace-containerized-sdlc&title=Containerized%20SDLC%20Demo) to launch the Labspace.
2827

29-
Be sure to check out the [docs](https://github.com/dockersamples/labspace-infra/tree/main/docs) for additional information and guidelines.
28+
## Contributing
3029

30+
If you find something wrong or something that needs to be updated, feel free to submit a PR. If you want to make a larger change, feel free to fork the repo into your own repository.
3131

32+
**Important note:** If you fork it, you will need to update the GHA workflow to point to your own Hub repo.
3233

33-
### Setting up the deployment pipeline
34+
1. Clone this repo
3435

35-
The template repo contains a workflow file to make it easy to publish your Labspace.
36+
2. Start the Labspace in content development mode:
3637

37-
1. Add GitHub Action Secrets in your new repo for the following:
38+
```bash
39+
# On Mac/Linux
40+
CONTENT_PATH=$PWD docker compose up --watch
3841

39-
- `DOCKERHUB_USERNAME` - the username to authenticate to Docker Hub with
40-
- `DOCKERHUB_TOKEN` - a personal or organization access token to use for authentication
42+
# On Windows with PowerShell
43+
$Env:CONTENT_PATH = (Get-Location).Path; docker compose up --watch
44+
```
4145

42-
2. In the `.github/workflows/publish-labspace.yaml.temp` file, update the `DOCKERHUB_REPO` with the name of the Docker Hub repo you want to publish to.
46+
3. Open the Labspace at http://dockerlabs.xyz.
4347

44-
3. Rename the workflow file to remove the `.temp` extension.
48+
4. Make the necessary changes and validate they appear as you expect in the Labspace
4549

46-
```bash
47-
mv .github/workflows/publish-labspace.yaml.temp .github/workflows/publish-labspace.yaml
48-
```
50+
Be sure to check out the [docs](https://github.com/dockersamples/labspace-infra/tree/main/docs) for additional information and guidelines.

compose.override.yaml

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,7 @@ services:
33
environment:
44
PROJECT_CLONE_URL: https://github.com/dockersamples/labspace-containerized-sdlc
55

6-
# workspace:
7-
# # Override the default image if desired
8-
# # More details - https://github.com/dockersamples/labspace-infra/blob/main/docs/configuration.md#overriding-the-workspace-image
9-
# image: dockersamples/labspace-workspace-java
10-
11-
# # Override the default ports to publish additional ports you may need
12-
# # More details - https://github.com/dockersamples/labspace-infra/blob/main/docs/configuration.md#overriding-the-workspace-ports
13-
# ports: !override
14-
# - "6274:6274" # Expose the MCP inspector users will launch from inside the Labspace
15-
# - "8080:8080" # The port used by the app
16-
17-
# # Add other environment variables as needed
18-
# environment:
19-
# DANGEROUSLY_OMIT_AUTH: "true" # Skip auth for the MCP Inspector
20-
21-
# Add other models or services your Labspace may need
6+
workspace:
7+
image: dockersamples/labspace-workspace-node
8+
ports: !override
9+
- 8085:8085

compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
include:
2-
- oci://dockersamples/labspace-content-dev
2+
- oci://dockersamples/labspace-content-dev:dev-sdlc
33
- ./compose.override.yaml

labspace/01-introduction.md

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,71 @@
1-
# Introduction
1+
# Introduction: Meet the App
22

3-
👋 Welcome to the **Labspace starter** lab! During this lab, you will learn to do the following:
3+
Welcome to **The Containerized SDLC** lab! By the end, you'll have taken a real Node.js application from a bare source tree all the way through local development, automated testing, a CI/CD pipeline, and a live Kubernetes deployment — with containers playing a starring role at every step.
44

5-
- Learning Objective 1
6-
- Learning Objective 2
7-
- Learning Objective 3
8-
- Learning Objective 4
5+
## What you'll build
96

7+
**TaskFlow** is a simple task management REST API backed by PostgreSQL. The application code is already written and waiting for you. Your job is to containerize the *process* around it:
108

11-
## 🙋 What is a Labspace again?
9+
| Stage | What you'll do |
10+
|---|---|
11+
| 🖥️ **Local dev** | Write a `compose.yaml` to spin up a database and a visualizer |
12+
| 🧪 **Testing** | Write integration tests that use Testcontainers to start a real database |
13+
| 🔄 **CI/CD** | Write a Gitea Actions pipeline that tests, builds, and pushes a container image |
14+
| ☸️ **Deploy** | Write Kubernetes manifests and deploy to a live k3s cluster |
1215

13-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi sit amet auctor accumsan. Maecenas suscipit, libero quis ullamcorper pulvinar, dolor nisl vehicula orci, vel egestas arcu nibh eget enim.
16+
By the end, you'll see first-hand why a containerized SDLC makes software more portable, consistent, and reproducible.
1417

15-
Suspendisse potenti. Pellentesque eleifend eget ante eu egestas.
18+
## The SDLC journey
1619

17-
Nunc sit amet dapibus erat. Aliquam diam arcu, fringilla hendrerit metus sed, pellentesque fringilla lacus.
20+
```mermaid
21+
graph LR
22+
A[🖥️ Local Dev<br>Compose] --> B[🧪 Tests<br>Testcontainers]
23+
B --> C[🔄 CI/CD<br>Gitea Actions]
24+
C --> D[☸️ Deploy<br>Kubernetes]
25+
style A fill:#2563eb,color:#fff
26+
style B fill:#16a34a,color:#fff
27+
style C fill:#d97706,color:#fff
28+
style D fill:#9333ea,color:#fff
29+
```
1830

19-
Nulla ornare nulla risus. Curabitur ut ipsum euismod, accumsan lorem eu, pretium lorem. Fusce imperdiet fermentum hendrerit.
31+
## Tour the project
2032

33+
Start by confirming the environment is ready and getting familiar with the starter code.
2134

35+
1. Verify the key tools are available:
36+
37+
```bash
38+
node --version && docker --version && kubectl version --client --short 2>/dev/null || kubectl version --client
39+
```
40+
41+
2. List the project files:
42+
43+
```bash
44+
ls -la
45+
```
46+
47+
You should see `src/`, `package.json`, and `Dockerfile` — the core application that's ready to go.
48+
49+
3. Take a quick look at the API in the :fileLink[src/app.js]{path="src/app.js"} file. Specifically, the app:
50+
51+
- Exposes three endpoints: `GET /api/tasks`, `POST /api/tasks`, and `DELETE /api/tasks/:id`
52+
- Reads database connection details from environment variables (with sensible defaults)
53+
54+
4. Install the Node.js dependencies:
55+
56+
```bash
57+
npm install
58+
```
59+
60+
This installs Express and the PostgreSQL client (`pg`). It also generates a `package-lock.json` that you'll commit in a later section.
61+
62+
5. Try starting the app right now to see what happens without a database:
63+
64+
```bash
65+
node src/app.js
66+
```
67+
68+
> [!NOTE]
69+
> You'll see something like `Failed to start: connect ECONNREFUSED 127.0.0.1:5432`. The app can't connect to PostgreSQL because there isn't one running yet.
70+
71+
That error is exactly the problem you'll solve in the next section. The application needs a database, and the cleanest way to provide one — without installing anything on your machine — is Docker Compose.

0 commit comments

Comments
 (0)