Guides

How to install a .deb file on Ubuntu: apt, dpkg and gdebi

To install a deb file on Ubuntu, run sudo apt install ./file.deb so apt pulls in the dependencies. Plus dpkg -i, gdebi, inspecting, removing and errors.

Published ~10 min read
On this page

Short answer: open a terminal in the folder that holds the file and run sudo apt install ./name.deb. apt installs the package and fetches every dependency it lists from Ubuntu’s repositories. The ./ matters: without a path, apt searches its repositories for a package literally called name.deb and stops with Unable to locate package.

Ubuntu · Debian
cd ~/Downloads
sudo apt install ./mytool_1.4.2_amd64.deb

The apt and dpkg output on this page comes from a small test package built and checked on Debian 12 (dpkg 1.21.23, apt 2.6.1), installed into a throwaway directory rather than a live system. Ubuntu uses the same two programs, so the commands are identical there.

Cheat sheet

TaskCommand
Install, with dependenciessudo apt install ./app.deb
Install several files at oncesudo apt install ./*.deb
Preview what would happenapt install -s ./app.deb
Install with dpkg, then fix dependenciessudo dpkg -i app.deb; sudo apt --fix-broken install
Show name, version, dependenciesdpkg -I app.deb
List the files insidedpkg -c app.deb
Print only the package namedpkg-deb -f app.deb Package
Is it installed, which version?dpkg -s NAME
Files it installeddpkg -L NAME
Remove itsudo apt remove NAME
Remove it and its config filessudo apt purge NAME
Remove dependencies nothing needs nowsudo apt autoremove

sudo apt install ./file.deb: the method to use

Give apt anything that looks like a path, meaning it contains a slash, and it treats the argument as a file instead of a package name: ./app.deb, ~/Downloads/app.deb and /tmp/app.deb all work. apt reads the dependencies out of the file, finds them in your configured repositories, and installs everything in the right order. Several files at once (sudo apt install ./*.deb) is the way to install a program a vendor splits into packages that depend on each other.

Preview first with -s

-s simulates the whole run without changing anything and needs no sudo. On the test package, which depends on jq:

apt install -s ./mytool_1.4.2_amd64.deb · Debian 12
The following additional packages will be installed:
  jq libjq1
The following NEW packages will be installed:
  jq libjq1 mytool
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Inst libjq1 (1.6-2.1+deb12u3 Debian-Security:12/oldstable-security [amd64])
Inst jq (1.6-2.1+deb12u3 Debian-Security:12/oldstable-security [amd64])
Inst mytool (1.4.2 local-deb [amd64])
Conf libjq1 (1.6-2.1+deb12u3 Debian-Security:12/oldstable-security [amd64])
Conf jq (1.6-2.1+deb12u3 Debian-Security:12/oldstable-security [amd64])
Conf mytool (1.4.2 local-deb [amd64])

local-deb marks the file you supplied; the two other packages come from the distribution’s archive (on Ubuntu the lines name the Ubuntu release instead). The real run prints the same plan, asks Do you want to continue? [Y/n] when it needs extra packages, then downloads and installs. Ubuntu 26.04 and Debian 13 ship APT 3, which shows the same information in a new layout, under headings such as Installing: and Installing dependencies:.

The “Download is performed unsandboxed” notice

apt output
N: Download is performed unsandboxed as root as file '/root/mytool_1.4.2_amd64.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)

Harmless. apt normally reads files through an unprivileged _apt user, which cannot open a private directory such as /root or a home folder with tight permissions, so it reads the file as root instead and carries on. The install still completes. Put the file in /tmp before installing and the notice goes away.

dpkg -i: the low-level way, and fixing what it leaves behind

dpkg is the tool underneath apt. It installs exactly the file you hand it and never downloads anything, so a package with a missing dependency gets unpacked but not set up:

sudo dpkg -i mytool_1.4.2_amd64.deb · dependency missing
Selecting previously unselected package mytool.
Preparing to unpack mytool_1.4.2_amd64.deb ...
Unpacking mytool (1.4.2) ...
dpkg: dependency problems prevent configuration of mytool:
 mytool depends on libfoo2 (>= 2.0); however:
  Package libfoo2 is not installed.

dpkg: error processing package mytool (--install):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 mytool

dpkg -l mytool now shows the state iU: unpacked, not configured. apt refuses to install anything else until that is settled and points you at the fix itself:

Ubuntu · Debian
sudo apt --fix-broken install      # same as: sudo apt -f install

apt either installs the missing dependencies and finishes the configuration, or, if it cannot find them anywhere, offers to remove the half-installed package. Read the list it shows before you answer Y. If dpkg itself was cut off in the middle (a dropped SSH session, a reboot), the error is a different one, and dpkg was interrupted covers it. Today dpkg -i mostly makes sense for installing a set of files on a machine without network access; everywhere else, apt install ./ does the same job and handles dependencies.

gdebi and the App Center

gdebi is a small installer for local .deb files. Like apt, it resolves dependencies from your repositories; unlike dpkg -i, it checks them before touching the system and refuses outright if they cannot be met, rather than leaving a half-installed package. Since apt learned to install local files it is mostly a matter of habit:

Ubuntu · Debian
sudo apt install gdebi-core
sudo gdebi mytool_1.4.2_amd64.deb

On Ubuntu Desktop 24.04, the App Center opens local .deb files again since an update in July 2024: right-click the file, choose Open With, then App Center, and it warns that the package comes from a third party before installing. If a double-click opens the archive manager instead, use the terminal command above.

Look inside a .deb before you install it

A .deb is an archive with two parts: control data (name, version, dependencies, scripts) and the files themselves. dpkg reads both without installing anything:

dpkg -I mytool_1.4.2_amd64.deb
 new Debian package, version 2.0.
 size 1132 bytes: control archive=620 bytes.
     320 bytes,    11 lines      control
     114 bytes,     2 lines      md5sums
      81 bytes,     4 lines   *  postinst             #!/bin/sh
 Package: mytool
 Version: 1.4.2
 Architecture: amd64
 Maintainer: Example Vendor <packages@example.com>
 Installed-Size: 12
 Depends: jq (>= 1.6)
 Section: utils
 Priority: optional
 Homepage: https://example.com/mytool
 Description: example command-line tool
  A small example package used to show how dpkg inspects a .deb file.
  • Architecture has to match your system, which dpkg --print-architecture prints: amd64 on x86-64 PCs and servers, arm64 on 64-bit ARM. all means the package runs anywhere.
  • Depends is what apt will pull in alongside it.
  • postinst (and preinst, prerm, postrm when present) are maintainer scripts. dpkg runs them as root during installation and removal.
dpkg -c mytool_1.4.2_amd64.deb
drwxr-xr-x root/root         0 2026-10-21 12:22 ./
drwxr-xr-x root/root         0 2026-10-21 12:22 ./usr/
drwxr-xr-x root/root         0 2026-10-21 12:22 ./usr/bin/
-rwxr-xr-x root/root        30 2026-10-21 12:22 ./usr/bin/mytool
drwxr-xr-x root/root         0 2026-10-21 12:22 ./usr/share/
drwxr-xr-x root/root         0 2026-10-21 12:22 ./usr/share/doc/
drwxr-xr-x root/root         0 2026-10-21 12:22 ./usr/share/doc/mytool/
-rw-r--r-- root/root         8 2026-10-21 12:22 ./usr/share/doc/mytool/copyright

To read the scripts, or to try the program without installing it, unpack the parts:

any Debian or Ubuntu system
dpkg-deb -e mytool_1.4.2_amd64.deb control/    # control file and maintainer scripts
cat control/postinst
dpkg-deb -x mytool_1.4.2_amd64.deb files/      # the files, without installing anything

Verify where the file came from

  • Download from the vendor’s own site or the project’s official release page, over HTTPS, not from a mirror site or a forum attachment.
  • Compare the checksum when the vendor publishes one: sha256sum app.deb prints the hash to compare by eye, and with the vendor’s checksum file next to it, sha256sum -c SHA256SUMS --ignore-missing answers app.deb: OK or FAILED. If the vendor also signs that file, check the signature with gpg --verify against their published key.
  • Make sure it is a package at all. file app.deb should say Debian binary package; a download link that needs a browser can leave you with an HTML page saved under a .deb name.

Why a repository beats a downloaded .deb

A package installed from a file is not tied to any source, so apt upgrade never updates it. apt policy makes that visible: the only place it knows the package from is dpkg’s own status file.

apt policy mytool
mytool:
  Installed: 1.4.2
  Candidate: 1.4.2
  Version table:
 *** 1.4.2 100
        100 /var/lib/dpkg/status

So before downloading anything, check whether Ubuntu already packages it (apt policy NAME, apt search NAME) and whether the vendor offers an APT repository; adding the repository gets you the same program plus its updates. Some vendor packages add their repository on their own during installation (Google Chrome’s does), so look in /etc/apt/sources.list.d/ afterwards: if a new file appeared there, the next apt upgrade keeps the program current. When the package name is right but apt still cannot find it, the repository side is explained in Unable to locate package. If a repository also carries the package and you want to keep your hand-installed version, hold it with sudo apt-mark hold NAME.

Remove a package you installed from a .deb

apt and dpkg know the package by its name, not by the file name. Read the name from the file, or search the installed list:

Ubuntu · Debian
dpkg-deb -f mytool_1.4.2_amd64.deb Package   # prints the name: mytool
dpkg -l | grep -i mytool                      # or find it among installed packages
sudo apt remove mytool                        # remove the program, keep its config files
sudo apt purge mytool                         # remove it together with its config files
sudo apt autoremove                           # remove dependencies nothing needs any more

The dependencies apt pulled in for the package (jq and libjq1 in the example) are marked as automatically installed, so autoremove clears them once nothing else needs them. dpkg -L mytool lists every file the package put on the system, if you want to see what goes before removing it.

Errors when installing a .deb, and the fix

E: Unable to locate package app.deb

sudo apt install mytool_1.4.2_amd64.deb
E: Unable to locate package mytool_1.4.2_amd64.deb
E: Couldn't find any package by glob 'mytool_1.4.2_amd64.deb'
E: Couldn't find any package by regex 'mytool_1.4.2_amd64.deb'

The path is missing, so apt went looking for a package with that name. Add ./ in front, or give the full path.

The following packages have unmet dependencies

sudo apt install ./mytool_1.4.2_amd64.deb
The following packages have unmet dependencies:
 mytool : Depends: libfoo2 (>= 2.0) but it is not installable
E: Unable to correct problems, you have held broken packages.

apt knows no package that satisfies the dependency. Usually the file was built for a different release or distribution (a newer Ubuntu with newer libraries, or Debian instead of Ubuntu), so download the build for your release; its codename comes from . /etc/os-release && echo "$VERSION_CODENAME". Sometimes the dependency exists but sits in a repository component you have not enabled, such as universe: see enabling a missing component. Forcing the install with dpkg’s --force-depends only moves the failure to the moment the program starts.

dependency problems - leaving unconfigured

That is the dpkg -i failure shown above. Run sudo apt --fix-broken install.

package architecture (arm64) does not match system (amd64)

dpkg output
dpkg: error processing archive mytool_1.4.2_arm64.deb (--install):
 package architecture (arm64) does not match system (amd64)

You downloaded the build for another processor. Compare the Architecture line of dpkg -I with dpkg --print-architecture and fetch the matching file. The refusal comes from dpkg when it unpacks the file: in the test, apt’s simulation happily planned the install of the arm64 file, so do not take a clean preview as proof.

dpkg-deb: error: 'app.deb' is not a Debian format archive

The file is not a package. In the test, an HTML page saved as page.deb produced exactly this, and file page.deb answered HTML document. Copy the direct download link, fetch it again with curl -fLO or wget, and compare the checksum.

Could not get lock, or dpkg was interrupted

Neither is about your file. Another apt process (often the automatic updater) holds the package database, or an earlier run stopped half way. Fix those first with Could not get lock /var/lib/dpkg/lock-frontend and dpkg was interrupted, then run the install again.

trying to overwrite '/usr/bin/x', which is also in package y

Two packages ship the same file: often an older build of the same program installed under a different package name, or a vendor package that collides with one from Ubuntu. Remove the other package first. --force-overwrite exists, but it leaves two packages claiming one file, and the next update of either breaks it again.

Installing a .deb on a server

On a VPS there is no browser to click a download button. Copy the direct link to the .deb from the vendor’s release page and fetch it on the server, into /tmp, which also avoids the _apt notice:

Ubuntu · Debian server
cd /tmp
curl -fLO https://example.com/downloads/mytool_1.4.2_amd64.deb
sha256sum mytool_1.4.2_amd64.deb      # compare with the vendor's published value
sudo apt install ./mytool_1.4.2_amd64.deb

-f makes curl fail on an HTTP error instead of saving the error page as your package, and -L follows the redirects most release pages use. If the server answers curl: command not found, see installing curl. VMHeaven VPS run on x86-64, so the amd64 build is the right one, and the commands are the same on an Ubuntu VPS and a Debian VPS.

Frequently asked

How do I install a .deb file from the terminal on Ubuntu?

Run sudo apt install ./file.deb in the folder that holds the file, or give its full path. apt installs the package and downloads every dependency it lists from Ubuntu's repositories. Without the ./ (or another path with a slash), apt looks for a package named file.deb in its repositories and fails with Unable to locate package.

What is the difference between apt install ./file.deb and dpkg -i?

dpkg -i installs only the file you give it and never downloads anything, so a package with missing dependencies is left unpacked but not configured. apt install ./file.deb resolves and installs those dependencies first. After a failed dpkg -i, sudo apt --fix-broken install finishes the job or offers to remove the package.

How do I uninstall a program installed from a .deb file?

Use the package name, not the file name: dpkg-deb -f file.deb Package prints it. Then sudo apt remove NAME removes the program, sudo apt purge NAME also deletes its configuration files, and sudo apt autoremove clears the dependencies that were installed only for it.

Does a package installed from a .deb file get updates?

Only if it also added a repository. A plain .deb is not linked to any source, so apt upgrade never touches it, and apt policy NAME lists only /var/lib/dpkg/status. Some vendor packages, Google Chrome's for example, add their own APT repository during installation, and from then on updates arrive with your normal apt upgrade.

Related articles

All guides