Imagine: you open a terminal, type a package install command, and get silence or a connection error. Often the reason is that network access goes only through a proxy server, and the system doesn't know about it. This guide will teach you how to configure proxy everywhere it's needed on Linux and in CI.

Introduction: What You'll Gain and Who This Guide Is For

By the end of this guide, you'll confidently configure proxy in the Linux terminal and in continuous integration systems. You'll understand how environment variables work, how to correctly construct the proxy URL, and how to make all key developer tools work through a proxy.

Here's exactly what you'll get:

  • A working proxy configuration in the current terminal session.
  • A permanent configuration that survives a reboot.
  • Correct configuration for apt, dnf, git, npm, pip, curl, wget, Docker.
  • Working CI pipelines in GitHub Actions and GitLab Runner.
  • Understanding how to verify traffic actually goes through the proxy.
  • Skills for securely storing your proxy password.

Who this guide is for: beginner sysadmins, developers, and DevOps engineers working in an environment with a corporate proxy. There's also advanced content for seasoned users: systemd nuances, ProxyCommand for SSH, and secret masking in CI.

What you need to know beforehand: you should be able to open a terminal, enter commands, and understand what files and folders are. Everything else is explained in simple language along the way.

How much time you'll need: basic setup takes about 15 minutes. Going through the entire guide with configuration of all tools and CI takes roughly 60–90 minutes. Take your time—better to work through it thoughtfully.

Tip: keep this guide open in a separate window and run the commands one by one. That way you won't miss any important steps.

Preliminary Preparation: Address, Port, Login, and the Correct Proxy URL

Before configuring anything, you need to gather your proxy server details. Without them, you can't move forward.

Where to get proxy details

Typically, a proxy is provided by one of the following:

  • Your company's system administrator — if you're on a corporate network. Ask them for the address, port, and authentication details.
  • A proxy rental service — usually the dashboard has a settings block with access details.
  • Your own server — if you set up a proxy yourself, you already know the details.

You need four pieces: host, port, username, and password. Sometimes authentication is not required—in that case the proxy is without credentials.

How to construct the proxy URL

The proxy is specified as a single string — a URL. The general format is:

scheme://login:password@host:port

Let's break it down with an example. Suppose the proxy address is proxy.example.com, port 3128, login ivan, password secret123. Then the URL looks like:

http://ivan:secret123@proxy.example.com:3128

If authentication is not needed, the URL is simpler:

http://proxy.example.com:3128

About the scheme: most often the http scheme is used even for accessing HTTPS websites. That's normal — the scheme here indicates the protocol for communicating with the proxy itself, not the target site. Occasionally you may encounter proxies with the https or socks5 scheme.

Why special characters in the password must be encoded

This is one of the most common causes of mysterious errors. If the password contains special characters like @, :, /, #, ?, they break the URL parsing. For example, the @ symbol separates the authentication data from the address. If it appears in the password, the system gets confused and can't tell where the password ends and the address begins.

The solution is percent-encoding. Each problematic character is replaced with a percent sign and its hexadecimal code.

Key replacements:

  • @ becomes %40
  • : becomes %3A
  • / becomes %2F
  • # becomes %23
  • ? becomes %3F
  • space becomes %20
  • % becomes %25

Example: if the password is p@ss:word, then in the URL it should appear as p%40ss%3Aword. So the full URL becomes:

http://ivan:p%40ss%3Aword@proxy.example.com:3128

Tip: to quickly encode a password, use the command: python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=''))" 'your_password'. It will output a ready-to-use string for the URL.

⚠️ Warning: never type your real password directly on the command line in plain sight on a shared machine — it will end up in shell history. We'll talk about secure input separately at the end of the guide.

✅ Check: you should have one or more constructed proxy URLs with all special characters in the password encoded. Store them in a safe place, preferably a password manager.

Basic Concepts: Environment Variables, Case Sensitivity, and NO_PROXY Format

So that configuration doesn't feel like magic, let's cover three fundamental concepts. This will take five minutes but save you hours of debugging.

What are environment variables

An environment variable is a named value that the operating system keeps in memory and passes to running programs. Think of it like a note the system shows to each new program: here's the proxy address, use it.

