Як запустити `apt-get` у докер-файлі за проксі?


76

Я працюю на віртуальній машині (Ubuntu 13.10) з Docker (версія 0.8.1, збірка a1598d1). Я намагаюся створити образ за допомогою dockerfile. По- перше, я хочу , щоб оновити пакети (використовуючи код нижче - проксі обфусцірованний) , але apt-getраз з помилкою: Could not resolve 'archive.ubuntu.com'.

FROM ubuntu:13.10
ENV HTTP_PROXY <HTTP_PROXY>
ENV HTTPS_PROXY <HTTPS_PROXY>
RUN export http_proxy=$HTTP_PROXY
RUN export https_proxy=$HTTPS_PROXY
RUN apt-get update && apt-get upgrade

У хост-системі я також запустив наступне:

sudo HTTP_PROXY=http://<PROXY_DETAILS>/ docker -d &

Хост може працювати apt-getбез проблем.

Як я можу змінити файл docker, щоб він міг потрапляти на сервери ubuntu з контейнера?

Оновлення

Я запустив код у CentOS (змінивши FROM ubuntu:13.10на FROM centos), і він працював нормально. Здається, це проблема з Ubuntu.


Я щойно перевірив http-проксі в centos (оновлення yum) та в ubuntu: 13.10 (apt-get update). Обидва зображення працюють для мене, я навіть намагався видалити налаштування dns з контейнера, щоб протестувати проксі (він працює нормально без dns, як слід). Я використовую лише http_proxy (без https).
Іржі

Ви насправді маєте "<HTTP_PROXY>" у своєму Dockerfile чи це заповнювач?
Behe

У мене є фактичний проксі у файлі. Я просто не можу поділитися адресою.
Крістофер Луден,


Погляньте на цю статтю: Використання Docker за проксі-
сервером

Відповіді:


98

ОНОВЛЕННЯ :

Ви неправильно написали великі літери змінних середовища в ENV. Правильним є http_proxy. Вашим прикладом має бути:

FROM ubuntu:13.10
ENV http_proxy <HTTP_PROXY>
ENV https_proxy <HTTPS_PROXY>
RUN apt-get update && apt-get upgrade

або

FROM centos
ENV http_proxy <HTTP_PROXY>
ENV https_proxy <HTTPS_PROXY>
RUN yum update 

Всі змінні, зазначені в ENV, додаються до кожної команди RUN. Кожна команда RUN виконується у власному контейнері / середовищі, тому вона не успадковує змінні від попередніх команд RUN!

Примітка: Для цього не потрібно викликати демон Docker з проксі-сервером, хоча якщо ви хочете витягувати зображення тощо, вам також потрібно встановити проксі-сервер для docker deamon. Ви можете встановити проксі для демона в /etc/default/dockerUbuntu (це не впливає на налаштування контейнерів).


Крім того, це може статися у випадку, якщо ви запустили свій проксі на хості (тобто localhost, 127.0.0.1). Localhost на хості відрізняється від localhost в контейнері. У такому випадку вам потрібно використовувати інший IP (наприклад, 172.17.42.1), щоб прив’язати свій проксі до, або якщо ви прив’яжете до 0.0.0.0, ви можете використовувати 172.17.42.1 замість 127.0.0.1 для підключення з контейнера під часdocker build .

Ви також можете шукати приклад тут: Як швидко відновити докер-файл за допомогою кешу?


У мене немає проксі-сервера на хості. Це корпоративна довіреність, за якою я стою. Той самий код працює на CentOS (змінюючи FROMєдиний) з однаковими налаштуваннями проксі.
Крістофер Луден

3
З огляду на поточний стан Docker, схоже, ви повинні мати ENV http_proxy corporate-proxy.comсвій файл Docker. Це досить огидно, оскільки це означає, що ви не можете ділитися своїм Dockerfile з кимось, хто не входить до вашої компанії. Я щойно перевірив це, запустивши polipo у контейнері, намагаючись кешувати apt-get installкоманди для розробки Dockerfiles. Можливо, у майбутній версії Docker буде встановлена ​​якась магічна конфігурація iptables, яка дозволяє прозоро проксірувати HTTP-запити?
Тім Поттер

