-
-
Notifications
You must be signed in to change notification settings - Fork 931
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: in docker debug support with delve (#1789)
- Loading branch information
Showing
5 changed files
with
253 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
FROM golang:1.16-buster | ||
ENV CGO_ENABLED 1 | ||
|
||
RUN apt-get update && apt-get install -y --no-install-recommends inotify-tools psmisc | ||
RUN go get github.com/go-delve/delve/cmd/dlv | ||
|
||
COPY script/debug-entrypoint.sh /entrypoint.sh | ||
|
||
VOLUME /dockerdev | ||
|
||
WORKDIR /dockerdev | ||
|
||
ENV DELVE_PORT 40000 | ||
ENV SERVICE_NAME service | ||
|
||
EXPOSE 8000 $DELVE_PORT | ||
|
||
ENTRYPOINT ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
version: '3.7' | ||
|
||
services: | ||
${SERVICE_NAME}: | ||
build: | ||
dockerfile: ./.docker/Dockerfile-debug | ||
ports: | ||
- ${REMOTE_DEBUGGING_PORT}:40000 | ||
security_opt: | ||
- apparmor=unconfined | ||
cap_add: | ||
- SYS_PTRACE | ||
volumes: | ||
- type: bind | ||
source: ${SERVICE_ROOT} | ||
target: /dockerdev | ||
read_only: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
--- | ||
id: debug-docker-delve-ory-kratos | ||
title: Debugging Ory Kratos in Docker with Delve | ||
--- | ||
|
||
Very often, there is a need to debug Kratos being deployed as a Docker image. To | ||
support this, Kratos ships with a couple of files: | ||
|
||
- The `Dockerfile-debug` file, which you can find in the `.docker` directory. | ||
- The `docker-compose.template.dbg` file, which you can find in the same | ||
directory. This file defines a template for a service, one would like to debug | ||
in Docker | ||
- and a supplementary `debug-entrypoint.sh` skript, located in the `script` | ||
directory. | ||
|
||
Actually, these files do not include any Kratos specifica and thus can be used | ||
for any Golang based project. As you already could infer, this support is meant | ||
to be used in a docker-compose setup as described below. You can however run it | ||
as a standalone Docker container as well. You can find some information on how | ||
to achieve this at the end of this document. | ||
|
||
## As part of a docker-compose setup | ||
|
||
Imagine you have the following project structure: | ||
|
||
- docker-compose - a directory containing your `docker-compose.yaml` file | ||
- kratos - a directory containing the Kratos code | ||
- kratos-frontend - a directory containing a frontend application for Kratos | ||
|
||
The `docker-compose.yml` mentioned above could look as follows: | ||
|
||
```yaml | ||
version: '3.7' | ||
|
||
volumes: | ||
postgres-db: | ||
|
||
services: | ||
postgresd: | ||
image: postgres:9.6 | ||
ports: | ||
- '5432:5432' | ||
volumes: | ||
- type: volume | ||
source: postgres-db | ||
target: /var/lib/postgresql/data | ||
read_only: false | ||
environment: | ||
- PGDATA=/var/lib/postgresql/data/pgdata | ||
- POSTGRES_PASSWORD=secret | ||
- POSTGRES_USER=kratos | ||
|
||
kratos-migrate: | ||
image: kratos | ||
build: | ||
context: ../kratos | ||
dockerfile: ./.docker/Dockerfile-build | ||
environment: | ||
- DSN=postgres://kratos:secret@postgresd:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4 | ||
volumes: | ||
- type: bind | ||
source: path-to-kratos-config | ||
target: /etc/config/kratos | ||
command: migrate sql -e --yes | ||
depends_on: | ||
- postgresd | ||
|
||
kratos: | ||
image: kratos | ||
build: | ||
context: ../kratos | ||
dockerfile: ./.docker/Dockerfile-build | ||
depends_on: | ||
- kratos-migrate | ||
ports: | ||
- '4433:4433' # public | ||
- '4434:4434' # admin | ||
command: serve -c /etc/config/kratos/kratos.yml --watch-courier --dev | ||
volumes: | ||
- type: bind | ||
source: path-to-kratos-config | ||
target: /etc/config/kratos | ||
|
||
kratos-frontend: | ||
image: kratos-frontend | ||
build: | ||
context: ../kratos-kratos-frontend | ||
dockerfile: ./Dockerfile | ||
env_file: | ||
- file-containing-all-required-configuration.env | ||
``` | ||
|
||
To enable debugging of Kratos without changing the above docker-compose file, | ||
you can do the following (from the docker-compose directory): | ||
|
||
```bash | ||
SERVICE_NAME=kratos SERVICE_ROOT=../kratos REMOTE_DEBUGGING_PORT=9999 envsubst < ../kratos/.docker/docker-compose.template.dbg \ | ||
> docker-compose.kratos.tmp | ||
docker-compose -f docker-compose.yaml -f docker-compose.kratos.tmp up --build -d kratos | ||
``` | ||
|
||
The first line will create an overwrite docker-compose file to have a debug | ||
configuration for the kratos service. The second line will start a debug | ||
container by | ||
|
||
- mounting your `kratos` directory into the resulting Docker container, | ||
- downloading Delve, | ||
- building Kratos inside the container, | ||
- starting it in Delve with the arguments, you've defined in your regular | ||
docker-compose file - in the example above, this would be | ||
`serve -c /etc/config/kratos/kratos.yml --watch-courier --dev` - and | ||
- watching for changes on any go file within the mounted code base. | ||
|
||
Each time you change a .go file, the Delve process will be stopped, Kratos will | ||
be recompiled and Delve will be started again. With other words, you'll have to | ||
re-connect with your debugger again after each change. | ||
|
||
As you can see from the above usage, the `docker-compose.template.dbg` template | ||
expects the following variables to be defined: | ||
|
||
- `SERVICE_ROOT` - the root directory of the service to be started in the debug | ||
mode. | ||
- `SERVICE_NAME` - the name of the service from the docker-compose file. | ||
- `REMOTE_DEBUGGING_PORT` - the host port, the Delve listening port should be | ||
exposed as. This is the port you should connect your remote debugger to. | ||
|
||
If you run docker-compose this way, the container run with debugging enabled | ||
will wait until the debugger connects. If your IDE supports remote debugging, | ||
set host to `localhost` and port to the value, you've used for | ||
`REMOTE_DEBUGGING_PORT` in your remote debugging configuration. | ||
|
||
## As a standalone Docker container | ||
|
||
If you just would like to start Kratos in a container in debug mode, you can | ||
just use the `Dockerfile-debug` file instead of the regular `Dockerfile`. Make | ||
however sure your build context in the root directory of Kratos and not the | ||
`.docker` directory. In your IDE the debug configuration has to reference that | ||
file. In addition, you'll have to expose the Delve service port 40000 under the | ||
port 8000, as well as the actual port of the service, you'll like to access from | ||
your host, configure the bind mounts and set the run options to | ||
`--security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/bin/bash | ||
|
||
FILE_CHANGE_LOG_FILE=/tmp/changes.log | ||
SERVICE_ARGS="$@" | ||
|
||
log() { | ||
echo "***** $1 *****" | ||
} | ||
|
||
init() { | ||
log "Initializing" | ||
truncate -s 0 ${FILE_CHANGE_LOG_FILE} | ||
tail -f ${FILE_CHANGE_LOG_FILE} & | ||
} | ||
|
||
build() { | ||
log "Building ${SERVICE_NAME} binary" | ||
go env -w GOPROXY="proxy.golang.org,direct" | ||
go mod download | ||
go build -gcflags "all=-N -l" -o /${SERVICE_NAME} | ||
} | ||
|
||
start() { | ||
log "Starting Delve" | ||
dlv --listen=:${DELVE_PORT} --headless=true --api-version=2 --accept-multiclient exec /${SERVICE_NAME} -- ${SERVICE_ARGS} & | ||
} | ||
|
||
restart() { | ||
build | ||
|
||
log "Killing old processes" | ||
killall dlv | ||
killall ${SERVICE_NAME} | ||
|
||
start | ||
} | ||
|
||
watch() { | ||
log "Watching for changes" | ||
inotifywait -e "MODIFY,DELETE,MOVED_TO,MOVED_FROM" -m -r ${PWD} | ( | ||
while true; do | ||
read path action file | ||
ext=${file: -3} | ||
if [[ "$ext" == ".go" ]]; then | ||
echo "$file" | ||
fi | ||
done | ||
) | ( | ||
WAITING="" | ||
while true; do | ||
file="" | ||
read -t 1 file | ||
if test -z "$file"; then | ||
if test ! -z "$WAITING"; then | ||
echo "CHANGED" | ||
WAITING="" | ||
fi | ||
else | ||
log "File ${file} changed" >> ${FILE_CHANGE_LOG_FILE} | ||
WAITING=1 | ||
fi | ||
done | ||
) | ( | ||
while true; do | ||
read TMP | ||
restart | ||
done | ||
) | ||
} | ||
|
||
# main part | ||
init | ||
build | ||
start | ||
watch |