> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Debugging

export const DisclaimerNix = () => <Tip>
    You can now use composable image to install runtimes and tools in your application container. To find out more, see the <a href="/docs/configure-apps/app-reference/composable-image">Composable image</a> topic.
  </Tip>;

<DisclaimerNix />

Effectively debugging web apps takes effort,
especially when an HTTP request goes through multiple layers before reaching your web app.
Follow the steps below to debug a specific app.

You can choose to debug in an environment deployed to Upsun
or with your app running locally but connected to deployed services.
In either case, make sure to debug in a preview environment.

For more general information, see how to [troubleshoot development](/docs/troubleshooting/general).

## 1. Create a new environment

Start by creating a new environment completely isolated from production but with the same data for debugging:

```bash theme={null}
upsun branch debug-branch
```

## 2. Get access

<Tabs>
  <Tab title="Remote">
    Access your app container via [SSH](/docs/development/ssh):

    ```bash theme={null}
    upsun ssh
    ```
  </Tab>

  <Tab title="Local">
    To access deployed apps and services, open tunnels to everything your app has relationships with:

    ```bash theme={null}
    upsun tunnel:open
    ```

    In the same terminal, set the relevant environment variables:

    ```bash theme={null}
    export PLATFORM_RELATIONSHIPS="$(upsun tunnel:info --encode)"
    export PORT=8888
    ```
  </Tab>
</Tabs>

## 3. Run your app in inspect mode

<Tabs>
  <Tab title="Remote">
    Stop the current process and restart it in inspect mode:

    ```bash theme={null}
    sv stop app
    node --inspect <START_FILE>
    ```
  </Tab>

  <Tab title="Local">
    In the same terminal as the previous step, run the following command:

    ```bash theme={null}
    node --inspect <START_FILE>
    ```
  </Tab>
</Tabs>

Replace `<START_FILE>` with the file defined for [your app's `start` command](/docs/languages/nodejs#4-start-your-app).

You get output something like this:

```bash theme={null}
Debugger listening on ws://127.0.0.1:9229/10701e5d-d627-4180-a967-d47a924c93c0
For help, see: https://nodejs.org/en/docs/inspector
Listening on port 8888
```

## 4. (If debugging remotely) Forward the debugger port locally

In another terminal, create an SSH tunnel that forwards to the 9229 port:

```bash theme={null}
ssh -N -L 9229:localhost:9229 $(upsun ssh --pipe)
```

## 5. Connect the debugger

You can now connect the debugger as if you were debugging a local application.
See examples with some common tools:

<Tabs>
  <Tab title="Using Chrome developer tools">
    Go to `chrome://inspect`.
    Find your running app under the `Remote Target` list.
    Click **inspect** to start the debugger.
  </Tab>

  <Tab title="Using Visual Studio Code">
    Use the `Node.js: Attach` debugger option.

    If you haven't created the option:

    1. On the **Run and Debug** tab, click `create a launch.json file`.
    2. Select `Node.js` as the environment.
    3. In the `configurations` array, start IntelliSense (usually <kbd>ctrl</kbd>+<kbd>space</kbd>).
    4. Select `Node.js: Attach`.
    5. Make sure the port is the same as in [step 4 above](#4-if-debugging-remotely-forward-the-debugger-port-locally).

    Once you have the option:

    In the **Run and Debug** tab, select `Attach` from the menu and click **Start Debugging** (the green arrow).

    See more on [Node.js debugging in Visual Studio Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging).
  </Tab>
</Tabs>

Now when you load the site at your deployed URL (if debugging remote) or localhost (if debugging locally),
the local debugger you've attached is called.

Set breakpoints:

<Tabs>
  <Tab title="Remote">
    In the JavaScript files from your remote site:
    On the **Run and Debug** tab under **Loaded Scripts** find `Attach: Remote Process` > `/app`.
  </Tab>

  <Tab title="Local">
    Directly in your source files.
  </Tab>
</Tabs>

## Other issues

### pm2 process manager blocks other processes

If you're using the [`pm2` process manager](https://github.com/unitech/pm2) to start your app from a script,
you might find it daemonizes itself and blocks other processes (such as backups) by constantly respawning.
This may happen even if you use the `--no-daemon` flag.

Instead of using a script, call `pm2 start` directly in your [`start` command](/docs/languages/nodejs#4-start-your-app).
