前一篇帖子(云服务器下docker部署scrapyd)中介绍了如何把Scrapyd容器化,并部署在云服务器中。但是并没有添加用户验证,也就是说,如果该Scrapyd是可以任何人访问的,那么只要知道IP地址和端口,总会有人想拿它做坏事,比如我的服务器中就出现了以下的情况:

redis解决相对比较简单,只需要在redis.conf配置文件中添加一个较为复杂的密码即可,而Scrapyd出现这种情况有以下几种办法:
- 不允许外部访问;
- 对scrapyd源代码进行魔改;
- 在Scrapyd外添加Nginx作为反向代理
这里采用第三种解决办法(第一种称不上什么解决办法),相关配置文件见github
首先,大致捋一下思路,这里使用两个容器:Nginx和Scrapyd容器,他们之间通过docker的内部网络进行通信,而为了方便操作,这里使用的是docker-compose,首先,目录结构如下:
docker-compose.yml是dockerc-compose所需要的的文件,可以理解它是docker run命令的文件化;外层的Dockerfile负责scrapyd容器,nginx文件夹内的文件则负责Nginx容器;supervisor*.conf 则是supervisor的配置文件。
这里插一句,目前Scrapyd容器中药开启两个进程,分别是官方的Scrapyd进程和logparser进程,logparser负责整理日志并向外提供日志分析结果,该库的优点在于不用修改scrapyd而能对日志进行解析
在新版的scrapyd容器中,将由supervisor负责开启scrapyd进程和logparser进程。
接着我们打开docker-compose.yml:
version: "2.2"
services:
scrapyd:
build: .
image: scrapyd
volumes:
- .:/opt
nginx:
build: ./nginx
ports:
- "6800:6800"
links:
- "scrapyd:scrapyd"
我们创建了scrapyd镜像和nginx镜像,然后我们打开了nginx容器的6800端口,并可以让nginx容器可以访问到scrapyd容器。
然后是根目录下的Dockerfile文件:
FROM python:3.7
ENV REFRESHED_AT 2020-02-22
ENV PATH /usr/local/bin:$PATH
#add the scrapyd configure file
ADD ./scrapyd.conf /etc/scrapyd/scrapyd.conf
#add requirements.txt
ADD requirements.txt /opt/requirements.txt
WORKDIR /opt
#install scrapyd
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
# install logparser
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple logparser
# 安装supervisor
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple supervisor
# 拷贝配置文件
#拷贝supervisor、sshd、crond配置到相关目录
COPY supervisord.conf /etc/supervisor/
COPY supervisord_scrapyd.conf /etc/supervisor/
COPY supervisord_logparser.conf /etc/supervisor/
#设置容器启动时执行的命令
# ENTRYPOINT ["/usr/bin/supervisord", "-nc", "/etc/supervisor/supervisord.conf"]
ENTRYPOINT ["supervisord", "-nc", "/etc/supervisor/supervisord.conf"]
EXPOSE 6800
EXPOSE 6801
多的一部分是supervisor的安装、配置文件的赋值和启动命令的改变。supervisor的相关配置文件内容见github地址。
接着是nginx的Dockerfile文件:
FROM nginx
ADD default.conf /etc/nginx/conf.d/
ADD passwd /etc/nginx/
nginx使用的是官方镜像,这里仅仅把配置文件添加到相应的文件夹下即可。
passwd为linux下的htpasswd命令导出的一个关于账号和密码的字符串,网上提供了在线工具,打开该工具,比如账号为zhangsan,密码为lisi,那么生成的md5可能是下面的结果:
zhangsan:$apr1$m2btnlgu$YOfDkzstJHvYk8CpQDbdK0
把结果保存到passwd文件。接着是default.conf:
server {
listen 6800;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://scrapyd:6800; # 转发
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
auth_basic "Please input password";
auth_basic_user_file /etc/nginx/passwd;
}
}
nginx负责监听6800端口,并把请求转发给http://scrapyd:6800,同时开启了用户验证,只有满足验证的用户才可以访问真正的页面。
接着就可以在项目的根目录下进行镜像的创建和启动了:
docker-compose up
该命令会创建镜像(如果没有镜像的话),然后以前台的方式运行,此时访问对应的地址时,则会首先进行验证,如图:
如果使用requests进行发送scrapyd请求的话,可以使用:
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
详情见:身份认证