Release to your own machine

Run a controlled local release, check health, and practice stopping it.

Where do you want to run the labs?

Local machine instructions selected. You can switch at any time.

Switching changes the instructions only. Stop any exercise server or container yourself before starting the other route. Both routes use the same files and completion marks.

YOUR TASK · LOCAL MACHINE

Run the fixed API locally and check both an allowed request and a denied request.

Before you start

Node.js 24 and the fixed app.mjs from lab 02.

You’re finished when

Health returns ok, Alice gets 200, Bob gets 403, and you stop the server you started.

Go to step 1 ↓

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

  1. Terminal 1 · extracted starter folder

    Start the fixed server

    TERMINAL 1
    node 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 continuing

    Learning fixture listening on port 3000.

  2. 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 continuing

    The page displays {"status":"ok"}. This checks availability, not authorization.

  3. 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 2
    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 continuing

    200 followed by a record containing owner: alice and title: Alice note.

  4. Terminal 2

    Send Bob’s denied request

    TERMINAL 2
    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()))"

    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 continuing

    403 followed by { error: Forbidden }. Alice’s title must not be in the response.

  5. Terminal 2

    Verify the running API automatically

    TERMINAL 2
    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 continuing

    PASS with 4 checks. This checks this exercise, not production readiness.

  6. 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 continuing

    Terminal 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.

OWNER REQUEST
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()))"
OTHER USER
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()))"
CheckExpected result
GET /health200 with status: ok
Alice reads record 1200 with the synthetic Alice note
Bob reads record 1403 with an error, no title
Container health after startuphealthy
Stop your fixtureThe 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 happenedWhy it mattersWhat 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.

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?

Choose an answer
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 your results

Confirm both results before marking this lab complete.