Many network utilities in Linux read special variables at startup and, if they find them, automatically route traffic through the proxy. The most important ones:

  • HTTP_PROXY — proxy for unencrypted HTTP requests.
  • HTTPS_PROXY — proxy for encrypted HTTPS requests.
  • NO_PROXY — a list of addresses to access directly, bypassing the proxy.
  • FTP_PROXY — proxy for the FTP protocol, rarely used nowadays.
  • ALL_PROXY — proxy for all protocols at once, often used for socks.

Difference between http_proxy and HTTP_PROXY by case

This is a subtle but important point. Linux is case-sensitive, so http_proxy and HTTP_PROXY are formally two different variables. Different programs read different versions.

Historically, it has been like this:

  • The curl utility reads both lowercase and uppercase versions, but lowercase http_proxy has a security feature — uppercase HTTP_PROXY is ignored by curl in CGI environments to prevent attacks.
  • The wget utility traditionally prefers lowercase names.
  • Many programs in different languages read uppercase versions.

Practical conclusion: to avoid guesswork, set both versions — lowercase and uppercase. That's the most reliable strategy, and we'll use it.

NO_PROXY format and why it doesn't understand CIDR

The NO_PROXY variable contains a comma-separated list of addresses to access directly. This is critical for internal resources: databases, local services, cloud metadata.

Example of a correct value:

localhost,127.0.0.1,.example.com,.internal,169.254.169.254

Notice the dot before example.com. The dot means all subdomains match: api.example.com, git.example.com, and so on.

⚠️ Warning: NO_PROXY generally does not understand CIDR notation or subnet masks. Entries like 10.0.0.0/8 won't work in most tools. Some modern library versions may support it, but you shouldn't rely on it. List specific addresses and domain suffixes explicitly.

Also, NO_PROXY typically does not support asterisks as wildcards. Don't write *.example.com — use a leading dot: .example.com.

Tip: always add localhost and 127.0.0.1 to NO_PROXY. Otherwise, local requests will go through the proxy and almost certainly break.

✅ Check: you understand the purpose of HTTP_PROXY, HTTPS_PROXY, and NO_PROXY, know about case sensitivity, and remember that NO_PROXY dislikes CIDR. Now you can move on to practice.

Step 1: Enable Proxy in the Current Session and Test with curl

Goal of this step: learn to quickly enable proxy in an open terminal and verify it works. These settings only last until you close the terminal window — perfect for testing.

Set variables with export

The export command creates an environment variable in the current session. Run the following commands, substituting your proxy URL.

  1. Open a terminal.
  2. Enter the command for HTTP: export http_proxy="http://ivan:secret123@proxy.example.com:3128"
  3. Enter the command for HTTPS: export https_proxy="http://ivan:secret123@proxy.example.com:3128"
  4. Duplicate in uppercase: export HTTP_PROXY="$http_proxy"
  5. And again: export HTTPS_PROXY="$https_proxy"
  6. Set exceptions: export no_proxy="localhost,127.0.0.1,.example.com"
  7. Duplicate: export NO_PROXY="$no_proxy"

The construct "$http_proxy" substitutes the value of the already set lowercase variable, so you don't have to type the URL again.

Tip: note that the entire URL is enclosed in double quotes. This protects against incorrect interpretation of special characters by your bash shell.

Test with curl

Now verify that the variables are read. The curl utility is great for this.

  1. Check that the variable is set: echo $http_proxy — you should see your URL.
  2. Make a request with verbose output: curl -v http://example.com
  3. In the output, look for a line mentioning Connected to proxy.example.com — this means curl went through the proxy.

If authentication is correct and the proxy is reachable, you'll get an HTML page in the response. If you see error 407, there's a problem with the login or password — go back to the section on password encoding.

Tip: the -v (verbose) flag shows connection details. It's your main debugging tool for proxy. Without it, you won't see where the request is actually going.

To disable the proxy in the current session, use the unset command: unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY. All variables will be removed.

✅ Check: the command curl -v http://example.com shows a connection through your proxy server and returns page content. If so, the first step is successful.

Step 2: Make the Configuration Permanent

