This post is basically a note to the future me and describes the software I install on a fresh linux machine. My linux boxes are usually Ubuntu or Mint, sometimes Debian for servers, but in all cases, they are Debian-based.

Before starting, don’t forget to update the repositories in order to install the latest versions:

1sudo apt update
2sudo apt upgrade

and after having installed all what you need, purge what is not necessary anymore:

1sudo apt autoremove
2sudo apt autoclean

The bare minimum to survive

Editing text

By default there is vim, but personally I just can’t. I’ve been using emacs for more than 30 years. I also use jed on the console as it is a very acceptable emacs clone. jed is a small (~375KB where vim is ~1.7MB) emacs-like editor customisable in a language called S-Lang. jed had been around since about 30 years and I’ve used it on an OS/2 Warp machine because emacs was unstable. See John E. Davis Software page. If size is really an issue, zile or nano are smaller Yet, zile lacks some nice features Jed offers, and nano is really basic and has a totally different keyboard layout.

1sudo apt install jed emacs # zile

To get spellchecking in various languages, you need to install aspell and the languages’ dictionaries, for example aspell-fr and aspell-en for French and English.

1sudo apt install aspell aspell-fr aspell-en
2aspell dump dicts

You also need to configure emacs:

1;; spell checking
2(setq ispell-program-name "aspell")
3(add-hook 'text-mode-hook 'flyspell-mode) ;; spell text modes
4(add-hook 'prog-mode-hook 'flyspell-prog-mode) ;; spell comment in programs
5(ispell-change-dictionary "english")
6;; (ispell-change-dictionary "francais")

Terminal tools

Linux is equipped with almost all tooling that is required for regular administration. Yet, sometimes, those tools can be replaced with more ergonomic counterparts.

  • In the early dark days, we had ps. Then arrived top which showed the most resource consuming processes as a self updating list in terminal. A much nicer alternative is btop which shows CPU, RAM, etwork usage and processes with UTF8 graphics in the terminal. Another one is htop, simpler but much smaller.

  • tree offers an elegant pseudo-graphical view of directories.

  • For a quick rendering of HTML files (for example documentations) in a terminal lynx or links are the right tools to use. Personally, lynx is my favorite.

1sudo apt install btop htop tree lynx

Network services access

  • ssh is nice to access some remote server is fine, as long as you keep typing and as long as there is no networks issues to avoid disconnections and remote work crash. Otherwise, use a terminal multiplexer, like screen or tmux. I personally use tmux. Here is nive a beginer’s guide.
  • httpie provides http and https CLI utilities to query HTTP services and getting replies in a user-friendly format. Sure, curl and wget exist and I use them too, but http and https are nice alternatives.
  • lftp is an FTP terminal client which can be used in scripts and which proposed nicer interactive features over basic ftp. Not the only one but it’s the one I use.
  • shhfs auser@my.domain.com:/home/auser ~/mnt mounts the auser’s home directory on the local machine on ~/mnt. Useful for scripts that already work locally, for example.
1sudo apt install tmux httpie curl wget lftp sshfs

Programming

My main activity on my machine is programming (today as a hobby) and documenting what I develop, exploring some ideas, etc. The two basic tools are emacs for programming and git for version controlling, already discussed above.

Programming tools

  • git, of course for version controlling.

  • Whenever I deal with JSON, typically for APIs, I love using jq which cleanly displays, filters, transforms, etc. JSON files.

  • yq is another Swiss army knife to deal with YAML, JSON, INI and XML. For JSON, it uses jq under the hood.

1sudo apt install jq yq git

Programming languages

ASDF: the The Multiple Runtime Version Manager

For years, I was fighting with languages’ versions until I discovered asdf. asdf is a version manager: it manages different versions of the same application’s runtimes, for example, but not limited to, languages.

There is no asdf Debian/Ubuntu package (or at least I didn’t find it), but pre-compiled binaries are available for main architectures on Github. Once downloaded, the archive contains one executable, asdf, that should be moved in a directory in the PATH. Finally, let’s add the directory where asdf will store the applications’ executables to the PATH: add the line export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH" to ~/.bashrc

