Skip to content

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:

  1. Install a new, third-party repository
  2. 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.

1
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring

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

1
2
3
4
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

1
2
3
4
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:

1
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:

1
2
3
4
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:

1
`lsb_release -cs`

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:

1
deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx"

Versus:

1
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

1
2
superman@develop:~$ lsb_release -cs
focal

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:

1
2
sudo apt update
sudo apt install nginx

My apt update got me some new packages:

1
2
3
4
5
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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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.