Third Party Packages
We've just done a big upgrade of the existing packages on our system. Let's now knock down two bottles with a single stone:
- Install a new, third-party repository
- Install some new software from the repository
Adding Apt Repositories
We need to install nginx, a web server, so that we can serve a static website from our server. The repository is maintained by the official nginx developers at nginx.org and it offers the latest versions of nginx available.
First, nginx has some dependencies before it can run, so let's install those now. We're about to use apt install for the first time.
That installed only 1 new package on my system. Your results might vary.
Now we need a GPG key. This is a public key like cryptographic component that's used to securely sign the packages inside the repository. This helps to guarantee that the package you download was created by the nginx developers and hasn't been changed whilst you were downloading it to your system. Apt takes care of checking all of this for you.
Run this: curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
superman@develop:~$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1561 100 1561 0 0 1255 0 0:00:01 0:00:01 --:--:-- 1255
We're using a very powerful tool called curl to download https://nginx.org/keys/nginx_signing.key (note how it's downloading over HTTPS? That makes downloading this file secure.) We then pipe (|) the stdout from the curl command into the stdin of the gpg command. The gpg command then saves the signing key locally and it can now be used to verify packages from the nginx developers and their apt repository. We can even test this: gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
superman@develop:~$ gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid nginx signing key <signing-key@nginx.com>
We have a public key that will expire in 2024-06-14.
Now let's add the Apt repository:
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
And I get:
superman@develop:~$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
> http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
> | sudo tee /etc/apt/sources.list.d/nginx.list
deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu focal nginx
We're using echo to print a string. The string has some sneaky tricks embedded in it:
What this is doing is calling the (local) command lsb_release with the -cs flags, and then substituted itself in the string with the results. Compare these strings:
deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx"
Versus:
deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu focal nginx
Notice in the second string we don't have lsb_release -cs, we have focal? Run the command: lsb_release -cs
So echo is using that embedded little trick to execute the lsb_release command inside the string so the value is replaced with the current version of Ubuntu you're running.
Now we have a string you've seen before (with a slight difference): deb <signing-key> <url> <distribution> <repository>. The <signing-key> field is used to tell Apt that the GPG key we downloaded earlier should be used to check the packages are secure and coming from the original authors unedited or not corrupted.
Finally, we update the list of packages we have available and then install nginx:
My apt update got me some new packages:
superman@develop:~$ sudo apt update
...
Get:6 http://nginx.org/packages/ubuntu focal InRelease [3,584 B]
Get:7 http://nginx.org/packages/ubuntu focal/nginx amd64 Packages [15.7 kB]
...
And my apt install installed nginx for me:
superman@develop:~$ sudo apt install nginx
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
libfwupdplugin1
Use 'sudo apt autoremove' to remove it.
The following NEW packages will be installed:
nginx
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 879 kB of archives.
After this operation, 3,117 kB of additional disk space will be used.
Get:1 http://nginx.org/packages/ubuntu focal/nginx amd64 nginx amd64 1.20.2-1~focal [879 kB]
Fetched 879 kB in 3s (258 kB/s)
Selecting previously unselected package nginx.
(Reading database ... 108473 files and directories currently installed.)
Preparing to unpack .../nginx_1.20.2-1~focal_amd64.deb ...
----------------------------------------------------------------------
Thanks for using nginx!
Please find the official documentation for nginx here:
* https://nginx.org/en/docs/
Please subscribe to nginx-announce mailing list to get
the most important news about nginx:
* https://nginx.org/en/support.html
Commercial subscriptions for nginx are available on:
* https://nginx.com/products/
----------------------------------------------------------------------
Unpacking nginx (1.20.2-1~focal) ...
Setting up nginx (1.20.2-1~focal) ...
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for systemd (245.4-4ubuntu3.15) ...
Whenever you're installing from the default, included Canonical repositories, you only need to use sudo apt install. You don't have to keep adding repositories like we have above. This was to demonstrate adding a new repository and installing software.
Simple.