@TimPotter Я думаю, що це не так вже й погано (ніякої розширеної магії не потрібно). Вам потрібно налаштувати Polipo на хості з батьківським проксі ( polipo parentProxy=corporate-proxy.com) , а потім вам потрібно налаштувати прозорий проксі з допомогою IPTables: iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner <polipo-user> --dport 80 -j REDIRECT --to-port 8123.
Іржі

1
Я щойно склав проект, який забезпечує squid, що працює в контейнері, з відповідними командами iptables / ip rules для перенаправлення всього іншого контейнерного трафіку через контейнер squid для прозорого проксі-сервера. Це може бути корисно для того, що ви описуєте? silarsis.blogspot.com.au/2014/03/proxy-all-containers.html
KevinL

у вас є спосіб отримати налаштування http_proxy в демоні docker (/ etc / defailt / docker) з контейнера docker? тож я можу додати сценарій для введення в Dockerfile
Ларрі Кай

50

Оновлено 10.02.2018

Завдяки новій функції в опції --configdocker, вам більше не потрібно встановлювати проксі в Dockerfile. Ви можете мати той самий файл Docker, який буде використовуватися в корпоративному середовищі та поза ним.

--config string      Location of client config files (default "~/.docker")

або змінної середовища DOCKER_CONFIG

`DOCKER_CONFIG` The location of your client configuration files.

$ export DOCKER_CONFIG=~/.docker

https://docs.docker.com/engine/reference/commandline/cli/

https://docs.docker.com/network/proxy/

Я рекомендую встановити проксі з httpProxy, httpsProxy, ftpProxyта noProxy(Офіційний документ пропускає змінну, ftpProxyяка іноді корисна)

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://127.0.0.1:3001",
     "httpsProxy": "http://127.0.0.1:3001",
     "ftpProxy": "http://127.0.0.1:3001",
     "noProxy": "*.test.example.com,.example2.com"
   }
 }
}

Налаштуйте проксі-IP та порт, якщо потрібно, та збережіть у ~/.docker/config.json

Після того, як ви правильно його встановили, ви можете запустити збірку докера та запустити докер як зазвичай.

$ docker build -t demo . 

$ docker run -ti --rm demo env|grep -ri proxy
(standard input):http_proxy=http://127.0.0.1:3001
(standard input):HTTPS_PROXY=http://127.0.0.1:3001
(standard input):https_proxy=http://127.0.0.1:3001
(standard input):NO_PROXY=*.test.example.com,.example2.com
(standard input):no_proxy=*.test.example.com,.example2.com
(standard input):FTP_PROXY=http://127.0.0.1:3001
(standard input):ftp_proxy=http://127.0.0.1:3001
(standard input):HTTP_PROXY=http://127.0.0.1:3001

Стара відповідь (Знято з експлуатації)

Нижче налаштування в Dockerfile працює для мене. Я тестував в CoreOS, Vagrantі boot2docker. Припустимо, що проксі-порт є3128

В Centos:

ENV http_proxy=ip:3128 
ENV https_proxy=ip:3128

В Ubuntu:

ENV http_proxy 'http://ip:3128'
ENV https_proxy 'http://ip:3128'

Будьте обережні з форматом, у когось є http, у когось немає, хтось із єдиною квотою. якщо IP-адреса 192.168.0.193, тоді буде встановлено:

В Centos:

ENV http_proxy=192.168.0.193:3128 
ENV https_proxy=192.168.0.193:3128

В Ubuntu:

ENV http_proxy 'http://192.168.0.193:3128'
ENV https_proxy 'http://192.168.0.193:3128'

Якщо вам потрібно встановити проксі в coreos, наприклад, щоб витягнути зображення

cat /etc/systemd/system/docker.service.d/http-proxy.conf

[Service]
Environment="HTTP_PROXY=http://192.168.0.193:3128"

1
Можливо, вам доведеться додати налаштування проксі-сервера https, оскільки apt-get використовуватиме безпечні з'єднання. [Послуга] Середовище = "HTTP_PROXY = ваш-проксі-сервер: порт " HTTPS_PROXY = ваш-проксі-сервер: порт: 3128 "" NO_PROXY = localhost, 127.0.0.0 / 8 "
pharsfalvi

Зверніть увагу, що для Centos вам потрібно явно додати номер порту, навіть якщо це порт за замовчуванням 80: stackoverflow.com/a/46949277/1654763
Munchkin

1
Це спрацювало. Дякую за приклад. Docker docs про це не зрозуміло.
ToTenMilan

