I have a directory apkmirror-scraper-compose with the following structure:
.
├── docker-compose.yml
├── privoxy
│ ├── config
│ └── Dockerfile
├── scraper
│ ├── Dockerfile
│ ├── newnym.py
│ └── requirements.txt
└── tor
└── Dockerfile
I'm trying to run the following docker-compose.yml:
version: '3'
services:
privoxy:
build: ./privoxy
ports:
- "8118:8118"
links:
- tor
tor:
build:
context: ./tor
args:
password: ""
ports:
- "9050:9050"
- "9051:9051"
scraper:
build: ./scraper
links:
- tor
- privoxy
where the Dockerfile for tor is
FROM alpine:latest
EXPOSE 9050 9051
ARG password
RUN apk --update add tor
RUN echo "ControlPort 9051" >> /etc/tor/torrc
RUN echo "HashedControlPassword $(tor --quiet --hash-password $password)" >> /etc/tor/torrc
CMD ["tor"]
that for privoxy is
FROM alpine:latest
EXPOSE 8118
RUN apk --update add privoxy
COPY config /etc/privoxy/config
CMD ["privoxy", "--no-daemon"]
where config consists of the two lines
listen-address 0.0.0.0:8118
forward-socks5 / tor:9050 .
and the Dockerfile for scraper is
FROM python:2.7-alpine
ADD . /scraper
WORKDIR /scraper
RUN pip install -r requirements.txt
CMD ["python", "newnym.py"]
where requirements.txt contains the single line requests. Finally, the program newnym.py is designed to simply test whether changing the IP address using Tor is working:
from time import sleep, time
import requests as req
import telnetlib
def get_ip():
IPECHO_ENDPOINT = 'http://ipecho.net/plain'
HTTP_PROXY = 'http://privoxy:8118'
return req.get(IPECHO_ENDPOINT, proxies={'http': HTTP_PROXY}).text
def request_ip_change():
tn = telnetlib.Telnet('tor', 9051)
tn.read_until("Escape character is '^]'.", 2)
tn.write('AUTHENTICATE ""\r\n')
tn.read_until("250 OK", 2)
tn.write("signal NEWNYM\r\n")
tn.read_until("250 OK", 2)
tn.write("quit\r\n")
tn.close()
if __name__ == '__main__':
dts = []
try:
while True:
ip = get_ip()
t0 = time()
request_ip_change()
while True:
new_ip = get_ip()
if new_ip == ip:
sleep(1)
else:
break
dt = time() - t0
dts.append(dt)
print("{} -> {} in ~{}s".format(ip, new_ip, int(dt)))
except KeyboardInterrupt:
print("Stopping...")
print("Average: {}".format(sum(dts) / len(dts)))
The docker-compose build builds successfully, but if I try docker-compose up, I get the following error message:
Creating network "apkmirrorscrapercompose_default" with the default driver
ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
I tried searching for help on this error message, but couldn't find any. What is causing this error?
I ran into this problem because I had OpenVPN running. As soon as I killed OpenVPN, docker-compose up fired right up, and the error disappeared.
I ran in this problem with OpenVPN working as well and I've found a solution where you should NOT stop/start OpenVPN server.
Idea that You should specify what exactly subnet you want to use. In docker-compose.yml write:
networks:
default:
driver: bridge
ipam:
config:
- subnet: 172.16.57.0/24
That's it. Now, default network will be used and if your VPN did not assign you something from 172.16.57.* subnet, you're fine.
I've seen it suggested docker may be at its maximum of created networks. The command docker network prune can be used to remove all networks not used by at least one container.
My issue ended up being, as Robert commented about: an issue with openvpn service openvpn stop 'solved' the problem.