I container Docker spesso richiedono accesso a risorse esterne tramite proxy — per il parsing, test da diverse regioni o per aggirare restrizioni. Una configurazione errata del proxy porta a errori di connessione, perdite dell'IP reale e malfunzionamenti delle applicazioni. In questo articolo esamineremo tutti i modi per configurare i proxy in Docker: da semplici variabili d'ambiente a scenari avanzati con docker-compose e reti personalizzate.
Perché sono necessari i proxy nei container Docker
I container Docker vengono utilizzati in vari scenari in cui i proxy diventano una necessità. Esaminiamo le principali attività che i proxy risolvono nelle applicazioni containerizzate.
Parsing e raccolta dati: Se esegui parser in container Docker per raccogliere dati da marketplace (Wildberries, Ozon), social media o motori di ricerca, i proxy proteggono da blocchi per IP. I container consentono di scalare il parsing — eseguire 10-50 istanze contemporaneamente, ciascuna con il proprio proxy.
Test da diverse regioni: Durante lo sviluppo di applicazioni web o API mobili è spesso necessario verificare come il servizio funzioni da diversi paesi. I container Docker con proxy di diverse geolocalizzazioni consentono di automatizzare tali test nel pipeline CI/CD.
Automazione e bot: I container con Selenium, Puppeteer o Playwright per l'automazione dei browser richiedono proxy per lavorare con più account. Ogni container riceve il proprio proxy e un ambiente isolato.
Superamento delle restrizioni aziendali: In alcune infrastrutture, i container Docker devono passare attraverso un proxy aziendale per accedere a Internet. Senza una configurazione corretta, i container non saranno in grado di scaricare pacchetti o accedere a API esterne.
Importante: I container Docker ereditano le impostazioni di rete del sistema host, ma i proxy devono essere configurati esplicitamente. La semplice presenza di un proxy sull'host non significa che i container lo utilizzino automaticamente.
Configurazione di base tramite variabili d'ambiente
Il modo più semplice per configurare un proxy in un container Docker è passare le variabili d'ambiente al momento dell'avvio. Questo metodo funziona per la maggior parte delle applicazioni che rispettano le variabili standard HTTP_PROXY, HTTPS_PROXY e NO_PROXY.
Avvio del container con proxy tramite docker run:
docker run -d \
-e HTTP_PROXY="http://username:password@proxy.example.com:8080" \
-e HTTPS_PROXY="http://username:password@proxy.example.com:8080" \
-e NO_PROXY="localhost,127.0.0.1,.local" \
your-image:latest
Spiegazione dei parametri:
HTTP_PROXY— proxy per le richieste HTTPHTTPS_PROXY— proxy per le richieste HTTPS (usa http://, non https://)NO_PROXY— elenco degli indirizzi che non devono passare attraverso il proxy
Esempio con proxy SOCKS5:
docker run -d \
-e HTTP_PROXY="socks5://username:password@proxy.example.com:1080" \
-e HTTPS_PROXY="socks5://username:password@proxy.example.com:1080" \
your-image:latest
Errore comune: Utilizzare https:// nell'URL del proxy per HTTPS_PROXY. È corretto specificare http:// o socks5://, anche per il traffico HTTPS. Il protocollo nell'URL indica il tipo di server proxy, non il tipo di traffico.
Configurazione del proxy per il daemon Docker (influisce su tutti i container):
Se hai bisogno che tutti i container utilizzino il proxy per impostazione predefinita, configura il daemon Docker. Crea un file /etc/systemd/system/docker.service.d/http-proxy.conf:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=http://proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.local"
Dopo le modifiche, riavvia Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
Configurazione del proxy nel Dockerfile
Quando costruisci un'immagine Docker che deve scaricare pacchetti tramite un proxy (ad esempio, apt-get, pip, npm), è necessario configurare il proxy durante la fase di costruzione. Docker supporta argomenti di build-time per questo.
Esempio di Dockerfile con supporto per proxy:
FROM python:3.11-slim
# Argomenti per il proxy (passati durante la costruzione)
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
# Impostazione delle variabili d'ambiente per la costruzione
ENV HTTP_PROXY=${HTTP_PROXY}
ENV HTTPS_PROXY=${HTTPS_PROXY}
ENV NO_PROXY=${NO_PROXY}
# Installazione delle dipendenze tramite proxy
RUN apt-get update && apt-get install -y curl
# Installazione dei pacchetti Python
COPY requirements.txt .
RUN pip install --proxy ${HTTP_PROXY} -r requirements.txt
# Copia dell'applicazione
COPY . /app
WORKDIR /app
# Rimozione delle variabili del proxy per il runtime (opzionale)
ENV HTTP_PROXY=
ENV HTTPS_PROXY=
CMD ["python", "app.py"]
Costruzione dell'immagine passando il proxy:
docker build \
--build-arg HTTP_PROXY=http://proxy.example.com:8080 \
--build-arg HTTPS_PROXY=http://proxy.example.com:8080 \
--build-arg NO_PROXY=localhost,127.0.0.1 \
-t my-app:latest .
Per le applicazioni Node.js (npm tramite proxy):
FROM node:18-alpine
ARG HTTP_PROXY
ARG HTTPS_PROXY
# Configurazione di npm per funzionare tramite proxy
RUN npm config set proxy ${HTTP_PROXY}
RUN npm config set https-proxy ${HTTPS_PROXY}
COPY package*.json ./
RUN npm install
# Pulizia delle impostazioni del proxy per npm
RUN npm config delete proxy
RUN npm config delete https-proxy
COPY . .
CMD ["node", "server.js"]
Consiglio: Se il proxy è necessario solo per la costruzione e non per l'esecuzione dell'applicazione, pulisci le variabili d'ambiente alla fine del Dockerfile. Questo previene la fuoriuscita accidentale delle credenziali nei log del container.
Configurazione del proxy in docker-compose.yml
Docker Compose semplifica la gestione dei proxy per applicazioni multi-container. Puoi configurare il proxy globalmente o per singoli servizi.
Configurazione di base con proxy per un servizio:
version: '3.8'
services:
parser:
image: python:3.11-slim
environment:
- HTTP_PROXY=http://username:password@proxy.example.com:8080
- HTTPS_PROXY=http://username:password@proxy.example.com:8080
- NO_PROXY=localhost,127.0.0.1,db
volumes:
- ./app:/app
working_dir: /app
command: python parser.py
db:
image: postgres:15
# Il database non utilizza il proxy
environment:
- POSTGRES_PASSWORD=secret
Utilizzo di un file .env per la memorizzazione sicura delle credenziali:
Crea un file .env nella directory con docker-compose.yml:
PROXY_URL=http://username:password@proxy.example.com:8080
NO_PROXY=localhost,127.0.0.1
Riferisciti alle variabili in docker-compose.yml:
version: '3.8'
services:
parser:
image: python:3.11-slim
environment:
- HTTP_PROXY=${PROXY_URL}
- HTTPS_PROXY=${PROXY_URL}
- NO_PROXY=${NO_PROXY}
volumes:
- ./app:/app
working_dir: /app
command: python parser.py
Configurazione del proxy per la costruzione dell'immagine in docker-compose:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
- HTTP_PROXY=${PROXY_URL}
- HTTPS_PROXY=${PROXY_URL}
- NO_PROXY=${NO_PROXY}
environment:
- HTTP_PROXY=${PROXY_URL}
- HTTPS_PROXY=${PROXY_URL}
ports:
- "3000:3000"
Scalabilità con proxy diversi per ogni istanza:
Se hai bisogno di eseguire più parser, ciascuno con il proprio proxy, utilizza servizi separati:
version: '3.8'
services:
parser-1:
image: my-parser:latest
environment:
- PROXY_URL=http://user:pass@proxy1.example.com:8080
volumes:
- ./data:/data
parser-2:
image: my-parser:latest
environment:
- PROXY_URL=http://user:pass@proxy2.example.com:8080
volumes:
- ./data:/data
parser-3:
image: my-parser:latest
environment:
- PROXY_URL=http://user:pass@proxy3.example.com:8080
volumes:
- ./data:/data
Configurazione del proxy a livello di applicazione
Alcune applicazioni non supportano le variabili d'ambiente standard HTTP_PROXY. In questi casi, è necessario configurare il proxy nel codice dell'applicazione o nei file di configurazione.
Python (libreria requests):
import os
import requests
# Ottenere il proxy dalla variabile d'ambiente
proxy_url = os.getenv('PROXY_URL', 'http://proxy.example.com:8080')
proxies = {
'http': proxy_url,
'https': proxy_url
}
# Utilizzare il proxy nelle richieste
response = requests.get('https://api.example.com/data', proxies=proxies)
print(response.json())
# Per proxy SOCKS5 installa pip install requests[socks]
# proxies = {
# 'http': 'socks5://user:pass@proxy.example.com:1080',
# 'https': 'socks5://user:pass@proxy.example.com:1080'
# }
Python (aiohttp per richieste asincrone):
import os
import aiohttp
import asyncio
async def fetch_with_proxy():
proxy_url = os.getenv('PROXY_URL')
async with aiohttp.ClientSession() as session:
async with session.get(
'https://api.example.com/data',
proxy=proxy_url
) as response:
data = await response.json()
print(data)
asyncio.run(fetch_with_proxy())
Node.js (libreria axios):
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = process.env.PROXY_URL || 'http://proxy.example.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
axios.get('https://api.example.com/data', {
httpsAgent: agent
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error.message);
});
Node.js (modulo https integrato):
const https = require('https');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = process.env.PROXY_URL;
const agent = new HttpsProxyAgent(proxyUrl);
const options = {
hostname: 'api.example.com',
port: 443,
path: '/data',
method: 'GET',
agent: agent
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => data += chunk);
res.on('end', () => console.log(JSON.parse(data)));
});
req.on('error', (error) => console.error(error));
req.end();
Selenium con proxy in un container Docker:
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType
import os
proxy_url = os.getenv('PROXY_URL', 'proxy.example.com:8080')
# Configurazione del proxy per Chrome
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument(f'--proxy-server={proxy_url}')
# Per l'autenticazione usa un'estensione o un tunnel SSH
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://example.com')
print(driver.title)
driver.quit()
Puppeteer con proxy:
const puppeteer = require('puppeteer');
(async () => {
const proxyUrl = process.env.PROXY_URL || 'proxy.example.com:8080';
const browser = await puppeteer.launch({
args: [`--proxy-server=${proxyUrl}`],
headless: true
});
const page = await browser.newPage();
// Autenticazione per il proxy
await page.authenticate({
username: 'your-username',
password: 'your-password'
});
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
})();
Quale tipo di proxy scegliere per Docker
La scelta del tipo di proxy dipende dall'attività che la tua applicazione deve svolgere nel container Docker. Esaminiamo i principali scenari e raccomandazioni.
| Tipo di proxy | Quando utilizzare | Vantaggi | Svantaggi |
|---|---|---|---|
| Datacenter | Parsing, richieste API, test | Alta velocità, basso costo, stabilità | Facilmente rilevabili, bloccati su siti protetti |
| Residenziali | Lavoro con social media, marketplace, siti complessi | IP reali, basso rischio di blocco, ampia geografia | Più costosi, più lenti dei datacenter, traffico limitato |
| Mobili | Test di API mobili, superamento di blocchi severi | Massima anonimato, IP degli operatori mobili | Prezzo elevato, geografia limitata |
Raccomandazioni per la scelta per compiti specifici:
Parsing di marketplace e cataloghi di prodotti: Se stai eseguendo il parsing di Wildberries, Ozon o altri marketplace tramite container Docker, utilizza proxy residenziali. Queste piattaforme bloccano attivamente gli IP dei datacenter. Configura la rotazione dei proxy ogni 5-10 minuti per simulare diversi utenti.
Test e sviluppo API: Per testare le proprie API o integrazioni con servizi esterni, sono adatti proxy dei datacenter. Offrono alta velocità e stabilità della connessione, che è importante per i test automatizzati nel CI/CD.
Automazione Selenium/Puppeteer: Quando esegui automazione del browser in container per lavorare con siti protetti (social media, banche, applicazioni web complesse), scegli proxy residenziali. Ridurranno la probabilità di CAPTCHA e blocchi.
Test geodistribuiti: Se hai bisogno di verificare la disponibilità del servizio da diversi paesi, utilizza proxy residenziali con scelta di geolocalizzazione specifica. Avvia più container Docker, ciascuno con il proxy del proprio paese.
Consiglio per la scalabilità: Quando avvii 10+ container con proxy, utilizza un pool di proxy con rotazione automatica. Questo semplifica la gestione e previene il riutilizzo di un singolo IP da parte di più container.
Risoluzione dei problemi comuni
Quando si lavora con proxy nei container Docker, si presentano problemi tipici. Esaminiamo i più comuni e i modi per risolverli.
Problema 1: Il container non riesce a connettersi al proxy
Sintomi: Errori "Connection refused", "Proxy connection failed", timeout durante l'avvio del container.
Soluzioni:
- Controlla la disponibilità del proxy dall'host:
curl -x http://proxy:port https://example.com - Assicurati che il server proxy sia accessibile dalla rete Docker. Se il proxy è su localhost dell'host, usa
host.docker.internal(Mac/Windows) o l'IP dell'host nella rete bridge - Controlla le regole del firewall — i container Docker potrebbero essere bloccati per le connessioni in uscita
- Per proxy con autenticazione, verifica la correttezza di username e password, esegui l'escape dei caratteri speciali nell'URL
Esempio di accesso al proxy sull'host:
# Mac/Windows
docker run -e HTTP_PROXY=http://host.docker.internal:8080 my-image
# Linux (scopri l'IP dell'host nella rete bridge)
ip addr show docker0 # Di solito 172.17.0.1
docker run -e HTTP_PROXY=http://172.17.0.1:8080 my-image
Problema 2: DNS non risolve tramite proxy
Sintomi: Errori "Could not resolve host", le richieste DNS non passano attraverso il proxy.
Soluzioni:
- Utilizza un proxy SOCKS5 invece di HTTP — SOCKS5 proxy le richieste DNS
- Configura DNS in Docker: aggiungi
--dns 8.8.8.8durante l'avvio del container - Per applicazioni che non supportano DNS tramite proxy, utilizza proxychains all'interno del container
# Dockerfile con proxychains
FROM python:3.11-slim
RUN apt-get update && apt-get install -y proxychains4
# Configurazione di proxychains
RUN echo "strict_chain\nproxy_dns\n[ProxyList]\nsocks5 proxy.example.com 1080" > /etc/proxychains4.conf
# Avvio dell'applicazione tramite proxychains
CMD ["proxychains4", "python", "app.py"]
Problema 3: Perdita dell'IP reale del container
Sintomi: Il servizio di destinazione vede l'IP dell'host o del container invece dell'IP del proxy.
Soluzioni:
- Controlla che l'applicazione stia effettivamente utilizzando il proxy — fai una richiesta a https://api.ipify.org
- Assicurati che tutti i client HTTP nel codice siano configurati per utilizzare il proxy
- Per connessioni WebRTC e WebSocket, il proxy potrebbe non funzionare — disabilita WebRTC nei browser
- Controlla le intestazioni delle richieste — alcune librerie aggiungono X-Forwarded-For con l'IP reale
Test di perdita dell'IP nel container:
# Senza proxy
docker run --rm curlimages/curl:latest curl https://api.ipify.org
# Con proxy
docker run --rm \
-e HTTPS_PROXY=http://proxy.example.com:8080 \
curlimages/curl:latest curl https://api.ipify.org
Problema 4: Lento funzionamento tramite proxy
Sintomi: Alte latenze, timeout, caricamento lento dei dati.
Soluzioni:
- Controlla la velocità del proxy direttamente dall'host — potrebbe esserci un problema con il proxy stesso
- Aumenta i timeout nell'applicazione per lavorare con proxy lenti
- Utilizza connessioni keep-alive per riutilizzare le connessioni TCP
- Per proxy residenziali, una velocità lenta è la norma, ottimizza il numero di richieste
- Configura un pool di connessioni nei client HTTP per richieste parallele
Problema 5: Il proxy funziona per HTTP, ma non per HTTPS
Sintomi: Le richieste HTTP passano, HTTPS restituiscono errori SSL/TLS.
Soluzioni:
- Assicurati che la variabile HTTPS_PROXY sia impostata (non solo HTTP_PROXY)
- Utilizza http:// nell'URL del proxy per HTTPS_PROXY, non https://
- Controlla se il proxy supporta il metodo CONNECT per il tunneling HTTPS
- Per proxy con certificati autofirmati, disabilita la verifica SSL (solo per test!)
Sicurezza e gestione delle credenziali
Memorizzare le credenziali del proxy nei container Docker richiede particolare attenzione alla sicurezza. Una gestione errata delle password può portare alla loro fuoriuscita nei log, nelle immagini o nei repository.
Utilizza Docker Secrets per la produzione:
Docker Swarm supporta un meccanismo di segreti per la memorizzazione sicura delle password. Crea un segreto:
echo "http://username:password@proxy.example.com:8080" | docker secret create proxy_url -
Utilizza in docker-compose per Swarm:
version: '3.8'
services:
app:
image: my-app:latest
secrets:
- proxy_url
environment:
- PROXY_URL_FILE=/run/secrets/proxy_url
command: sh -c 'export HTTP_PROXY=$(cat $$PROXY_URL_FILE) && python app.py'
secrets:
proxy_url:
external: true
Variabili d'ambiente tramite file (.env):
Per lo sviluppo, utilizza file .env, ma NON committarli mai in Git. Aggiungili a .gitignore:
# .gitignore
.env
.env.local
*.env
Crea .env.example senza credenziali reali:
# .env.example
PROXY_URL=http://username:password@proxy.example.com:8080
NO_PROXY=localhost,127.0.0.1
Evita di hardcodare le credenziali nelle immagini:
Pericoloso: Non scrivere mai le password direttamente nel Dockerfile usando ENV. Questi valori vengono memorizzati nei layer dell'immagine e sono accessibili anche dopo la rimozione.
# ❌ MALE - la password rimarrà nell'immagine
FROM python:3.11
ENV HTTP_PROXY=http://user:secretpass@proxy.com:8080
COPY . /app
# ✅ BENE - passa tramite argomenti di build o variabili runtime
FROM python:3.11
ARG HTTP_PROXY
# Utilizzato solo durante la costruzione, non memorizzato nell'immagine finale
Utilizza build multi-stage per pulire le credenziali:
# Fase di costruzione con proxy
FROM python:3.11 AS builder
ARG HTTP_PROXY
ENV HTTP_PROXY=${HTTP_PROXY}
COPY requirements.txt .
RUN pip install -r requirements.txt
# Fase finale senza variabili del proxy
FROM python:3.11-slim
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY . /app
WORKDIR /app
CMD ["python", "app.py"]
Rotazione delle credenziali del proxy:
Se il tuo fornitore di proxy supporta API per generare credenziali temporanee, utilizzale invece di password statiche. Crea uno script di init nel container:
#!/bin/bash
# entrypoint.sh
# Ottenere credenziali temporanee dall'API
PROXY_CREDS=$(curl -s https://api.proxyservice.com/generate-temp-auth)
export HTTP_PROXY="http://${PROXY_CREDS}@proxy.example.com:8080"
# Avvio dell'applicazione
exec python app.py
Logging senza fuoriuscita delle password:
Configura il logging in modo che le variabili con il proxy non vengano incluse nell'output:
import os
import re
def safe_log_env():
"""Logging delle variabili d'ambiente senza password"""
for key, value in os.environ.items():
if 'PROXY' in key:
# Maschera la password nell'URL
safe_value = re.sub(r'://([^:]+):([^@]+)@', r'://\1:****@', value)
print(f"{key}={safe_value}")
else:
print(f"{key}={value}")
safe_log_env()
Conclusione
Configurare i proxy nei container Docker è un'abilità importante per gli sviluppatori che lavorano con parsing, automazione e sistemi distribuiti. Hai imparato come configurare i proxy tramite variabili d'ambiente, Dockerfile e docker-compose, come integrare i proxy nel codice delle applicazioni in Python e Node.js, e come risolvere problemi tipici di connessione e sicurezza.
Punti chiave per un lavoro di successo con i proxy in Docker: utilizza variabili d'ambiente per flessibilità, memorizza le credenziali in modo sicuro tramite segreti o file .env, scegli il tipo di proxy in base al compito e testa sempre l'assenza di fuoriuscite dell'IP reale prima di avviare in produzione.
Per la maggior parte delle attività di parsing e automazione nei container Docker, ti consigliamo di utilizzare proxy residenziali — offrono alta anonimato e minimo rischio di blocchi quando si lavora con siti e API protetti. Se hai bisogno di massima velocità per testare API o compiti interni, dai un'occhiata ai proxy dei datacenter.