Installing the Fedora Server Edition as a virtual machine using Cockpit

Peter Boy, Jan Kuparinen, Brett Weir, Rowan Puttergill Version F34-F44 Last review: 2026-09-15
The objective here is to install a Fedora Server in a virtual machine using the deployed generic installation media. An underlying assumption is that the processor architecture is the same as that of the host. The other case is also possible, but requires additional configuration.

The descriptions can also be used as a blueprint for installing other distributions with the chosen distribution’s own installation media.

Why Cockpit

Fedora Server is designed as a "headless" system. Therefore, it comes without an elaborate graphical user interface and corresponding hardware. Only a simple text console is available. A system administrator performs all work on the machine using the command line.

Cockpit offers an alternative "remote" graphical interface. It operates in the web browser of the system administrator’s desktop and runs the required commands on the server on their behalf.

Cockpit saves the memorization of the complex parameter zoo of virt-install, the CLI installation tool. It saves long typing on the keyboard including the correction of accidental typos. But even those who 'speak virt-install' fluently, can benefit from Cockpit. It automatically provides much status information about configuration and resource usage, which you would otherwise have to collect manually. And this information is always present, no need to keep this information in mind.

Therefore, Cockpit is useful for a beginner in server administration, for the part-time administrator as well as for experienced administrators. Particularly impressive is, that Cockpit does not require its own specific configuration organization, but strictly uses the standard configuration methods. So you can mix and match Cockpit based and CLI based administration work.

Preparations

We assume a complete installation of virtualization support according to the Adding Virtualization Support guide.

Open your browser and connect to the Cockpit instance of your host server. Consult the Postinstallation Customizations guide to find out the possible connection paths. Log in with an administrative user account. In the overview (start) page select Virtual machines in the left navigation column.

If there is no entry Virtual machines follow the Adding Virtualization Support guide to ensure that the system is ready for virtualization.

Cockpit `__Virtual machines__` page

Provisioning installation media

Cockpit offers the option to load an installation medium not only locally, but also from a remote location. Especially if several virtual machines are to be installed, it is more efficient to keep the installation medium locally.

Select Terminal in the left navigation bar and issue the commands line by line:

