Every server I provision starts out headless, no exceptions — it’s just leaner and safer that way. But every so often I need a GUI on a box I’d normally never put one on: a temporary development VM, a machine running something like Cockpit or phpMyAdmin where I’d rather click around than fight with curl, or occasionally just a training environment for someone still getting comfortable with Linux. GNOME is Ubuntu’s default desktop environment, and installing it after the fact from a minimal Ubuntu Server install is a completely supported, well-trodden path. I want to walk through it properly here — the actual install, the package choices, the display manager decisions, and how to undo all of it cleanly if you change your mind.
What GNOME Is, Briefly
GNOME is a full desktop environment — window manager, panel/dock, file manager, settings app, and a curated set of default applications, all built on GTK. It’s what ships by default on a standard Ubuntu Desktop ISO install. When you install Ubuntu Server, none of this is present; you get a bare command-line environment by design, to keep resource usage and attack surface minimal. Installing GNOME afterward brings that same desktop experience to an existing server install.
Before You Start: Update the System
Always begin with a full update, since installing over a thousand new packages on top of a stale package cache is asking for dependency conflicts:
sudo apt update
sudo apt upgrade -y
Choosing Your Installation Method: apt vs. tasksel
There are two supported approaches, and they produce essentially the same result.
Method 1: Direct apt Install (What I Actually Use)
This is the method I reach for, because it gives clear visibility into exactly what’s being installed rather than going through an interactive menu:
sudo apt install ubuntu-desktop -y
This is the full metapackage — it pulls in GNOME itself plus Ubuntu’s default application set (Firefox, LibreOffice, the Files app, Terminal, and so on) and the GNOME Display Manager (GDM3). It’s a large install — expect well over a gigabyte of downloads and considerably more once unpacked.
If you want GNOME itself without the full curated app bundle, there’s a lighter option:
sudo apt install ubuntu-desktop-minimal -y
This installs the core GNOME shell and essential components without the extras — a meaningfully smaller footprint, and my preferred choice for a VM or server where I just need a working GUI, not a full productivity suite.
Method 2: tasksel
tasksel is a Debian/Ubuntu utility that presents a curated menu of installable “tasks” — bundles of related packages for a specific role (desktop environment, LAMP server, mail server, and so on):
sudo apt install tasksel -y
sudo tasksel
This opens an interactive text-based menu (navigate with arrow keys, select with Space, confirm with Enter on “OK”). Choose “Ubuntu desktop” for the full install. You can also skip the interactive menu entirely and specify the task directly on the command line, which is what I’d actually use in an automated provisioning script:
sudo tasksel install ubuntu-desktop
Both methods end up installing essentially the same package set — I use apt directly for anything I’m scripting or doing personally, and tasksel mainly when walking someone else through the process interactively, since the menu is more approachable for a first-timer.
What Happens During Install
Expect the process to take anywhere from five to twenty minutes depending on your connection and disk speed — it’s downloading and unpacking well over a thousand packages. Partway through, you may be prompted to choose or confirm a display manager. Ubuntu’s default is GDM3 (GNOME Display Manager), which is the natural choice if you’re staying with GNOME — it has native Wayland support and integrates most cleanly with GNOME specifically. If a different display manager (like LightDM) is already installed from a prior desktop environment attempt, you’ll be asked which one should own the actual login screen; pick GDM3 for the smoothest GNOME experience.
After Installation: Reboot and Log In
sudo reboot
Once the system comes back up, you should land on the GDM3 graphical login screen instead of a text console. Log in with your normal user credentials, and GNOME should load directly.
Verifying and Managing the Display Manager Manually
If for any reason the graphical login screen doesn’t appear automatically, or you want to confirm/set which display manager is active:
sudo dpkg-reconfigure gdm3
This reopens the same display-manager selection prompt shown during install, letting you explicitly choose GDM3 (or another installed display manager) as the system default.
To check which display manager is currently configured to run:
cat /etc/X11/default-display-manager
To manually start the display manager without a full reboot (useful right after install, to confirm things are working before committing to a reboot):
sudo systemctl start gdm3
GDM3 Resource Footprint
Worth knowing before you commit to this on a resource-constrained box: GDM3 itself typically adds somewhere in the neighborhood of 100–150 MB of RAM just for the login manager, before GNOME Shell itself is even running — GNOME Shell at idle commonly sits around 700–900 MB total. If you’re doing this on a machine with limited memory, that overhead is worth factoring in; lighter desktop environments like XFCE exist specifically for lower-resource scenarios.
Remote GUI Access (VNC)
If the server is headless (no monitor attached) and you want to actually use the GNOME desktop remotely rather than just having it installed, you’ll need a VNC server on top of the desktop install itself. A common combination:
sudo apt install tigervnc-standalone-server -y
vncserver
The first run of vncserver prompts you to set a VNC password and creates a default configuration under ~/.vnc/. Once running, connect from your workstation with any VNC client pointed at server-ip:5901 (the default first display). I generally recommend tunneling this over SSH rather than exposing the VNC port directly to the internet, since VNC’s own authentication is comparatively weak:
ssh -L 5901:localhost:5901 user@server-ip
Then point your VNC client at localhost:5901 on your own machine — the traffic tunnels through the encrypted SSH connection instead of traveling in the clear.
Wayland vs. Xorg
Current Ubuntu LTS releases default to Wayland as the GNOME session’s display protocol, replacing the older Xorg (X11) as the default. Wayland is generally the better choice for modern hardware — better security isolation between applications, smoother handling of mixed-DPI displays — but some older applications, screen-sharing tools, or proprietary GPU drivers (particularly older NVIDIA driver versions) work more reliably under Xorg. GDM3’s login screen offers a small gear icon near the password field where you can explicitly choose “GNOME” (Wayland) or “GNOME on Xorg” per login session, without needing to reconfigure anything system-wide. If you’re troubleshooting graphics glitches, remote display issues, or screen-sharing problems, switching to the Xorg session as a diagnostic step is often the fastest way to determine whether Wayland itself is the culprit.
Common Post-Install Issues
Black screen or login loop after installing NVIDIA proprietary drivers. This is a frequent pain point — install ubuntu-drivers-common and let it select the recommended driver rather than guessing manually:
sudo ubuntu-drivers autoinstall
sudo reboot
GNOME Shell extensions misbehaving after an update. Extensions are a very common source of visual glitches or crashes after a GNOME version bump. Disable all extensions temporarily to isolate the issue:
gnome-extensions list
gnome-extensions disable EXTENSION_UUID
Fonts rendering oddly or missing entirely. Usually resolved by ensuring the standard font packages are present:
sudo apt install --reinstall fonts-liberation fonts-noto -y
Removing GNOME Cleanly (Reverting to Headless Server)
If you installed GNOME temporarily and want your server back to a lean, headless state, purge both the desktop metapackage and the display manager:
sudo apt purge ubuntu-desktop gnome-shell gnome-desktop3-data -y
sudo apt purge gdm3 -y
sudo apt autoremove --purge -y
sudo reboot
autoremove --purge cleans up the large tail of dependency packages that were pulled in alongside the desktop metapackage but aren’t needed by anything else — without this step, a surprising amount of leftover cruft tends to remain even after removing the headline packages. After rebooting, confirm the system comes up to a plain text login rather than a graphical one.
Switching to a Different Desktop Environment Instead
If GNOME specifically isn’t what you want but you still want some GUI, the same pattern applies to other desktop environments, each with its own metapackage:
sudo apt install kubuntu-desktop -y # KDE Plasma
sudo apt install xubuntu-desktop -y # XFCE
sudo apt install lubuntu-desktop -y # LXQt
sudo apt install ubuntu-mate-desktop -y # MATE
Installing a second desktop environment alongside GNOME is fully supported — both will appear as selectable sessions from the display manager’s login screen gear icon, letting you switch between them per login without reinstalling anything. Just be aware installing multiple full desktop environments side by side means you’ll likely be prompted again about which display manager should be the system default; you can safely keep GDM3 even with KDE installed alongside it, or switch to SDDM if you’re primarily using KDE — either combination works.
Customizing GNOME After Install
Once GNOME is up and running, a few settings I adjust immediately on any fresh install:
GNOME Tweaks, a settings app for options not exposed in the standard Settings panel — window title bar buttons, font rendering, and legacy application theming:
sudo apt install gnome-tweaks -y
Extensions, GNOME’s mechanism for adding functionality the base shell doesn’t include — dock customization, system tray icon support for legacy applications, workspace indicators, and similar quality-of-life additions. The browser-based extension installer requires a small connector package:
sudo apt install gnome-shell-extension-manager -y
I generally install extensions through the Extension Manager application rather than manually placing files, since it handles version compatibility checks against your installed GNOME Shell version automatically, avoiding the common failure mode of installing an extension built for a different GNOME release.
Dark mode and appearance, accessible from Settings → Appearance, which on current GNOME versions applies system-wide across most GTK applications without additional configuration.
Managing GNOME as a Service Consideration
If you’ve installed GNOME on a machine that’s still primarily meant to function as a server — running background services, web applications, or databases — it’s worth explicitly confirming those services aren’t being affected by the presence of a graphical session. In practice GDM3 and GNOME Shell run entirely independently of systemd services like nginx, postgresql, or docker, but the machine’s overall resource budget is now shared between the desktop environment and whatever workloads it was already running. On memory-constrained instances, I check actual headroom after the install completes:
free -h
systemctl status gdm3
If GDM3 and GNOME Shell together are consuming resources you can’t spare, that’s a strong signal to either remove the desktop environment once its immediate purpose is served, or switch to a lighter alternative like XFCE instead of GNOME for any longer-term graphical need on that particular machine.
Automating GNOME Installation for Repeatable Provisioning
If you regularly spin up development VMs or training environments that need the same GNOME setup each time, wrapping the install in a small provisioning script avoids repeating the manual steps:
#!/bin/bash
set -e
apt update
apt upgrade -y
apt install ubuntu-desktop-minimal -y
apt install gnome-tweaks tigervnc-standalone-server -y
systemctl set-default graphical.target
reboot
The set -e at the top ensures the script stops immediately on the first failing command rather than continuing on and potentially leaving the system in an inconsistent half-installed state — a habit worth adopting for any provisioning script, not just this one. systemctl set-default graphical.target explicitly ensures the system boots to the graphical login target going forward, which is normally set automatically by the desktop metapackage’s post-install scripts but is worth confirming explicitly in an automated context where you can’t rely on interactive prompts behaving as expected.
Troubleshooting
apt install fails partway through with dependency errors: Almost always a stale package cache. Run sudo apt update and retry; if problems persist, sudo apt --fix-broken install attempts to resolve broken dependency chains automatically.
System boots to a black screen with no login prompt at all: Try switching to a text console with Ctrl+Alt+F3 (or F2–F6) to get a working terminal, then check the display manager’s status: systemctl status gdm3. A crashed or misconfigured display manager service is the most common cause, and restarting it (sudo systemctl restart gdm3) or reconfiguring it (sudo dpkg-reconfigure gdm3) resolves most cases.
GNOME feels sluggish on a VM: Confirm 3D acceleration is actually available to the guest — GNOME Shell relies on GPU compositing, and running it in a VM without proper graphics passthrough or virtual GPU support degrades performance noticeably. For VMs without solid GPU support, a lighter desktop environment (XFCE) is often a better fit than fighting GNOME’s animations.
Security Considerations
Running a full graphical desktop on a server measurably increases the attack surface — more packages, more running services, more listening ports (if you add VNC or remote desktop on top), and a much larger codebase than a minimal CLI install. If GNOME is genuinely only needed temporarily (debugging a GUI application, running a graphical installer once), consider removing it afterward using the cleanup steps above rather than leaving it installed indefinitely on a production system. For anything long-term, weigh whether the actual need justifies the expanded surface, or whether a headless approach with tools like Cockpit (web-based admin) could serve the same purpose without a full desktop stack.
Compatibility Notes
This guide reflects Ubuntu 24.04 LTS, which ships GNOME 46 by default with Wayland as the default session type. Package names (ubuntu-desktop, ubuntu-desktop-minimal, gdm3) have been stable across recent LTS releases (22.04, 24.04), so the same commands generally apply with minimal adjustment. Non-Ubuntu Debian-based distributions typically use task-gnome-desktop (via tasksel) rather than Ubuntu’s own ubuntu-desktop metapackage, since the Ubuntu-branded package includes Ubuntu-specific theming and default applications not present upstream in Debian.
Summary
Installing GNOME on an existing Ubuntu Server is a single well-supported command — sudo apt install ubuntu-desktop for the full experience, or ubuntu-desktop-minimal for a leaner footprint — followed by a reboot into the GDM3 login screen. The process is safely reversible with apt purge and autoremove --purge if you only needed the GUI temporarily. For remote access to a headless machine, pair the desktop install with a VNC server tunneled over SSH rather than exposed directly, and be mindful that a full desktop environment meaningfully increases resource usage and attack surface compared to the CLI-only server install you started from.
References
- Ubuntu Desktop documentation — https://help.ubuntu.com/
- GNOME project — https://www.gnome.org/
- Debian tasksel documentation — https://wiki.debian.org/tasksel
- Ubuntu package search (ubuntu-desktop) — https://packages.ubuntu.com/