Goal of this step: make the proxy automatically enabled every time you log in and survive a reboot. There are several levels — choose the one that suits you.

Option A: Only for your user via ~/.bashrc

The ~/.bashrc file runs every time an interactive terminal is opened under your user. This is the safest option — you won't affect other users on the system.

  1. Open the file with an editor: nano ~/.bashrc
  2. Scroll to the very end of the file.
  3. Add the same export lines from Step 1.
  4. Save the file: press Ctrl+O, then Enter, then Ctrl+X to exit.
  5. Apply the changes without rebooting: source ~/.bashrc

Tip: before editing, make a backup: cp ~/.bashrc ~/.bashrc.backup. If something goes wrong, you can easily restore the original.

Option B: System-wide via /etc/environment

The file /etc/environment sets variables for all users and works even outside bash. Its format is special: no export keyword, just NAME=value.

  1. Open the file with admin privileges: sudo nano /etc/environment
  2. Add lines without export, e.g.: http_proxy="http://ivan:secret123@proxy.example.com:3128"
  3. Add similar lines for https_proxy, HTTP_PROXY, HTTPS_PROXY, no_proxy, NO_PROXY.
  4. Save and exit.
  5. To apply, log out and log back in, or reboot.

Option C: Via /etc/profile.d

A more flexible system-wide method is to create a separate script in the /etc/profile.d folder. All .sh files there are executed at login.

  1. Create a file: sudo nano /etc/profile.d/proxy.sh
  2. Inside, use normal export commands as in Step 1.
  3. Save the file.
  4. Make it executable: sudo chmod +x /etc/profile.d/proxy.sh

This method is more convenient than /etc/environment because it supports full shell syntax.

Option D: For system services via systemd drop-in

Attention — this is an important nuance. Background services managed by systemd do not read your ~/.bashrc and often ignore /etc/environment. They need a separate approach — a drop-in file.

Suppose you need a specific service named some-service to work through the proxy.

  1. Create a drop-in directory and file: sudo systemctl edit some-service
  2. An editor will open. Enter the configuration block.
  3. In the [Service] section, add lines like: Environment="HTTP_PROXY=http://ivan:secret123@proxy.example.com:3128"
  4. Add similar Environment lines for HTTPS_PROXY and NO_PROXY.
  5. Save the file.
  6. Reload configuration: sudo systemctl daemon-reload
  7. Restart the service: sudo systemctl restart some-service

The Environment directive sets the variable specifically for this service. This is the only correct way for systemd services.

⚠️ Warning: on RHEL, CentOS, Fedora, and AlmaLinux, paths and tools are the same — systemd works identically. Differences will appear later in the package manager section.

✅ Check: open a new terminal (not the one where you manually ran export) and run echo $http_proxy. If you see your URL, the permanent configuration works.

Step 3: Configure Package Managers and Utilities Individually

Goal of this step: many tools do not read environment variables or have their own configuration files. We'll set up each one separately so nothing breaks.

apt on Ubuntu and Debian

The apt package manager often runs via sudo and may not see your variables. It's more reliable to set the proxy in its own configuration file.

  1. Create a file: sudo nano /etc/apt/apt.conf.d/95proxies
  2. Add a line: Acquire::http::Proxy "http://ivan:secret123@proxy.example.com:3128";
  3. Add a line for HTTPS: Acquire::https::Proxy "http://ivan:secret123@proxy.example.com:3128";
  4. Save the file.
  5. Test: sudo apt update

Note the semicolon at the end of each line — it's mandatory in apt's syntax.

dnf and yum on RHEL, Fedora, AlmaLinux

On RHEL-family systems, dnf and yum are used instead of apt. The proxy is set in the main config.

  1. Open the file: sudo nano /etc/dnf/dnf.conf (for older systems /etc/yum.conf)
  2. Add to the [main] section: proxy=http://proxy.example.com:3128
  3. If authentication is needed, add separately: proxy_username=ivan and proxy_password=secret123
  4. Save the file.
  5. Test: sudo dnf makecache

In dnf, it's more convenient to specify login and password as separate directives rather than inside the URL.