asdf works with plugins where each plugin knows how to install a given version of the application it manages. To list all what asdf can manage type asdf plugin list all. This will list 845 (as of today) plugins.

Installing Java and Groovy

As a first example let’s install the Groovy language. I use it to run a CLI podcast downloader I wrote years, years ago and that I’m too lazy to rewrite. Groovy being based on Java, let’s install Java first.

To install an app (or a language) with asdf, we first need to add the right plugin. Type asdf plugin list all | grep java to get the name of the plugin, and add it:

1asdf plugin list all | grep java
2  java           https://github.com/halcyon/asdf-java.git
3asdf plugin add java
4asdf list
5java
6  No versions installed

asdf list lists all installed applications. Here it says we have installed the java plugin but not the Java language runtime itself. We could have also typed asdf plugin list to only get information about installed plugins. To install an application, we need to specify a version. To get all the versions of the Java programming language, type asdf list all java (spoiler alert, there are more than 6000 possibilities…). Let’s get the latest openjdk:

 1# what openjdk versions are available
 2asdf list all java | grep openjdk
 3  openjdk-9
 4	...
 5	openjdk-27
 6# Install version 27
 7asdf install java openjdk-27   # This will take some time
 8
 9# Check it had been installed
10asdf list
11  java
12    openjdk-27                 # The correct version is installed
13
14# Make it the default version
15asdf set -u java openjdk-27
16
17# Check if installed:
18java -version
19  openjdk version "27" 2026-09-15
20  ...

With the same procedure, you may want to install another version and test it:

 1asdf install java openjdk-12
 2asdf list java
 3  openjdk-12      # Installed
 4  *openjdk-27     # The star shows which one is active
 5asdf set -u java openjdk-12
 6asdf list java
 7   *openjdk-12    # Looks good
 8    openjdk-27
 9java -version
10  openjdk version "12" 2019-03-19

We are now ready to install Groovy

 1asdf plugin list all | grep groovy
 2  groovy       https://github.com/weibemoura/asdf-groovy.git
 3asdf plugin add groovy
 4asdf list all groovy
 5  2.4.4
 6	...
 7	6.0.0-beta-3
 8asdf install groovy 5.1.2   # the last stable version
 9asdf set -u groovy  5.1.2
10asdf list groovy
11  *5.1.2                    # Great!
12groovy -version
13  Groovy Version: 5.1.2 JVM: 12 Vendor: Oracle Corporation OS: Linux

And voilĂ !

Installing Erlang and Elixir

Since some years, my favorite language is Elixir. Elixir is based on another monument which is Erlang. As for Groovy and Java, Erlang needs to be installed first.

A small difficulty here is that the straight installation as we did for Java will omit two important features: cryptography (ssl will not work) and wxWidgets (observer, dedugger and other X applications will not work).

The first part is to install some libraries at system level:

1sudo apt install -y \
2  build-essential autoconf m4 libncurses-dev libssh-dev \
3  unixodbc-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev \
4  libssl-dev \
5  libwxgtk3.2-dev libwxgtk-webview3.2-dev \
6  fop xsltproc libxml2-utils \
7  curl git

Then we can install the asdf plugins for Erlang and Elixir:

1asdf plugin add erlang
2asdf plugin add elixir

For its installation, Erlang will be compiled by asdf. We need to force the compilation with ssl and wx:

 1export KERL_CONFIGURE_OPTIONS="--with-ssl --with-wx"
 2# latest version found with 'asdf list all erlang'
 3version="29.0.6"
 4
 5asdf install erlang $version
 6asdf set -u erlang $version
 7
 8# Check the version
 9erl -v
10  Erlang/OTP 29 [erts-17.0.6] [source] [64-bit] ...

Now we are ready to do the same with Elixir:

 1# latest version found with 'asdf list all elixir'
 2version="1.20.4-otp-29"
 3
 4asdf install elixir $version
 5asdf set -u elixir $version
 6
 7# Check the version
 8elixir -v
 9  ...
10  Elixir 1.20.4 (compiled with Erlang/OTP 29)

Other useful stuff managed by ASDF