2
$DOCKER_CONFIGповинен вказувати на каталог, а не безпосередньо на config.jsonфайл
Якуб

43

Ви можете використовувати --build-arg опцію, коли хочете побудувати за допомогою файлу Docker.

З посилання на https://github.com/docker/docker/issues/14634 , див. Розділ "Створення за допомогою --build-arg з кількома HTTP_PROXY":

[root@pppdc9prda2y java]# docker build 
  --build-arg https_proxy=$HTTP_PROXY --build-arg http_proxy=$HTTP_PROXY 
  --build-arg HTTP_PROXY=$HTTP_PROXY --build-arg HTTPS_PROXY=$HTTP_PROXY 
  --build-arg NO_PROXY=$NO_PROXY  --build-arg no_proxy=$NO_PROXY -t java .

ПРИМІТКА. У власній системі переконайтеся, що ви встановили змінні середовища HTTP_PROXY та NO_PROXY.


Це неприємне обхідне рішення, для постійного налаштування слід використовувати Dockerfile, як @Reza Farshi наводив приклад
Paweł Smołka

18
Неприємний обхідний шлях? У деяких (більшості) випадків бажано, щоб ваш власний проксі не вписувався в зображення, якщо ваше зображення (наприклад) буде використовуватися людьми в інших частинах вашої компанії, які можуть стояти за іншим проксі.
вентолін

11

перед будь-якою командою apt-get у вашому Dockerfile ви повинні поставити цей рядок

COPY apt.conf /etc/apt/apt.conf

Не забувайте створювати apt.conf у тій самій папці, що і у вас Dockerfile , вміст файлу apt.conf має бути таким:

Acquire::socks::proxy "socks://YOUR-PROXY-IP:PORT/";
Acquire::http::proxy "http://YOUR-PROXY-IP:PORT/";
Acquire::https::proxy "http://YOUR-PROXY-IP:PORT/";

якщо ви використовуєте ім'я користувача та пароль для підключення до проксі-сервера, тоді apt.conf має виглядати так, як показано нижче:

Acquire::socks::proxy "socks://USERNAME:PASSWORD@YOUR-PROXY-IP:PORT/";
Acquire::http::proxy "http://USERNAME:PASSWORD@YOUR-PROXY-IP:PORT/";
Acquire::https::proxy "http://USERNAME:PASSWORD@YOUR-PROXY-IP:PORT/";

наприклад :

Acquire::https::proxy "http://foo:bar@127.0.0.1:8080/";

Де foo - це ім’я користувача, а бар - пароль.


apt взагалі не підтримує проксі SOCKS. Acquire::socks::proxyозначає встановити проксі-сервер для всіх URL-адрес, починаючи зі socksсхеми. Оскільки у вас sources.listнемає жодних socks://URL-адрес, цей рядок повністю ігнорується. Я надішлю редагування, щоб виправити це.
Ганс-Крістоф Штайнер

У вас є /etc/apt/apt.conf.d/<config>на jessie, так що Dockerfile COPYдиректива потребує оновлення тут.
Ain Tohvri

Це була єдина відповідь, яка працювала для мене (запуск Docker для Windows за корпоративним проксі).
Коннор Годдард,

8

Використовуйте --build-arg у змінній середовища нижнього регістру:

docker build --build-arg http_proxy=http://proxy:port/ --build-arg https_proxy=http://proxy:port/ --build-arg ftp_proxy=http://proxy:port --build-arg no_proxy=localhost,127.0.0.1,company.com -q=false .

5

Як пропонують інші відповіді, --build-argможливо рішення. У моєму випадку мені довелося додати --network=hostкрім --build-argопцій.

docker build -t <TARGET> --build-arg http_proxy=http://<IP:PORT> --build-arg https_proxy=http://<IP:PORT> --network=host .

Якщо це працює лише при використанні --network = host, це може бути проблемою з dnsmasq. Дивіться відповідь Wisbucky нижче. Після отримання належного dns в / etc / resolv, conf на хості, вам не потрібно буде --network = host
user2707671

4

Незначною альтернативою відповіді, яку надає @Reza Farshi (що в моєму випадку працює краще), є виведення налаштувань проксі для /etc/apt/apt.confвикористання echoчерез Dockerfile, наприклад:

FROM ubuntu:16.04

RUN echo "Acquire::http::proxy \"$HTTP_PROXY\";\nAcquire::https::proxy \"$HTTPS_PROXY\";" > /etc/apt/apt.conf

