Google Chrome is not in Ubuntu’s archive, and there is no official snap of it either, so it comes from Google’s own .deb package. That one file installs the browser and drops a signed apt source on your system, which means every later Chrome release arrives with your normal apt upgrade. Ubuntu itself ships Firefox as a snap, and its Chromium package is a snap too, so the .deb is the route that gets you Chrome.
The steps below cover the desktop install, the dialogs you meet on first launch, the default browser setting, headless use on a server, Selenium, the new ARM64 build and a clean removal. We ran them in October 2026 on an Ubuntu 26.04 desktop and an Ubuntu 24.04 server with Chrome 155. The desktop steps ran on 26.04 and the server, headless and Selenium steps on 24.04, with the same .deb on both.
Check the requirements
Chrome needs a 64-bit machine and an account that can use sudo. Disk use depends a lot on what’s already installed, because a desktop already has most of Chrome’s libraries and a server image has almost none of them. On our two test machines that came to one package against 150, so plan for the larger figure if the target is a server:
- Ubuntu 26.04 or 24.04, desktop or server
- x86_64 (amd64), or ARM64 since Google started publishing it
- About 600 MB free on a desktop, 1.1 GB on a server, counting the 138 MB download
- A user with sudo rights
There is no 32-bit build, and there has not been one for years, so an old 32-bit laptop has to stay on Chromium or Firefox. If you want a fully open-source browser anyway, our guide to installing Chromium on Ubuntu covers the snap that Ubuntu ships. Chromium lacks Google account sync, and it updates through snapd instead of apt, which matters if you manage updates centrally.
Download the Chrome package
The download URL from Google ends in _current_ instead of a version number, so the same command always fetches the newest stable release. That is handy for a fresh install, but it also means two downloads a week apart can hold different builds, so check the version before you copy the file to other machines. Download it into your home directory:
cd ~
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
The file weighed 138 MB in our test. To see which release you actually got, read the version field straight from the package, which works without installing anything:
dpkg-deb -f google-chrome-stable_current_amd64.deb Version
It printed the stable build that was current on the day we tested. Compare it with the Chrome Releases blog when a security fix matters to you, because Google announces each stable build there:
155.0.8059.84-1
Clicking the download button on google.com/chrome gives you the same file if you pick the 64-bit .deb for Debian and Ubuntu, so either route ends at the same apt command below.
Install Chrome with apt
Install the file with apt, not with dpkg -i. dpkg -i unpacks the package but refuses to configure it when a dependency is missing, which leaves it half installed, while apt resolves the dependencies for you. The ./ in front of the name is what tells apt that you mean a local file and not a package from the archive:
sudo apt install -y ./google-chrome-stable_current_amd64.deb
On the Ubuntu 26.04 desktop, apt installed exactly one package, because GNOME had already pulled in every library Chrome links against. The interesting lines are the alternatives the package registers on its way in. They decide which browser older scripts and terminal tools launch, and they come up again in the default browser section, because they do not do what most people expect:
update-alternatives: using /usr/bin/google-chrome-stable to provide /usr/bin/x-www-browser (x-www-browser) in auto mode
update-alternatives: using /usr/bin/google-chrome-stable to provide /usr/bin/gnome-www-browser (gnome-www-browser) in auto mode
update-alternatives: using /usr/bin/google-chrome-stable to provide /usr/bin/google-chrome (google-chrome) in auto mode
A run of debconf: unable to initialize frontend lines can follow when apt runs without a terminal, from a script or a non-interactive SSH command. They’re harmless, because the package asks no questions. Confirm the binary is on your path and reports the version you downloaded:
google-chrome --version
The output matches the package version:
Google Chrome 155.0.8059.84
/usr/bin/google-chrome is an alternatives link that ends at /opt/google/chrome/google-chrome, which is where the whole browser lives. Nothing lands in your home directory until you launch it.
Inspect the Google apt repository
Older guides, including the earlier version of this one, show a one-line google-chrome.list file. Current packages write a deb822 file named google-chrome.sources instead, in the same format Ubuntu uses for its own ubuntu.sources:
cat /etc/apt/sources.list.d/google-chrome.sources
The file names a chrome-stable path in the URI and a dedicated keyring under /usr/share/keyrings. The header comment also matters: if you delete the file, the package will not recreate it on the next update, so Chrome silently stops updating:
### THIS FILE IS AUTOMATICALLY CONFIGURED ###
# Changes to this file will not be preserved.
# This file will not be recreated if removed.
X-Repolib-Name: Google Chrome
Types: deb
URIs: https://dl.google.com/linux/chrome-stable/deb/
Suites: stable
Components: main
Architectures: amd64
Signed-By: /usr/share/keyrings/google-chrome.gpg
Because Signed-By points at that one file, Google’s key only vouches for Google’s repository and not for anything else apt fetches. You do not need to import a key by hand. List what the keyring holds:
gpg --show-keys /usr/share/keyrings/google-chrome.gpg
The primary key dates from 2016. The signing subkeys rotate every year, and each one is valid for three years:
pub rsa4096 2016-04-12 [SC]
EB4C1BFD4F042F6DDDCCEC917721F63BD38B4796
uid Google Inc. (Linux Packages Signing Authority) <[email protected]>
sub rsa4096 2024-01-30 [S] [expires: 2027-01-29]
sub rsa4096 2025-01-07 [S] [expires: 2028-01-07]
sub rsa4096 2026-03-10 [S] [expires: 2029-03-09]
The package’s install script rewrites this keyring every time Chrome updates, so a machine that keeps updating always holds the current subkeys. A machine left unpatched for years can fall behind, and then apt rejects the repository signature and stops offering new Chrome builds at all. Reinstalling the current .deb repairs it, because the new package carries the new subkeys and writes them before apt checks the repository again.
We also tested the upgrade path on the 24.04 server. We created the old google-chrome.list by hand with the deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main line that Google’s own package used to write, then installed the current package over it. The install script deleted the legacy file and wrote the .sources file, so a machine set up that way ends up with one clean source. The script only deletes a .list whose lines match that exact form, though. If yours has no [arch=amd64] option, a signed-by= option or extra lines, it stays, and apt keeps fetching the old chrome/deb path as a second repository, which can also fail its signature check now that the old key is gone, so delete it by hand.
Refresh the package index to make sure apt can reach and verify the repository. Two Google lines in the output, with no W: or E: lines after them, mean the signature checked out:
sudo apt update
Our run fetched the release file and the package index from the chrome-stable path:
Get:3 https://dl.google.com/linux/chrome-stable/deb stable InRelease [2548 B]
Get:5 https://dl.google.com/linux/chrome-stable/deb stable/main amd64 Packages [1404 B]
From here, Chrome updates arrive with sudo apt update && sudo apt upgrade, or through Software Updater on the desktop, along with the rest of your packages.
Launch Chrome the first time
Open Chrome from the app grid, or run google-chrome in a terminal inside your desktop session. On Ubuntu 26.04 the first launch shows three Chrome screens, and on some machines GNOME adds a keyring prompt on top of the second one.
The first is Google’s Additional Terms of Service, which the Linux build asks you to accept before it opens a window:

Click Accept and Chrome opens its welcome dialog. If you log in to Ubuntu automatically, without typing a password, GNOME immediately covers that dialog with a request to choose a password for a new Default Keyring. Chrome stores its encryption key for saved passwords and cookies there, and with automatic login there is no unlocked login keyring for it to use:

You have two sensible choices here. Set a password and Ubuntu asks for it once per session when Chrome starts, which keeps saved passwords encrypted on disk. Leave both fields empty and the keyring is stored unencrypted, so anyone who can read your home directory can read those secrets too. If you log in with a password, which is the default on a fresh Ubuntu install, this prompt never appears and Chrome uses your login keyring silently.
Once the keyring prompt is answered, the welcome dialog underneath it is usable. Both boxes are ticked by default, and the first one is the quickest way to make Chrome your default browser:

We kept the default browser box and cleared the usage statistics box, which stops Chrome sending crash reports and usage data to Google. You can change either later in Settings. The last screen offers Google account sign-in for sync:

Stay signed out works fine if you only want the browser. Chrome then opens a normal new tab. Your profile lives in ~/.config/google-chrome, and ours had already grown to 158 MB after this first launch.
Chrome runs as a native Wayland client in Ubuntu’s default session. Chrome launches its child processes with --ozone-platform=wayland, and 7 of the 13 Chrome processes on our desktop carried that flag, so you do not need the old chrome://flags toggle or a launcher flag to get Wayland.
Set Chrome as the default browser
Two different settings are called “default browser” on Ubuntu, and the install only changes one of them. The package registers Chrome for x-www-browser with priority 200, against Firefox’s 40, so the Debian alternatives system switches to Chrome straight away. That link is what terminal tools and older scripts call when they want a browser, which is why it changes silently during an install:
update-alternatives --display x-www-browser
Both browsers are registered, and auto mode picked the higher priority:
x-www-browser - auto mode
link best version is /usr/bin/google-chrome-stable
link currently points to /usr/bin/google-chrome-stable
link x-www-browser is /usr/bin/x-www-browser
/usr/bin/firefox - priority 40
/usr/bin/google-chrome-stable - priority 200
GNOME ignores that link. Links clicked in other apps follow the freedesktop default instead, and right after the install it still pointed at Firefox. That is why older advice to run update-alternatives --set x-www-browser changes nothing you’d notice on a desktop. Ticking the box in Chrome’s welcome dialog changes the setting that matters, and so does this command, run as your normal user:
xdg-settings set default-web-browser google-chrome.desktop
Read it back to confirm the change. It should name the Chrome desktop file:
xdg-settings get default-web-browser
Ours returned exactly that:
google-chrome.desktop
To go back to Firefox later, use its snap desktop file name, firefox_firefox.desktop, in the same command. In the GUI, the same setting sits under Settings, Apps, Default Apps.
Keep Chrome updated
The About page at chrome://settings/help shows the running version, but on Linux it has no update button and never downloads anything itself. That is different from Windows and macOS, where Chrome runs its own updater in the background, so on Ubuntu a machine that never runs apt keeps the same Chrome build forever:

Updates come only through apt, from the repository the package added. If you want Chrome updated without running a full system upgrade, upgrade just that package:
sudo apt update
sudo apt install --only-upgrade google-chrome-stable
Restart Chrome afterwards, because the old version keeps running until you do. On 24.04 and 26.04, unattended-upgrades only installs from Ubuntu’s own archive and ESM by default, never from Google’s repository, so Chrome updates wait for you or for Software Updater.
Install Chrome Beta or Dev alongside
Google’s stable repository also carries the other channels, so once the stable .deb is installed you do not need another download. On the day we tested, the repository listed these packages:
google-chrome-stable155google-chrome-beta157google-chrome-unstable(Dev) 158google-chrome-canary158
Install the beta straight from apt. It is a separate package, so the stable build stays installed and keeps updating on its own.
sudo apt install -y google-chrome-beta
The beta added its own source file and keyring next to the stable ones, pointing at its own chrome-beta/deb path:
google-chrome-beta.sources
google-chrome.sources
ubuntu.sources
The beta runs as google-chrome-beta with its own profile in ~/.config/google-chrome-beta, as the Chromium user data directory docs list. Testing a beta never touches your stable bookmarks or extensions, and the same goes for google-chrome-unstable and google-chrome-canary.
Run Chrome headless on a server
Chrome on a server is mostly used for screenshots, PDFs and browser tests. Expect a much bigger install than on a desktop, because a server image lacks the graphics, font and audio libraries Chrome links against even when it never draws a window. On our 24.04 server, a cloud image with no desktop packages, the same apt install pulled in 150 packages:
0 upgraded, 150 newly installed, 0 to remove and 0 not upgraded.
Need to get 89.9 MB/234 MB of archives.
After this operation, 880 MB of additional disk space will be used.
Chrome does not switch to headless mode on its own when there’s no display, whatever older guides say. Started like a desktop app over SSH, it finds no Wayland compositor, falls back to X11, finds no X server either and exits:
[30470:30470:1020/105055.278953:ERROR:ui/ozone/platform/x11/ozone_platform_x11.cc:257] Missing X server or $DISPLAY
[30470:30470:1020/105055.278990:ERROR:ui/aura/env.cc:246] The platform failed to initialize. Exiting.
Pass --headless every time. This prints the rendered DOM of a page after JavaScript has run, which is what most scrapers actually want:
google-chrome --headless --dump-dom https://example.com
For a screenshot, set the window size so every capture comes out at the same dimensions. Chrome writes the file into the current directory unless you give it a full path.
google-chrome --headless --screenshot=example.png --window-size=1280,800 https://example.com
Chrome confirms the write on its last line. Before it, you’ll usually see a UPower D-Bus error, which only means the server has no power manager for Chrome to query. Ignore it:
77481 bytes written to file example.png
PDF output works the same way. --no-pdf-header-footer drops the date, title, URL and page numbers that Chrome otherwise prints in the margins:
google-chrome --headless --no-pdf-header-footer --print-to-pdf=example.pdf https://example.com
We got a one-page, 25 KB PDF, and a full --dump-dom run took 1.19 seconds from cold start. For HTML-to-PDF jobs that don’t need a full browser, wkhtmltopdf on Ubuntu is lighter, but its old Qt WebKit engine often breaks modern flexbox and grid layouts.
Puppeteer, Playwright and similar tools talk to Chrome over the DevTools protocol. Start it in the background with a debugging port, give it a few seconds to open the port, then query the endpoint:
google-chrome --headless --remote-debugging-port=9222 about:blank >/dev/null 2>&1 &
sleep 4
curl -s http://127.0.0.1:9222/json/version
The JSON reply includes the browser build and protocol version. If you see it, Puppeteer or Playwright can attach to this Chrome with the same URL.
"Browser": "Chrome/155.0.8059.84",
"Protocol-Version": "1.3",
That port has no authentication, and anyone who reaches it controls the browser, including its cookies and any session it is logged in to. Chrome binds it to 127.0.0.1, so every local user on the same host can already reach it, which is a reason to run automation under a dedicated account on shared machines. Reach it from your workstation through an SSH tunnel, and never change the bind address or put a proxy in front of it. Stop the test browser when you are done:
pkill -f remote-debugging-port=9222
Without that, a headless Chrome keeps running in the background and holds the port.
Drive Chrome with Selenium
Selenium needs a ChromeDriver whose major version matches the installed Chrome, and a mismatch fails at session start with a “session not created” error. Google publishes a matching driver for each Chrome release through the Chrome for Testing project, so you can build the download URL from the version string the browser reports and never guess:
sudo apt install -y unzip
VER=$(google-chrome --version | awk '{print $3}')
wget "https://storage.googleapis.com/chrome-for-testing-public/${VER}/linux64/chromedriver-linux64.zip"
unzip -o chromedriver-linux64.zip
sudo install -m 755 chromedriver-linux64/chromedriver /usr/local/bin/
Check that the driver build matches the browser build:
chromedriver --version
Ours matched the browser to the last digit:
ChromeDriver 155.0.8059.84 (5869fe313571d75152b77813cf0a4ee26a4e6df0-refs/branch-heads/8059@{#1303})
With Selenium 4 for Python, you can skip that step entirely. Its built-in Selenium Manager detects the installed Chrome and downloads the matching driver into ~/.cache/selenium on first use. Install Selenium in a virtual environment, since Ubuntu blocks pip from writing to the system Python:
sudo apt install -y python3-venv
python3 -m venv ~/sel
~/sel/bin/pip install selenium
Create a small test script. It opens a page headless and prints the title along with the two versions Selenium negotiated, which is the quickest proof that the browser and the driver agree:
nano ~/check.py
Add these lines to it:
from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_argument("--headless")
d = webdriver.Chrome(options=opts)
d.get("https://example.com")
print(d.title, "|", d.capabilities["browserVersion"], "|", d.capabilities["chrome"]["chromedriverVersion"].split()[0])
d.quit()
Run it with the Python inside the virtual environment:
~/sel/bin/python ~/check.py
We ran it twice, once with our manual driver in /usr/local/bin and once after deleting it. Both runs printed the same line, because Selenium Manager fetched the matching driver into ~/.cache/selenium/chromedriver/linux64 the second time:
Example Domain | 155.0.8059.84 | 155.0.8059.84
Pinning the driver by hand still makes sense on CI runners without internet access. Everywhere else, let Selenium Manager handle it, because a manual driver goes stale the next time apt upgrades Chrome. It keeps one driver per Chrome build in its cache, so only the first run after an upgrade waits for a download.
Install Chrome on ARM64 Ubuntu
Google announced Chrome for ARM64 Linux in March 2026, and the repository now serves it. Its arm64 index lists the same stable, beta, Dev and Canary builds as the amd64 one, and the direct download follows the same naming:
wget https://dl.google.com/linux/direct/google-chrome-stable_current_arm64.deb
sudo apt install -y ./google-chrome-stable_current_arm64.deb
We don’t have ARM hardware in the lab, so we inspected the package on x86 instead of running it. Reading the control fields and extracting the binary into a scratch directory shows what is inside:
dpkg-deb -f google-chrome-stable_current_arm64.deb Package Version Architecture
dpkg-deb -x google-chrome-stable_current_arm64.deb x
file x/opt/google/chrome/chrome
It’s a real aarch64 build, and its install script writes Architectures: arm64 into the same deb822 source file:
Package: google-chrome-stable
Version: 155.0.8059.84-1
Architecture: arm64
x/opt/google/chrome/chrome: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=72b4730f942f6f67cea7bd2c5494e58176e38215, stripped
That makes Chrome installable on ARM64 Ubuntu machines such as Ampere servers and NVIDIA DGX Spark workstations, which until this year had to fall back to Chromium. The repository and removal steps above apply to it unchanged. For Selenium, swap linux64 for linux-arm64 in the ChromeDriver URL, so the file becomes chromedriver-linux-arm64.zip, or let Selenium Manager pick the right build.
Remove Chrome
How much you remove depends on the apt verb. remove deletes the browser under /opt/google but leaves the package in the rc state, so its repository stays configured. Use it when you plan to reinstall soon, and purge when you want the machine clean:
sudo apt remove -y google-chrome-beta google-chrome-stable
Drop google-chrome-beta from the command if you never installed it. Then list what the packages left behind.
ls /etc/apt/sources.list.d/; ls /usr/share/keyrings/ | grep google; ls /opt/google
The browser directory was gone, but both source files and both keyrings were still there, so apt update keeps checking Google’s repositories:
google-chrome-beta.sources
google-chrome.sources
ubuntu.sources
google-chrome-beta.gpg
google-chrome.gpg
ls: cannot access '/opt/google': No such file or directory
That’s deliberate, since it lets a later reinstall pick up updates straight away. To remove Chrome for good, purge it instead, which also runs the cleanup that deletes the source files and keyrings. As before, leave out the beta if you never installed it:
sudo apt purge -y google-chrome-beta google-chrome-stable
After the purge, only Ubuntu’s own source remained. x-www-browser had already fallen back to Firefox when the package was removed. Three things survive either apt verb, because apt never touches your home directory:
~/.config/google-chrome, the profile (158 MB in our test)~/.cache/google-chrome, the disk cache- a stale
google-chrome.desktopline in~/.config/mimeapps.list
Delete the two directories only if you are sure you don’t want the bookmarks, saved passwords and extensions in them. A reinstall without them starts again from the first-run dialogs, so keep a copy if you might come back.
rm -rf ~/.config/google-chrome ~/.cache/google-chrome
GNOME already sends links to Firefox once Chrome is gone, but the old entry stays in mimeapps.list until something overwrites it. Setting the default explicitly rewrites the file:
xdg-settings set default-web-browser firefox_firefox.desktop
If you’re setting up a new machine, the Ubuntu 26.04 desktop install guide covers the steps before this one. Our comparison of snap vs Flatpak vs apt on Ubuntu 26.04 explains why Chrome is one of the apps where the .deb is the right call. The same package also works on Mint, covered in our guide to Chrome on Linux Mint, and Brave on Ubuntu uses a very similar apt repository setup if you want a second Chromium-based browser.