npm via .npmrc

  1. Set the proxy: npm config set proxy "http://ivan:secret123@proxy.example.com:3128"
  2. Set for HTTPS: npm config set https-proxy "http://ivan:secret123@proxy.example.com:3128"
  3. The settings are automatically written to ~/.npmrc.
  4. Verify: npm config get proxy

pip via pip.conf

  1. Create the directory: mkdir -p ~/.config/pip
  2. Open the file: nano ~/.config/pip/pip.conf
  3. Add a [global] section and a line: proxy = http://ivan:secret123@proxy.example.com:3128
  4. Save the file.
  5. Test by installing any package: pip install requests

Alternatively, you can specify the proxy directly in the command: pip install requests --proxy http://proxy.example.com:3128

git via http.proxy

  1. Set globally: git config --global http.proxy "http://ivan:secret123@proxy.example.com:3128"
  2. If needed, separately for HTTPS: git config --global https.proxy "http://ivan:secret123@proxy.example.com:3128"
  3. Verify: git config --global --get http.proxy

To remove the setting: git config --global --unset http.proxy

git over SSH via ProxyCommand

If you clone repositories over SSH (address like git@github.com), the http.proxy setting won't help — SSH is a different protocol. You need ProxyCommand.

  1. Open the file: nano ~/.ssh/config
  2. Add a block for the required host: Host github.com, then indented line ProxyCommand nc -X connect -x proxy.example.com:3128 %h %p
  3. Save the file.
  4. Install netcat if missing: sudo apt install netcat-openbsd on Ubuntu, sudo dnf install nmap-ncat on RHEL.

Here, %h and %p are automatically replaced with the destination host and port. The -X connect flag tells netcat to use an HTTP proxy.

curl via .curlrc

  1. Open the file: nano ~/.curlrc
  2. Add a line: proxy = "http://ivan:secret123@proxy.example.com:3128"
  3. Save the file.

Now curl will use the proxy always, even without environment variables.

wget via .wgetrc

  1. Open the file: nano ~/.wgetrc
  2. Add lines: http_proxy = http://proxy.example.com:3128 and https_proxy = http://proxy.example.com:3128
  3. Add use_proxy = on
  4. Save the file.

composer for PHP

Composer reads the HTTP_PROXY environment variable, so often no separate configuration is needed. If you want to set it explicitly, use the variable at run time: HTTP_PROXY=http://proxy.example.com:3128 composer install

Go and GOPROXY: an important warning

⚠️ Warning: the GOPROXY variable is NOT a proxy server in our sense. They must not be confused. GOPROXY points to a Go module mirror — a service from which libraries are downloaded. That's a repository address, not a network proxy.

To make Go access the internet through your regular proxy, use standard HTTP_PROXY and HTTPS_PROXY. Leave GOPROXY at its default value unless you have a specific need to change the module mirror.

Tip: remember the rule — if a variable name has the word PROXY, it doesn't necessarily mean it's about your network proxy. GOPROXY, npm registry, and similar ones are about package sources.

✅ Check: perform a test operation with each configured tool: sudo apt update, npm install, git ls-remote, and so on. All should successfully reach the network.

Step 4: Configure Docker and Kubernetes

Goal of this step: Docker is a special case. It has three different places to configure proxy, and confusing them is a common mistake. Let's cover each.

Place 1: Docker daemon via systemd drop-in

This setting is needed so that Docker itself can pull images from registries. The Docker daemon is managed by systemd, so we use the familiar drop-in mechanism.

  1. Create the directory: sudo mkdir -p /etc/systemd/system/docker.service.d
  2. Create a file: sudo nano /etc/systemd/system/docker.service.d/proxy.conf
  3. Add a [Service] section.
  4. Add a line: Environment="HTTP_PROXY=http://proxy.example.com:3128"
  5. Add similar lines for HTTPS_PROXY and NO_PROXY.
  6. Reload configuration: sudo systemctl daemon-reload
  7. Restart Docker: sudo systemctl restart docker

Verify with: sudo systemctl show --property=Environment docker

Place 2: During image build with build-arg

