这篇文章发表于 287 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

这里说的是直接给出docker环境的题目的情况,老是需要重新配调试环境是非常费时间和心态的一件事,但是很多时候题目和调试环境联系过于密切因而不得不在原先基础上整一个调试环境出来。这里简单说下一些环境的快速配法。

另外,建议整一个能科学上网的透明路由,免得老是要换源改原本的docker代码(折磨.jpg)。这一系列操作都完成之后,我发现自己效率提升了很多,做题时的心态也好了点(虽然还是菜的真实55555~),总之有点后悔为什么不早点出钱搞下自己的基础设施建设。

下文中出现的172.17.0.1docker0网卡中的IP地址。

PHP

这里安装Xdebug作为调试工具。

进入到带着php的docker环境里面,使用命令pecl install xdebug安装xdebug插件,一般会装上xdebug-3.1.2。如果没有pecl的话,就尝试安装——如果在ubuntu的容器里,可以像这样apt install php7.4-xml php7.4-dev这样直接省事地安装pecl软件。

然后你可以选择直接在php.ini文件中进行相关的修改,但是有时候会不太方便(有些比较特殊的环境不带php.ini而且一旦带了没改好就没法成功运行),我个人的建议是按照下面这样的方法改:

先来看看一些相关扩展文件的存放位置,

1
2
3
4
5
6
7
8
9
10
11
12
root@c81fe68f5baf:/usr/local/etc/php/conf.d# php --ini
Configuration File (php.ini) Path: /usr/local/etc/php
Loaded Configuration File: (none)
Scan for additional .ini files in: /usr/local/etc/php/conf.d
Additional .ini files parsed: /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini

root@c81fe68f5baf:/usr/local/etc/php/conf.d# cat docker-php-ext-sodium.ini
extension=sodium
root@c81fe68f5baf:/usr/local/etc/php/conf.d# find / -name xdebug.so 2>/dev/null
/usr/local/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so
root@c81fe68f5baf:/usr/local/etc/php/conf.d# ls /usr/local/lib/php/extensions/no-debug-non-zts-20190902/
opcache.so sodium.so xdebug.so

于是乎新建一个/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini文件,其中内容如下:

1
2
3
4
5
6
7
8
9
10
11
zend_extension = xdebug
xdebug.mode = debug
xdebug.log = /home/xdebug.log
xdebug.log_level = 7
xdebug.idekey = "PHPSTORM"
xdebug.remote_handler = "dbgp"
xdebug.remote_connect_back = 0
xdebug.client_host = 172.17.0.1
xdebug.start_with_request = yes
xdebug.client_port = 9001
xdebug.remote_log = /tmp/remote_xdebug.log

这时如果我们用php -m查看相关的模块就会发现xdebug已经在*[Zend Modules]*里面了。

这里可能有个大坑:如果你有两个config文件夹,比如/etc/php/7.4/cli/etc/php/7.4/fpm,就一定要修改那个运行网站时用到的config文件夹(一般来说是后者,这样的话你修改前者也仅仅是改PHP命令行的配置却不是改的网页,所以这种情况要改后者)。

如果你访问内容为<?php phpinfo();?>的网页时能够看到xdebug相关、配置正确的内容的话,说明以上步骤您已经成功了。

接着配置Phpstorm里面的内容,打开File->Settings...,按如下截图填写:

1

2

3

这些就不细说了,自己调整即可。

最后记得使用docker-compose restart或其他命令重启docker服务,不要把容器关掉,这样就白忙活了。

这一系列步骤完成后,就可以打开Phpstorm右上角的小电话愉快地进行调试了。

另外,如果你对某个PHP某个命令不是很熟悉的话,可以在docker容器里面安上psysh进行测试。安装的命令如下:

1
2
3
wget https://psysh.org/psysh
chmod +x psysh
./psysh

NodeJS

这个也相对比较简单。

只需要稍微调整下dockerfile或者docker-compose.yml的内容(当然也可能写在package.json里面),把原本其中的node app.js改成node --inspect=0.0.0.0:9229 app.js或者node --inspect-brk=0.0.0.0:9229 app.js,我一般使用前者,因为后者会先给断一下,对我来说没必要。

然后稍微配置下Phpstorm,其中的172.20.0.2就是运行着node的docker容器的ip地址。其他也就如图所示了。

4

这里的Remote URLs of local files (optional)基本上是不用指定的。

最后点击图上箭头所指的小甲虫运行即可。

打断点,访问相关的网页就应该能直接看到一些调试信息了。

Python

使用远程方法比较有通用性,如下图:

5

Configurations中所示,在Dockerfile里面加入pip install pydevd-pycharm~=213.6461.77,然后在那个入口的python文件那里填上:

1
2
import pydevd_pycharm
pydevd_pycharm.settrace('172.17.0.1', port=54444, stdoutToServer=True, stderrToServer=True)

并配置好Configurations中的IDE host namePortPath mappings即可。请先点击pycharm里面的小甲虫,然后再起docker容器,一般来说就能够成功连接上。

Java

不得不说,因为Java题基本上给的是jar包或者war包,所以配环境还是建议不要在Docker里面,太麻烦!以下内容不是很详细,仅供参考。

可以使用jd-gui反编译之后先调整下源码,比如说放在一个Maven框架下面,一定要留意文件夹的结构。有些jar包或者war包反编译之后没有pom.xml文件,所以需要自己配置里面的各种jar依赖包。因为我经常使用jd-gui,所以其反编译的依赖包都是.jar.src.zip这样的,可以提取其名字前缀然后尝试生成一些dependency信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import os, requests, json

dir_path = "."

search_url = "https://search.maven.org/solrsearch/select?wt=json&q=a:"
fails = []
for parent, dirnames, filenames in os.walk(dir_path):
for filename in filenames:
if filename[-12:] == ".jar.src.zip":
try:
name = filename[:-12]
sep_i = len(name) - name[::-1].index('-') - 1
package_name, package_version = name[:sep_i], name[sep_i + 1:]
r = requests.get(search_url + package_name)
loaded = json.loads(r.text)
groupid = loaded['response']['docs'][0]['g']

print("<dependency>")
print("<groupId>{}</groupId>".format(groupid))
print("<artifactId>{}</artifactId>".format(package_name))
print("<version>{}</version>".format(package_version))
print("</dependency>")
except:
fails.append(name)
continue
if len(fails) > 0:
print("[!] FAIL: " + str(fails))

这样肯定还是不够的,一些信息您甚至还需要后续的手动调整。以上都是我处理需要源码的依赖包时候的办法,其实如果不是特别重要的包的话,可以直接解压jar包或者war包然后再将其导入。

未完待续

其他环境有必要我会再丰富这篇文章的……