Use Docker with Proxy Servers Tutorial
Tags: docker, devops, tutorial, linux
Published: 2020-10-16 17:59:11

**If you ever tried to run Docker in a corporate network** then you know what I'm talking about. To prevent potential intrusions, infrastructure engineers force all internet traffic to go through proxy servers, sometimes making it extremely difficult to run even the simplest thing.

# Why should you read this article?
With this tutorial, you'll learn everything there is to know on how to configure proxies for Docker engine and containers!
- configure proxy servers in **Docker for Desktop**
- configure proxy servers with **Linux & Systemd**
- use proxy servers with **running containers**

Let's get started! 🚀

# Quick refresher: what is a Proxy server?
A proxy server is simply a server that sits in between your machine and the Internet, that can interact with the outside of your network on your behalf.

The main reasons why you would want to use a Proxy are the following:
- To **improve network performance** by caching internet content
- As an **additional layer of security** by implementing additional encryption, protect against DoS attacks, blacklist dangerous sites, and much more
- For **auditing and logging purposes**, many companies need to track *who and when* access mission-critical systems

# How Docker uses proxies
One thing that was very confusing for me at first, is that **Docker daemon and Docker containers don't share the same proxy configuration**!

![Proxy settings for docker engine and containers](https://dev-to-uploads.s3.amazonaws.com/i/l20qibhmg0bn14ewwg7v.png)

## Settings for Docker engine
Your Docker engine needs to connect to the internet to **access image registries** and **pull/push container images**.

If your settings are not correct you will typically see errors when trying to use `docker login` or pulling images from DockerHub, see below for example:

![docker pull fail](https://dev-to-uploads.s3.amazonaws.com/i/s3wmx8xs3s93fgvs00ih.png)

## Setting a Proxy on Docker for Mac/Windows
If you're running Docker for Desktop this is a really simple operation. You can do this from Docker's settings `Docker > Preferences > Resources > Proxies`. All you need to do is provide values for the following variables:
- `HTTP_PROXY`: the proxy server endpoint to handle HTTP calls
- `HTTPS_PROXY`: the endpoint to handle HTTPS calls _(notice this doesn't have to be an https endpoint)_
- `NO_PROXY`: a list of hosts that Docker can reach without using the proxy (usually you'll see `localhost,127.0.0.1` in this field

After this, you should click the *Apply & Restart* button, and you'll be able to push/pull images ✅

![docker desktop proxy settings](https://dev-to-uploads.s3.amazonaws.com/i/q1a9myv3q9gs6fbbzt19.png)

### Using authentication
One question I get asked a lot is **how to provide authentication** if this form does not have a *username* and *password* field. I am not sure why they didn't include such fields in the configuration, but you can just **use URL authentication** like this:

```
http://<username>:<password>@my.proxy.com:3128/
```
## Setting a Proxy on Linux with Systemd
If you're working with a Linux installation, you won't have access to some nice *Preferences* menu. In Linux, the Docker engine is **configured as a system service with Systemd**. 

Let's dust off our System Administration skills! 👨🏻‍💻

In most Linux distributions, Docker is configured as a service with Systemd. You can alter the service configuration by creating an **override file**. Follow these simple steps:

1) Edit the Docker service configuration with:
```bash
> sudo systemctl edit docker.service
```
Systemd will open (or create) the service override file with your default terminal editor.

2) Add or modify the service configuration to include proxy variables. Your service file should look like this:
```
[Service]
Environment=“HTTP_PROXY=http://10.0.1.60:3128”
Environment=“HTTPS_PROXY=http://10.0.1.60:3128”
Environment=“NO_PROXY=localhost,127.0.0.1”
```

3) **Save and close** the file, and restart Docker with
```bash
> sudo systemctl restart docker.service
```

## Running containers with proxy settings
Now that you set up proxies for Docker engine, you need to understand that **Docker will never share those settings with running containers**! 👎🏻

If you want your containers to access the internet, you'll need to supply Proxy settings **using environment variables** like this for example:

```bash
> docker run \
    --env http_proxy="http://my.proxy.com:3128" \
    --env https_proxy="http://my.proxy.com:3128" \
    nginx sh -c "curl google.com"
```

# Full Step-By-Step Tutorial
Take a look at my video below to see everything I described in the article in a real environment!

In the video, I'll also explain how you can configure Docker to **use proxy configuration for containers by default**? This way you won't have to pass `http_proxy` and `https_proxy` variables every time.

Productivity? Yes, please! 🚀

{% youtube cmIc-3NKiL8 %}

### **Don't forget to follow me** for more content like this!