When building an image, commands inside the Dockerfile (e.g., apt install) run in an isolated environment that doesn't see the host's proxy. The proxy must be passed explicitly.

  1. In the Dockerfile, add ARG http_proxy and ARG https_proxy instructions before the RUN commands.
  2. Build the image passing the arguments: docker build --build-arg http_proxy=http://proxy.example.com:3128 --build-arg https_proxy=http://proxy.example.com:3128 -t myimage .

⚠️ Warning: do not hardcode the proxy password into the Dockerfile using the ENV instruction. It will remain in image layers, and anyone who gets the image will see the password. Use build-arg instead, and better yet, use a password-less proxy for builds.

Place 3: Containers at runtime via ~/.docker/config.json

To have running containers automatically receive proxy variables, configure the Docker client config.

  1. Open the file: nano ~/.docker/config.json
  2. Add a proxies block with a default section.
  3. Inside, specify httpProxy, httpsProxy, and noProxy with your values.
  4. Save the file.

Now every docker run will automatically pass the variables into the container.

Variables in Kubernetes manifests

In Kubernetes, proxy is set via environment variables in the container specification. In the env section of a Pod or Deployment manifest, add items with names HTTP_PROXY, HTTPS_PROXY, NO_PROXY and corresponding value.

Tip: store secret values in Kubernetes Secrets and reference them via valueFrom, rather than writing the password directly in the manifest. This way, the password won't end up in version control.

✅ Check: run docker pull hello-world — the image should download. Then docker run --rm alpine env | grep -i proxy — you'll see the passed variables inside the container.

Step 5: Configure Proxy in CI — GitHub Actions and GitLab Runner

Goal of this step: make CI pipelines work through the proxy while securely storing credentials and not exposing the password in logs.

Storing credentials in secrets

The golden rule of CI: never write the proxy password directly in the YAML pipeline file. The file lives in the repository, and everyone will see the password. Use the secrets mechanism.

In GitHub Actions, secrets are added in repository settings under Settings, then Secrets and variables, then Actions. Create a secret named PROXY_URL and paste the full proxy URL there.

In GitLab, secrets are called CI/CD variables. They are added under Settings, then CI/CD, then Variables. Be sure to enable the Masked and Protected flags for sensitive values.

Configuring GitHub Actions

  1. In the pipeline file .github/workflows, add an env block at the job level.
  2. Set HTTP_PROXY to the value from the secret using ${{ secrets.PROXY_URL }} syntax.
  3. Similarly set HTTPS_PROXY and NO_PROXY.
  4. These variables will be available to all steps in the job.

Configuring GitLab Runner

GitLab has two levels. You can set variables directly in the .gitlab-ci.yml file using a variables block, or at the runner level in its config file config.toml under the environment section.

  1. For the project: add a variables block in .gitlab-ci.yml referencing protected variables.
  2. For all projects on the runner: open the runner's config.toml and add an environment parameter in the [[runners]] section with a list of required variables.

Masking the password in logs

Even with secrets, the password might accidentally appear in the log if some command prints it. GitHub Actions automatically masks secret values with asterisks. In GitLab, that's the job of the Masked flag — but it only works if the value meets requirements (no certain special characters and sufficient length).

⚠️ Warning: avoid commands with the -v flag or echo that print the full proxy URL to the log. Even with masking, it's better not to risk it. For debugging, print only the address and port without login and password.

Tip: store the proxy URL without embedded password, and keep login and password as separate secrets. That makes them easier to mask and rotate.

✅ Check: trigger the pipeline manually. A step that makes a network request (e.g., installing dependencies) should complete successfully. The password should not be visible in the logs.

Verify the Result: Ensure Traffic Actually Goes Through the Proxy

Setting it up is not enough — you need proof that traffic really goes through the proxy and not directly. Here's a checklist of verifications.

Checklist of what should work

  • The command echo $http_proxy in a new terminal shows your URL.
  • curl -v http://example.com shows a line Connected to your proxy.
  • sudo apt update successfully updates package lists.
  • git ls-remote to a remote repository succeeds.
  • docker pull downloads an image.
  • The CI pipeline completes in green.

How to test reliably

