Release to your own machine
Run a controlled local release, check health, and practice stopping it.
Need to set up your terminal or tools? · Look up a term
YOUR TASK · LOCAL MACHINE
Run the fixed API locally and check both an allowed request and a denied request.
Node.js 24 and the fixed app.mjs from lab 02.
Health returns ok, Alice gets 200, Bob gets 403, and you stop the server you started.
Do the exercise on your computer. This page provides instructions and saves completion marks; it does not run commands or check your files.
Follow these steps
Terminal 1 · extracted starter folder
Start the fixed server
TERMINAL 1node app.mjs
Leave this terminal open. While the server is running, it will not return to the command prompt. Use a second terminal for the requests below.
If you see
EADDRINUSE, another process is using port 3000. Stop only an earlier exercise server that you started, then retry.Check before continuingLearning fixture listening on port 3000.
Browser
Check that the server responds
Open http://127.0.0.1:3000/health in a new browser tab. Keep this lesson open too.
Check before continuingThe page displays {"status":"ok"}. This checks availability, not authorization.
Terminal 2 · extracted starter folder
Send Alice’s allowed request
Open another terminal in the same folder. Paste this whole command on one line and press Enter.
TERMINAL 2node -e "fetch('http://127.0.0.1:3000/records/1', {headers:{Authorization:'Bearer demo-alice'}}).then(async r=>console.log(r.status, await r.json()))"Check before continuing200 followed by a record containing owner: alice and title: Alice note.
Terminal 2
Send Bob’s denied request
TERMINAL 2node -e "fetch('http://127.0.0.1:3000/records/1', {headers:{Authorization:'Bearer demo-bob'}}).then(async r=>console.log(r.status, await r.json()))"If you get 200 with Alice’s note, the running app is still vulnerable. Stop it, save the fix from lab 02, and start it again.
Check before continuing403 followed by { error: Forbidden }. Alice’s title must not be in the response.
Terminal 2
Verify the running API automatically
TERMINAL 2node verify-lab.mjs release
The verifier checks health, anonymous denial, Alice’s allowed read, and Bob’s denied read. It contacts only your local exercise API. A NOT VERIFIED message means you should check the named failure before continuing.
Check before continuingPASS with 4 checks. This checks this exercise, not production readiness.
Terminal 1
Stop your exercise server
Return to Terminal 1 and press Ctrl+C. Refresh the health tab. It should no longer load from this process.
Check before continuingTerminal 1 returns to its command prompt. Your exercise server has stopped.
Why it works & help if you get stuck
CHECK THE RELEASE, NOT JUST THE PORT
Healthy is only the first question.
With the fixed app running, open a second terminal. Confirm a legitimate read still works and an unauthorized read is denied.
node -e "fetch('http://127.0.0.1:3000/records/1', {headers:{Authorization:'Bearer demo-alice'}}).then(async r=>console.log(r.status, await r.json()))"node -e "fetch('http://127.0.0.1:3000/records/1', {headers:{Authorization:'Bearer demo-bob'}}).then(async r=>console.log(r.status, await r.json()))"| Check | Expected result |
|---|---|
| GET /health | 200 with status: ok |
| Alice reads record 1 | 200 with the synthetic Alice note |
| Bob reads record 1 | 403 with an error, no title |
| Container health after startup | healthy |
| Stop your fixture | The process exits or the --rm container is removed |
For Docker, run docker inspect opsrung-lab --format "{{.State.Health.Status}}" from a second terminal. The check starts after five seconds and repeats every fifteen seconds, so allow a short startup period.
Finish the exercise: stop the fixture you started. For this local course, stopping and restarting the same verified artifact is the recovery practice. A production rollback also needs a retained previous artifact, configuration compatibility, and any database migration plan; this lab does not implement those.
IF YOUR RESULT IS DIFFERENT
Common wrong turns
| What happened | Why it matters | What to do instead |
|---|---|---|
| /health works but Bob gets 200. | Health does not validate record authorization. | Stop the stale server, rerun the tests, and restart the fixed version. |
| Port 3000 is already occupied. | Another process or earlier fixture owns the port. | Stop only your own fixture. Don’t terminate unrelated services. |
| Container is still “starting”. | The health interval has not elapsed. | Wait for the first health result; inspect its log if it becomes unhealthy. |
Need to set up your terminal or tools? · Look up a term
YOUR TASK · DOCKER
Run the fixed API locally and check both an allowed request and a denied request.
Docker and the fixed app from lab 02. Rebuild the image below so the running container includes your latest saved fix.
Health returns ok, Alice gets 200, Bob gets 403, and you stop the server you started.
Do the exercise on your computer. This page provides instructions and saves completion marks; it does not run commands or check your files.
Follow these steps
Terminal 1 · extracted starter folder
Build the fixed image and start the container
Run the build, then the run command. Leave Terminal 1 open after the listening message. Docker publishes the exercise on your own machine only.
TERMINAL 1docker build -t opsrung-lab:local . docker run --rm --name opsrung-lab -p 127.0.0.1:3000:3000 opsrung-lab:local
If the name is already in use, stop your previous exercise container with
docker stop opsrung-labin another terminal, then retry. If port 3000 is busy, stop an earlier exercise server you started.Check before continuingThe build passes its five tests, then prints Learning fixture listening on port 3000.
Browser
Check that the server responds
Open http://127.0.0.1:3000/health in a new browser tab. Keep this lesson open too.
Check before continuingThe page displays {"status":"ok"}. This checks availability, not authorization.
Terminal 2 · Docker
Send Alice’s allowed request
Run this in a second terminal on your computer. Docker runs the request inside the existing exercise container; no host Node.js is needed.
TERMINAL 2docker exec opsrung-lab node -e "fetch('http://127.0.0.1:3000/records/1', {headers:{Authorization:'Bearer demo-alice'}}).then(async r=>console.log(r.status, await r.json()))"Check before continuing200 followed by a record containing owner: alice and title: Alice note.
Terminal 2 · Docker
Send Bob’s denied request
Run this in a second terminal on your computer. Docker runs the request inside the existing exercise container; no host Node.js is needed.
TERMINAL 2docker exec opsrung-lab node -e "fetch('http://127.0.0.1:3000/records/1', {headers:{Authorization:'Bearer demo-bob'}}).then(async r=>console.log(r.status, await r.json()))"Check before continuing403 followed by { error: Forbidden }. Alice’s title must not be in the response.
Terminal 2
Verify the running API automatically
TERMINAL 2docker exec opsrung-lab node verify-lab.mjs release
The verifier checks health, anonymous denial, Alice’s allowed read, and Bob’s denied read. It contacts only your local exercise API. A NOT VERIFIED message means you should check the named failure before continuing.
Check before continuingPASS with 4 checks. This checks this exercise, not production readiness.
Terminal 2
Stop the exercise container
TERMINAL 2docker stop opsrung-lab
The foreground run in Terminal 1 exits too. Because it was started with
--rm, Docker removes this container after it stops. The image and your source files remain.Check before continuingThe command prints opsrung-lab. Terminal 1 returns to its prompt, and the health page no longer responds from this container.
TRY WITHOUT COPYING · OPTIONAL
Choose an address
A classmate’s browser cannot reach your service at 127.0.0.1:3000. Why? Should this local exercise be exposed just to make that address work for them?
Compare your reasoning
127.0.0.1 refers to the computer making the request. Their browser reaches their own machine. Keep the learning service local; this course does not require publishing it.
Explain your answer aloud or write a sentence before opening the explanation. This does not change your completion record.
A QUICK CHECK
What does a successful health check establish?
Compare with the solution +
Keep the review local: Node defaults to 127.0.0.1; the Docker command explicitly publishes to 127.0.0.1. The container listens on 0.0.0.0 internally so host port forwarding can reach it. No website publication is part of this lab.Docker port publishing ↗
Done with this one?
Marking complete is your own record.
Confirm both results before marking this lab complete.