$ sudo curl -O --output-dir /var/lib/libvirt/boot/ https://fedora.mirrorservice.org/fedora/linux/releases/44/Server/x86_64/iso/Fedora-Server-dvd-x86_64-44-1.7.iso
$ sudo curl -O --output-dir /var/lib/libvirt/boot/ https://fedora.mirrorservice.org/fedora/linux/releases/44/Server/x86_64/iso/Fedora-Server-44-1.7-x86_64-CHECKSUM
$ sudo curl -O https://fedoraproject.org/fedora.gpg | gpg --import
$ sudo gpgv --keyring ./fedora.gpg  /var/lib/libvirt/boot/*-CHECKSUM
$ sudo sh -c ' cd /var/lib/libvirt/boot/  &&  sha256sum --ignore-missing -c *-CHECKSUM '

You can safely ignore the warning of the last command about not correctly formatted lines.

You can provide additional installation media in an analog way. With everything necessary in place, we can start installing a virtual machine.

Basic configuration of the virtual machine to get installed

This guide uses Cockpit, version 367, and Cockpit machines, version 356. On updated systems, you may have an updated version and see slightly different screens.

To start a VM installation, connect your desktop browser to the Cockpit instance of your host server. Consult the Postinstallation Customizations guide to find out the possible connection paths. Log in as root or with your administrative account. In the overview (start) page select Virtual machines in the left navigation column and then Create VM (the button Import VM next to it refers to the other alternative, using disk images) and complete the form that opens.

Cockpit `__Create new virtual machine__` form

First, specify a name for the virtual machine to be created. It must be unique in the host server’s name space. Select the connection type, usually System (as opposed to User session). See explanation in the Adding Virtualization Support guide.

Then select the installation type to be used. The drop down menu offers several alternatives:

Download an OS

Download from a remote location. You have to choose the Distribution from a drop down menu in the next field. It includes various distributions and version. But you can’t select the Fedora edition. Not a recommendable option.

Cloud base image

That refers to the special case of cloud disk images. That is not covered here.

Local install media (ISO image or distro install tree)

Use a ISO image or a distro install tree stored on the local disk. This is the option we want to use here. Select this option and specify in the next field the fully qualified path and filename.

URL (ISO image or distro install tree)

The same as 'Download an OS', but you can freely specify the exact distribution by download URL in the next field and do not depend on a preset list.

Network boot (PXE)

That’s another special case we don’t cover here. You need to set up a special install server beforehand.

As mentioned above choose Local install media (ISO image or distro install tree) and specify in the following Installation source row the fully qualified file name. In our example of Fedora Server 44 it is /var/lib/libvirt/boot/Fedora-Server-dvd-x86_64-44-1.7.iso. The field provides typeahead completion, so you can either type the full path directly, or slowly select the path, directory by directory using the drop-down. If you type into the field, matching entries are offered as you type.

In the next line, Operating system, Cockpit should display the correct OS and release, in this example Fedora 44. If the exact release is not offered the field shows Fedora (unknown). Use that as a fallback; the installation itself is not affected.

In the next fields, leave Storage at the default Create new qcow2 volume, and set an appropriate Storage limit (the size of the virtual disk) and Memory. After selecting the install media, Cockpit fills in a suggested value for the memory based on the operating system and shows a warning if your values are below the recommended minimums. The warnings are informative, and on a memory-constrained host you may proceed with less, but remember that the installation program runs more comfortably with the recommended amounts.

Finally, check all entries again and then select Create and edit option. This allows us to perform further configurations, especially the network connections. This saves additional administration work later on.

It takes a short time and then the virtual machine’s details page is displayed.

Cockpit virtual machine details page

The upper part offers the opportunity to configure several general properties of the virtual hardware, including the size of the memory and the number of CPUs. The Autostart option defines whether the server should start the virtual machine automatically at system startup - important for reliable everyday operation.

Adjust the options according to your need.

Disks

The disk list shows that Cockpit has created a virtual disk in the disk-image storage pool, which by default is the default pool residing in the /var/lib/libvirt/images directory (on some systems the pool is named differently, e.g. Disk images). The virtual machine name is used as the name of the disk image file. The file extension qcow2 indicates a dynamic image format that occupies only as much space as the available data require and grows as needed to the maximum set size. This can be seen clearly in the Used and Capacity columns.

The administrator does not need to worry about all these details. A clear benefit of Cockpit.

Network connections

The list of network interfaces shows only one interface: the internal network managed by libvirt. Virtual machines, however, are mostly used for tasks that require access to the public network and also require reachability from the public network. Examples are web and mail servers or other custom services. For that, the virtual machine needs an additional, external connection via the physical interface of the host.

Cockpit offers two ways to provide it, selectable in the Interface type field:

Bridge to LAN

Creates a virtual bridge between the guest and the physical interface. The host’s network stack mediates the traffic, and the host can reach the guest directly through it.

Direct attachment

Attaches the guest’s virtual interface directly to the physical interface, bypassing the host’s network stack (libvirt implements this with macvtap). This is the recommended approach: it has less system load than a bridge, and because the host is not part of the data path, the VM’s external connection stays independent from the host’s own network configuration. For administrators of remote, not directly accessible servers, there is no need to touch the host’s network connection again after the initial setup.

An important limitation of direct attachment is that the host server itself can no longer reach the virtual machine directly through the physical interface. Therefore, keep the existing internal interface as a protected, host-only connection.

Choosing Direct attachment reveals an additional Mode row with four options:

bridge

The virtual interface is bridged to the physical interface. The virtual machine appears on the public network as a regular host with its own MAC address and its own IP address. This is the default and the mode we use here.

passthrough

The physical interface is handed over to the virtual machine exclusively: the host loses the interface, and only one virtual machine can use it. It offers the best performance, but is only suitable if the host does not need the interface itself.

private

The virtual machine’s traffic goes out under the MAC address of the physical interface. The virtual machine can reach the public network, but cannot be addressed directly from it. Suitable for outbound-only workloads.

vepa

All traffic is hairpinned through the external network switch. This requires switch support and is rarely used in practice.

Now repurpose the existing first interface for the external connection: select Edit in the row of the existing interface to open the settings form.

Cockpit `__Virtual network interface settings__` form

Select Direct attachment as Interface type and choose the external physical interface of the host in the Source field. Keep the preselected Mode (bridge) and leave Model and MAC address unchanged. Then select Save.

Next, select Add network interface for the internal connection between the host and the virtual machine. A nearly identical form opens: keep Interface type as Virtual network if it is not already preselected and select default as Source. Again, leave Model virtio (Linux, perf) and MAC address Generate automatically unchanged, and select Save.

Now everything is ready and the installation can begin.

Interactive installation

Select Install at the top of the form. Don’t select Power on, which boots from the virtual disk instead of the install media. After a short time the boot menu of the installation media appears.

Boot menu of the Fedora Server installation media

The default entry, Test this media & install Fedora 44, verifies the installation media first and then starts the installation. To skip the media check, highlight Install Fedora 44 with the arrow keys and press Enter. Shortly afterwards the installation program, Anaconda, shows up and displays the installation summary screen. Select Expand at the right top to increase readability. There is no collapse button, you have to click on the VM name in the breadcrumb displayed at the top.

Start with installation as usual. You can follow the Server installation guide.

The installation process will take some time.

If you want to save the disk image for future VM creation, select shutdown, copy the image to /var/lib/libvirt/boot/, and then start the VM anew for postinstallation steps. Otherwise restart according to the installation program’s advice: select Reboot System on the completion screen and proceed with postinstall.

Excursus: Save generated virtual machine for later reuse

Sometimes, after selecting Shutdown the machine automatically starts again. Login with your administrative account and perform a shutdown: sudo shutdown -h now. Then switch to a host’s terminal window and execute:

$ sudo qemu-img convert -O qcow2 /var/lib/libvirt/images/{VM_NAME}.qcow2 /var/lib/libvirt/boot/fedora-servervm-img.qcow2

A comparison of the two image files reveals that the originally created image is about 20 GiB in size, as specified while creating the virtual machine. Thus the dynamic capabilities of the qcow2 format are not used during the installation process. The copied image is only a fraction of that. The conversion process automatically re-uses the dynamic capability and creates a sparse image by masking out unused parts (thin provisioning). The copy could be made even smaller by using the -c parameter and additionally compressing the copied image. However, this may reduce the performance somewhat. In any way, the image will grow during later reuse in the course of operation depending on actual needs.

Follow the accompanying tutorial to prepare the copied image for reuse.

Virtual machines postinstallation tasks

There are some postinstallation task that are specific for a virtual machine. Otherwise, it is the same tasks that are performed after a bare-metal installation.

Before you start the postinstallation tasks you may consider to 'sparsify' the image, i.e. to mask out currently unused space and convert the image to thin provisioning (and so using the dynamic capabilities of the qcow2 image format). You must use a host terminal window. Cockpit does not currently support such an operation.

$ sudo qemu-img convert -O qcow2 /var/lib/libvirt/images/{VM_NAME}.qcow2 /var/lib/libvirt/images/{VM_NAME}-sparse.qcow2
$ sudo mv  /var/lib/libvirt/images/{VM_NAME}-sparse.qcow2  /var/lib/libvirt/images/{VM_NAME}.qcow2

If you have not already done so, start the virtual machine and log in with the administrator account. You can select Expand at the top of the console window to increase readability. Selecting the Serial tab (next to Graphical at the top of the console) instead of the graphical console further improves readability in some cases. However, on some devices this does not work at all.

All subsequent tasks must be executed with ROOT privileges. If the root account is locked, ROOT privileges should generally be acquired for the sake of simplicity.

$ sudo -i
[sudo] password for <user>:

Mandatory postinstallation tasks

  1. Check hostname and time synchronisation

    A correct hostname is specifically important for DHCP of the internal network to work properly. A correct time is important for various tasks, specifically synchronization.

    1. Check hostname. You need a correct static hostname.

      $ hostnamectl
      • Set hostname if required:

        $ sudo hostnamectl  set-hostname  <YourFQDN>
    2. Check time zone, time synchronisation, time

      $ timedatectl
      • Correct time zone if necessary:

        $ sudo timedatectl set-timezone <ZONE>
      • If necessary, activate time synchronisation:

        $ sudo timedatectl set-ntp true
      • Correct time if necessary:

        $ sudo timedatectl set-time <TIME>
  2. Consolidate internal network configuration

    The internal network must use DHCP. Don’t change that unless you are sure, what you are doing.

    Usually, it is useful to resolve a single member name to the internal network, in the example here vm1 to vm1.example.lan instead of vm1.example.com. For this purpose it is necessary to explicitly set the DNS search path of the internal interface.

    1. List the interfaces and determine the name of the internal interface

      $ nmcli con
      NAME    UUID                                  TYPE      DEVICE
      enp1s0  47df4730-171e-3bfe-b5d9-4238137e0f70  ethernet  enp1s0
      enp2s0  7627fc10-f1bf-3220-99e2-3bd369837439  ethernet  enp2s0
    2. Set the DNS search path for the internal interface

      If enp2s0 is the internal interface, set dns search and deactivate IPv6 that is not used internally

      $ sudo nmcli con mod enp2s0 ipv4.dns-search example.lan  ipv6.method disabled
      $ sudo nmcli con up enp2s0
      $ sudo systemctl restart NetworkManager
  3. Check name resolution

    Check /etc/resolv.conf

    $ ls -al /etc/resolv.conf

    If it is a file instead of a link, you have to fix it.

    $ sudo rm -f /etc/resolv.conf
    $ sudo ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
    $ ls -l /etc/resolv.conf
    $ sudo systemctl restart NetworkManager
    $ sudo systemctl restart systemd-resolved

    Check whether the name resolution works as desired.

    $ host vm1.example.com
    $ host vm1.example.lan
    $ host vm1
  4. Adjust firewall setting of the internal interface

    The installation program assigns all interfaces to the FedoraServer zone, which limits access to ssh (and Cockpit). For the internal, protected network a broader accessibility may be appropriate, depending on the use case. If appropriate, modify the configuration (check alternative zone and select a suitable one).

    $ firewall-cmd --get-active-zones
    $ sudo firewall-cmd --permanent  --zone=trusted  --change-interface=<internalIF>
    $ sudo firewall-cmd --reload
    $ firewall-cmd --get-active-zones
  5. Increase security of Cockpit access

    Refer to the corresponding section in the Postinstallation Customizations guide to find options to enhance security of Cockpit access.

Optional postinstallation tasks

  1. Making vim the default editor

    If you are a somewhat experienced administrator, you are probably annoyed that nano, the default editor since Fedora 34, always opens when you want to edit crontab or similar. It is therefore worth reconfiguring right from the start.

    # dnf install --allowerasing vim-default-editor
  2. Reconfiguring the external interface as static

    Many administrators prefer to configure the external interface statically to ensure connectivity even if the DHCP server fails or is corrupted. Adjust the following example as needed.

    $ sudo nmcli con mod <IF_NAME> ipv4.method static \clear
         ipv4.address "xxx.xxx.xxx.xxx/yy" \
         ipv4.gateway "xxx.xxx.xxx.zzz" \
         ipv4.dns "xxx.xxx.xxx.vvv" \
         ipv6.method manual \
         ipv6.addresses xxxx:xxxx:xxxx:xxxx::yyyy/64 \
         ipv6.gateway xxxx:xxxx:xxxx:xxxx::zz \
         ipv6.dns "xxxx.xxxx.xxxx.xxxx::vvv"  \
         connection.zone "FedoraServer"

    Ensure, parameter search-domain is empty!

  3. Remove unnecessary hardware packages

    $ sudo dnf remove iwl*  linux-firmware*  zd1211-firmware*  ipw*  atmel*  alsa-sof-firmware*

It is also advisable to review all the tasks in the general Postinstallation Customizations guide for virtual machines as well.