The most honest way is to find out what external IP address the destination server sees. Make a request to a service that shows your IP. If through the proxy, you'll see the proxy server's IP, not your own.

  1. Make a request without proxy: env -u http_proxy -u https_proxy curl -s http://ifconfig.me — you'll see your real IP.
  2. Make a request with proxy: curl -s http://ifconfig.me — you'll see the proxy's IP.
  3. If the two addresses differ, the proxy is working.

Another method is to check the proxy server's logs if you have access to them. Your requests should appear there.

Tip: the env -u command temporarily removes a variable for just that single command without affecting the session. Handy for comparing behavior with and without proxy.

✅ Check: the IP address with proxy differs from the direct one. This is 100% proof that traffic goes through the proxy.

Common Errors and Their Solutions

Let's go over frequent problems. Simple format: problem, cause, solution.

Problem 1: sudo doesn't inherit variables

Cause: sudo by default clears the environment for security reasons. Your export doesn't reach the command run under sudo.

Solution: use the -E flag to preserve the environment: sudo -E apt update. Or configure permanent preservation via the sudoers file. Run sudo visudo and add the line: Defaults env_keep += "http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY". After that, sudo will always pass these variables.

Problem 2: Certificate errors

Cause: Some corporate proxies intercept HTTPS and replace certificates with their own root certificate. The system doesn't know it and complains about an untrusted connection.

Solution: Obtain the proxy's root certificate from the administrator. On Ubuntu and Debian, copy it to /usr/local/share/ca-certificates with a .crt extension and run sudo update-ca-certificates. On RHEL, place it in /etc/pki/ca-trust/source/anchors and run sudo update-ca-trust. After that, all tools will trust the proxy.

Problem 3: curl works, apt doesn't

Cause: curl reads environment variables, but apt under sudo doesn't see them and has no dedicated proxy config.

Solution: configure the proxy in /etc/apt/apt.conf.d as described in Step 3. That's a separate configuration from environment variables, and it's what apt needs.

Problem 4: Password with special characters

Cause: characters like @, :, / in an unencoded password break URL parsing.

Solution: apply percent-encoding from the Preparation section. Replace @ with %40, : with %3A, and so on.

Problem 5: Error 407 Proxy Authentication Required

Cause: incorrect login or password, or the proxy requires authentication but you didn't provide any.

Solution: double-check the login and password. Make sure authentication data is in the URL. Verify special character encoding.

Problem 6: Internal resources are unreachable

Cause: requests to local and internal addresses go through the proxy, which doesn't know them.

Solution: add those addresses to NO_PROXY. Don't forget localhost, 127.0.0.1, and internal domains with a leading dot.

Problem 7: Docker daemon doesn't see proxy

Cause: you configured variables in bashrc, but the Docker daemon is managed by systemd and doesn't read them.

Solution: use the systemd drop-in from Step 4, don't forget daemon-reload and restart docker.

Problem 8: Settings didn't apply

Cause: you edited bashrc but didn't restart the terminal.

Solution: run source ~/.bashrc or open a new terminal window.

Additional Features and Advanced Configuration

Once the basic setup is working, you can improve convenience and flexibility.

Proxy toggle functions

It's convenient to create two functions in ~/.bashrc: proxy_on to enable and proxy_off to disable. Inside proxy_on, place the export commands; inside proxy_off, place the unset commands. Then toggling becomes a single command.

Different proxies for different tasks

You can set a proxy for just one command without changing the whole environment. Example: https_proxy=http://other:3128 curl https://example.com. The variable only applies to that command.

SOCKS proxy

If you have a SOCKS5 proxy, use the socks5 scheme in the URL and the ALL_PROXY variable. For curl, there's the --socks5 flag. Note that not all utilities work with SOCKS.

Tip: For tools that don't support proxy at all, there are wrappers like proxychains. But use them consciously — they change the behavior of the program's network calls.

Summary configuration table