# Test that we can now retrieve packages via 'apt-get'
RUN apt-get update

Перевага цього підходу полягає в тому, що адреси проксі можна передавати динамічно під час побудови зображення, а не копіювати файл налаштувань з хосту.

напр

docker build --build-arg HTTP_PROXY=http://<host>:<port> --build-arg HTTPS_PROXY=http://<host>:<port> .

відповідно до docker build docs.


3

я мав ту саму проблему і знайшов інший невеликий обхідний шлях: у мене є скрипт провізора, який додається із середовища побудови докера. У сценарії я встановив змінну середовища залежно від перевірки пінгу:

Файл Docker:

ADD script.sh /tmp/script.sh
RUN /tmp/script.sh

script.sh:

if ping -c 1 ix.de ; then
    echo "direct internet doing nothing"
else
    echo "proxy environment detected setting proxy"
    export http_proxy=<proxy address>
fi

це все ще дещо грубо, але працювало для мене


Це працювало у вас? Я можу змусити сценарій працювати нормально, але змінні середовища доступні лише для сценарію. Такі речі, як apt-get, cURL та wget, в кінцевому підсумку не бачать змінних середовища.
Ryan J. McDonough

3

Якщо ви правильно налаштували проксі-сервери, але все ще не можете зв’язатися з Інтернетом, це може бути роздільна здатність DNS. Перевірте /etc/resolve.confна хост Ubuntu VM. Якщо він міститьnameserver 127.0.1.1 , це неправильно.

Запустіть ці команди на хост Ubuntu VM, щоб виправити це:

sudo vi /etc/NetworkManager/NetworkManager.conf
# Comment out the line `dns=dnsmasq` with a `#`

# restart the network manager service
sudo systemctl restart network-manager

cat /etc/resolv.conf

Тепер /etc/resolv.confмає бути дійсне значення для сервера імен, яке буде скопійовано контейнерами докера.


Дякую! Ця відповідь була надзвичайно корисною і, нарешті, допомогла мені почати pip installпрацювати з докером за проксі. Це насправді не те, що хотів ОП, але мені дуже допомогло! :)
colidyre

Те саме тут, дякую! Ось додаткова інформація про цю проблему: superuser.com/questions/681993/…
user2707671

1

Ми робимо ...

ENV http_proxy http://9.9.9.9:9999
ENV https_proxy http://9.9.9.9:9999

і в кінці dockerfile ...

ENV http_proxy ""
ENV https_proxy ""

На даний момент (поки докер не вводить збірки env vars), дозволяє проксі env vars використовуватись ТІЛЬКИ для збірки, не виставляючи їх

Альтернативою рішенню є НЕ будувати свої зображення локально за проксі-сервером, а дозволити Docker створювати ваші зображення для вас, використовуючи docker "автоматизовані збірки". Оскільки docker не будує зображення за вашим проксі, проблема вирішена. Приклад автоматизованої збірки доступний за адресою ...

https://github.com/danday74/docker-nginx-lua (репозиторій GITHUB)

https://registry.hub.docker.com/u/danday74/nginx-lua (репозиторій DOCKER, який спостерігає за репозитарієм github за допомогою автоматизованої збірки та виконує збірку докера при натисканні на головну гілку github)


Просто хотів зазначити, що, оскільки ці ENV-вари розміщені в КОЖНОМУ проміжному контейнері, зняття їх у кінці не приховає їх, і до них все одно можна отримати доступ досить легко. З того, що я бачив, безпечні варіанти роботи з конфіденційними даними висвітлюються у цьому випуску github
Squadrons

1

і якщо ви хочете встановити проксі для wget, ви повинні помістити ці рядки у ваш Dockerfile

ENV http_proxy YOUR-PROXY-IP:PORT/
ENV https_proxy YOUR-PROXY-IP:PORT/
ENV all_proxy YOUR-PROXY-IP:PORT/

1

Як зазначав Тім Поттер, встановлення проксі-сервера в dockerfile жахливо. Створюючи образ, ви додаєте проксі-сервер для вашої корпоративної мережі, але, можливо, ви використовуєте в хмарі або DMZ, де проксі-сервер не потрібен, або проксі-сервер відрізняється.

Крім того, ви не можете ділитися своїм зображенням з іншими людьми за межами вашої корпоративної компанії.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.