Below is a solution to debug Rider remotely inside a Docker container. The exact solution will depend on your specific environment and what kind of image you are building with Docker. The steps are generally going to be as follows:
- Download the appropriate JetBrains SSH agent inside your
Dockerfile
- Setup necessary permissions to run it (some images may not run as
root
)
- Create a wrapper
entrypoint
script that first executes the SSH agent, and then executes your app.
- Set this
entrypoint
as the default ENTRYPOINT
or CMD
in your Dockerfile
- Run the image, forwarding the necessary debugger port
From there, the steps are the same as any other remote SSH connection.
Assume you have a Dockerfile
building your app on ubuntu
:
Dockerfile
FROM ubuntu:18.04
WORKDIR /usr/local/app
# Copy required files including entrypoint wrapper
COPY entrypoint.sh /usr/local/bin/
RUN apt-get update && apt-get install -y curl
RUN \
# replace with the appropriate arch as needed
curl -L "https://download.jetbrains.com/rider/ssh-remote-debugging/linux-x64/jetbrains_debugger_agent_20230319.24.0" \
-o /usr/local/bin/debugger && \
chmod +x /usr/local/bin/debugger
# debugging port
EXPOSE 7777
# expose your actual application ports e.g.
# EXPOSE 80
ENTRYPOINT ["entrypoint.sh"]
entrypoint.sh
#!/usr/bin/env bash
/usr/local/bin/debugger -port 7777 &
# execute your actual application next
# e.g. `node index.js`
sleep 1d
Next, build the image including your application with debugging symbols enabled:
$ docker build -t jetdebug .
[+] Building 13.2s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 532B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:18.04 0.0s
=> [1/5] FROM docker.io/library/ubuntu:18.04 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 170B 0.0s
=> CACHED [2/5] WORKDIR /usr/local/app 0.0s
=> [3/5] COPY entrypoint.sh /usr/local/bin/ 0.0s
=> [4/5] RUN apt-get update && apt-get install -y curl 10.7s
=> [5/5] RUN curl -L "https://download.jetbrains.com/rider/ssh-remote-debugging/linux-x64/jetbrains_debugger_agent_20230319.24.0" -o /usr/local/bin/debugger && chmod +x /usr/local/bin/debugger 2.3s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:b98a6356808dd97fe1222892914305fcf1f47e709ac68bde41077a8a24769563 0.0s
=> => naming to docker.io/library/jetdebug
Finally, start the container:
$ docker run --rm -i -p7777:7777 jetdebug
Using host key fingerprint SHA256:ietD1qIhLzcDNcmH/dm2kp6us1j8QRa4yErNhn7vAYo
Please use these credentials to establish SSH connection:
Login: root
Password: ajpOUbr7dNLIp1gy
Port: 7777
Copy the three lines above and switch to Rider: it will detect the credentials in the clipboard and suggest adding a new remote host configuration with these login, password, and port.
Note: you will still need to specify the host name manually.
Note that -p7777:7777
flag specifies forwarding port 7777
when running the container. If you are doing this on a separate server, you may need to change firewall settings to further allow access to the port remotely.
We can see now on the host that port 7777
is forwarded correctly to the debugging SSH agent:
$ nc -v localhost 7777
Connection to localhost (127.0.0.1) 7777 port [tcp/*] succeeded!
SSH-2.0-Go
^C
From here, you can connect remotely as per normal in Rider.
If your application uses a different base Docker image, the steps are the same, but may need to be adjusted for the OS and architecture involved.
The entrypoint
logic can obviously be written in any language.
Also note that this setup contains several anti-patterns and would never be recommended for any kind of production deployment. Besides the fact that debugging symbols should never be in production code, containers should only contain one concern and the debugging SSH process is not monitored by the docker
process in the case it should unexpectedly crash.