I use ASDF to make easily tests with some programming languages. ASDF has plugins to most of them: Ruby, Lua, SWIProlog, SBCL (Steel Bank Common Lisp), Rust, Go, Clojure, V, Zig, C3, Odin and of course (and unfortunately), Javascript as NodeJS or Deno.

It’s always the same procedure:

1asdf plugin add golang
2asdf list all golang
3asdf install golang 1.27.1
4asdf set -u golang 1.27.1

Office

WYSIWYG

  • You like it or not, Microsoft Office is the de facto document standard in the professional word. You may want to run Office in Wine, but there are Linux native alternatives to be considered. Libre Office is one such alternatives. It usually comes preinstalled on desktop distributions. My experience is that it’s interface is outdated and formatting if definitely not perfect.

    Free Office is another alternative. OK, it’s not open source, but the interface id much closer to Microsoft’s (which I have to use at work…) and the rendering is just fine. To install it:

    1curl -fsSL \
    2  https://softmaker.net/down/install-softmaker-freeoffice-2024.sh \
    3| sudo bash
    

    You will have to install a licence, but it’s free for personnal use and the professional 2026 licence costs 150USD for 5 licences.

Drawing

  • DrawIO is probably one of the best vector drawing application around. It’s available online and as a desktop Java-based application.

    Unfortunately, it’s not in Debian/Ubuntu/Mint repositories, but a .deb package is available on Github. Once downloaded from https://github.com/jgraph/drawio-desktop/releases/)., simply install it with sudo dpkg -i ~/Downloads/drawio-amd64-31.4.5.deb

  • For quick manipulations (resize, crop, color to black and white, etc.) of bitmaps I use mtpaint. If I could, I would reinstall xv that I used in the 90’s on Sun workstations and early linuxes but I couldn’t find it. mtpaint is basic, but it does quickly what I need without the need to read tutorials and documentations for hours.

    To install: sudo apt install mtpaint

  • graphviz is a great tool to draw graphs of many kinds from their textual definition. Simply

    To install sudo apt install graphviz

  • plantuml is another Java-based tool to generate diagrams from text. As it’s name suggests, it was first designed for UML diagrams (sequence, class, activity, etc), but it is constantly being extended with other types of diagrams like Gantt, RegEx, MindMap, network, and many more.

    To install: sudo apt install plantuml

Typesetting and generating HTML or PDF

  • Long ago I discovered LaTeX. It was like an electroshock: I didn’t need any more to style a document while I was writing it! typst is the modern successor of LaTeX. It doesn’t have as much libraries and styles a LaTeX (yet, the situation is improving almost every day), but it’s fast (really fast), it has an embedded language for extensions and customisations and it generates PDF and HTML files. It is also available via ASDF.

    1asdf plugin add typst
    2asdf list all typst
    3asdf install typst 0.15.1
    4asdf set -u typst 0.15.1
    
  • A more trivial tool is Markdown. There are dozens of versions and the tool that tries to gather all versions along with many other formats (Typst, LaTeX, Word, Roff, …) is PanDoc.

    1sudo apt install pandoc
    

Publishing on the web

This blog, but also my personal documentation on my home server are powered by Hugo. Hugo is a static web site generator. Hugo is available with apt or ASDF.

To install: sudo apt install hugo

Virtualization

Containers

Containers are probably the bigest recent (well, not that recent anymore) revolution in the way applications are distributed and ran. Here we’ll be installing Docker, but keep in mind that there are good and robust alternatives as for example Podman, a Docker alternative that probably is safer and faster (One day, I’ll have to give it a try), or LXC.

Docker

To install Docker with apt we need to install the Docker repository. What follows comes from Docker Docs:

  1. First add Docker’s GPG key

    1sudo apt update
    2sudo apt install ca-certificates curl
    3sudo install -m 0755 -d /etc/apt/keyrings
    4sudo curl -fsSL \
    5  https://download.docker.com/linux/ubuntu/gpg \
    6  -o /etc/apt/keyrings/docker.asc
    7sudo chmod a+r /etc/apt/keyrings/docker.asc
    
  2. Then add the repository to Apt sources

     1sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
     2Types: deb
     3URIs: https://download.docker.com/linux/ubuntu
     4Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
     5Components: stable
     6Architectures: $(dpkg --print-architecture)
     7Signed-By: /etc/apt/keyrings/docker.asc
     8EOF
     9
    10sudo apt update
    
  3. And eventually, install Docker

    1sudo apt install \
    2  docker-ce docker-ce-cli containerd.io \
    3  docker-buildx-plugin docker-compose-plugin
    