Keep this summary handy. Format: tool — configuration file — variable or directive.

  • Shell session — temporary in memory — export http_proxy and HTTP_PROXY.
  • User — ~/.bashrc — export variables.
  • System-wide — /etc/environment — http_proxy without export.
  • System-wide — /etc/profile.d/proxy.sh — export variables.
  • systemd service — drop-in via systemctl edit — Environment directive.
  • apt (Ubuntu, Debian) — /etc/apt/apt.conf.d/95proxies — Acquire::http::Proxy.
  • dnf, yum (RHEL) — /etc/dnf/dnf.conf — proxy, proxy_username, proxy_password.
  • npm — ~/.npmrc — proxy and https-proxy.
  • pip — ~/.config/pip/pip.conf — proxy in [global].
  • git over HTTPS — global git config — http.proxy.
  • git over SSH — ~/.ssh/config — ProxyCommand.
  • curl — ~/.curlrc — proxy.
  • wget — ~/.wgetrc — http_proxy, https_proxy, use_proxy.
  • composer — environment — HTTP_PROXY.
  • Docker daemon — /etc/systemd/system/docker.service.d/proxy.conf — Environment.
  • Docker build — build command — build-arg http_proxy.
  • Docker containers — ~/.docker/config.json — proxies block.
  • Kubernetes — Pod manifest — env with HTTP_PROXY.
  • GitHub Actions — workflow file — env block with secrets.
  • GitLab — .gitlab-ci.yml or config.toml — variables or environment.

FAQ: Frequently Asked Questions About Proxy Configuration

Do I need to set both lowercase and uppercase variables?

Yes, it's the most reliable strategy. Different programs read different cases, so setting both versions eliminates surprises.

Why does curl see the proxy but apt doesn't?

Because apt under sudo doesn't inherit environment variables and has its own configuration. Set apt separately via a file in /etc/apt/apt.conf.d.

How can I temporarily disable the proxy for one command?

Use env -u http_proxy -u https_proxy before the command. This removes the variables only for that run.

Can I specify a subnet in NO_PROXY?

Typically, no. NO_PROXY does not reliably understand CIDR notation. List specific addresses and domain suffixes with a leading dot.

Is GOPROXY my proxy server?

No. GOPROXY points to a Go module mirror, not a network proxy. For network proxy in Go, use HTTP_PROXY and HTTPS_PROXY.

How to store the proxy password securely?

In CI, use secrets. Locally, use a .netrc file with permissions 600 or a password manager. Avoid the password in command history.

Why doesn't git over SSH go through http.proxy?

Because SSH is a separate protocol. Configure ProxyCommand in ~/.ssh/config for the appropriate host.

What to do about certificate errors through the proxy?

Install the proxy's root certificate into the system trust store and update trust with update-ca-certificates on Debian or update-ca-trust on RHEL.

Settings in bashrc don't work in a new session, why?

Perhaps you edited the wrong file, didn't save changes, or didn't open a new terminal. Check with echo and source.

How to verify that traffic actually goes through the proxy?

Compare the external IP with and without the proxy using curl to an IP detection service. Different addresses confirm the proxy is working.

Conclusion: What You've Learned and Where to Go Next

Congratulations, you've come a long way. Let's summarize what you now know.

You've learned how to construct a correct proxy URL and encode special characters in the password. You understand the HTTP_PROXY, HTTPS_PROXY, and NO_PROXY variables, including case sensitivity and the exclusion format. You know how to enable proxy in a session and make the configuration permanent in several ways, including systemd drop-ins for services.

You've configured proxy for all key tools: apt and dnf, npm and pip, git over both HTTPS and SSH, curl and wget, composer, and you understand the important distinction of GOPROXY. You've mastered the three places to configure Docker and the variables in Kubernetes. Finally, you've set up proxy in GitHub Actions and GitLab with secure secret storage and password masking.

What to do next: reinforce your knowledge with practice. Set up proxy on a test machine from scratch following the guide. Create toggle functions for convenience. Explore your proxy server's logs to see the traffic with your own eyes.

Where to grow: the next step is automation of configuration through configuration management tools like Ansible, so you can deploy proxy on dozens of machines with a single command. It's also useful to dive deeper into working with certificates and different proxy types.

Tip: save the summary table from this guide as a cheatsheet. It will save you a lot of time when you need to quickly recall where to configure proxy for a specific tool.

You did great. Now proxy in the Linux terminal and in CI holds no mystery for you. Happy configuring and stable connections!