Verifying installation and running test container

We first need to check that Docker daemon is running and if not start it:

1sudo systemctl status docker
2# If it doesn't run:
3# sudo systemctl start docker

To verify the installation there is a hello-world image that displays a welcome message if all goes fine:

1sudo docker run hello-world
2Unable to find image 'hello-world:latest' locally
3latest: Pulling from library/hello-world
44f55086f7dd0: Pull complete
5...
6Hello from Docker!
7This message shows that your installation appears to be working correctly.
8...

Notice that to run a container, you need to belong to group docker. So either you need to run sudo docker ... or to make yourself belong to the docker group. This second solution is much more convenient, but is a way to gain root privileges. For my home machine that stays on my desk, I chose that option:

1sudo usermod -aG docker $USER   # add docker group to my profile
2newgrp docker                   # change my group ID 
3groups                          # validate I belong to that group
4docker run hello-world          # check it works

Notice also that this works only in the terminal where you typed newgrp docker. For a definitive solution, you need to logout and login again.

Running MariaDB

One of main usage I do of Docker is to build and run database architectures that are as close as possible to the future production and that do not perturb the database configurations of other projects. I mostly use MariaDB.

To run a DB named mydb:

 1export db_name="mydb"
 2export db_user=${db_name}_user
 3export db_pass=${db_name}_pass
 4export db_root=${db_name}_r00t_p@sswOrd
 5
 6docker run -i --rm --name ${db_name} \
 7-v "$(pwd)/data:/var/lib/mysql/" \
 8-p "3306:3306" \
 9-e MARIADB_DATABASE=${db_name} \
10-e MARIADB_USER=${db_user} \
11-e MARIADB_PASSWORD=${db_pass} \
12-e MARIADB_ROOT_PASSWORD=${db_root} \
13-d mariadb:10.10-jammy

To access the database we need a client. mycli is good at it but the good old mysql works also fine:

1sudo apt install mycli mysql-client

An eventually:

1mycli -h 127.0.0.1 -u ${db_user} --password=${db_pass} ${db_name}
2MariaDB mydb_user@127.0.0.1:mydb> show databases
3+--------------------+
4| Database           |
5+--------------------+
6| information_schema |
7| mydb               |
8+--------------------+
9...

Looks like it works!

x86 virtual machines

The straight forward way is VirtualBox. You get a GUI to create and execute virtual machines. Yet, I don’t like it a lot.

The native Linux solution is to use KVM and QEMU. All dependencies are automatically pulled if you install bridge-utils and virt-manager:

1sudo apt install bridge-utils virt-manager libosinfo-bin

Once done, start virt-manager to get the management GUI which allows to create, configure, run, destroy and manage the VMs. If you get authorization errors, you may need to add yourself to libvirt and kvm: sudo usermod -aG libvirt,kvm $USER and restart the session.

To create a VM on the command line, use virt-install. For example a NetBSD VM:

1virt-install --name netbsd-10.1 \
2  --ram 4096 --vcpus 2 \
3  --disk path=/var/lib/libvirt/images/netbsd-10.1.qcow2,size=20 \
4  --os-variant netbsd10.0 \
5  --network bridge=virbr0 \
6  --graphics spice \
7  --cdrom ~/Downloads/ISOs/NetBSD-10.1-amd64.iso

Then you can play with virsh:

1virsh list --all              # List all available VMs
2virsh start  netbsd-10.1      # Start the VM we just created
3virt-viewer netbsd-10.1       # Displays the graphical window
4virsh shutdown netbsd-10.1    # To cleanely stop the VM

Conclusion

Hi my future me. All we have installed so far makes a fresh machine usable for your needs. It has the basic CLI tools, our favourite languages and the simple virtualization methods.

Go and get yourself a beer to thank me to have spent all this time on this document. And never forget to have fun