In my projects involving Linux services, I installed Ubuntu Server, configured disk partitions, and performed initial system configurations to prepare the operating system for service deployment. This process included configuring network settings, updating packages, enabling remote administration, and applying basic security measures.
Install Ubuntu Server on virtual machines.
Configure disk partitions to separate operating system files from user data.
Perform initial system configurations, including time zone, networking, and package updates.
Enable SSH for remote administration.
Configure a firewall to restrict incoming network traffic.
Assign static IP addresses to prepare the servers for hosting services.
Ubuntu Server
Linux command-line tools
OpenSSH Server
UFW
Netplan
APT package manager
VMware ESXi virtual machines
Since some services require a Debian-based Linux distribution, I used Ubuntu Server because it provides a minimal installation without a graphical user interface, reducing resource usage. Below, I describe the process I followed to install and configure Ubuntu Server on virtual machines intended to host services.
After booting the VM from the ISO file, I was prompted to select the language and keyboard layout.
Since this VM had one virtual hard disk, it appeared as /dev/sda. I chose manual partitioning instead of automatic partitioning because the disk would contained data that needed to be preserved during future OS reinstallation.
I then created four partitions:
Root (/): This partition stores the operating system files, installed applications, and other system data. I typically allocated at least four times the ISO file size, adjusting the size of applications, logs, and expected data growth.
Boot (/boot): This partition stores files required to boot the operating system, including the Linux kernel and related boot files. I typically allocated 300–500 MB, depending on the installation requirements.
Swap: I created a swap partition on VMs with limited RAM. I typically allocated twice the RAM size.
Home (/home): I created a separate partition to store user home directories independently of the operating system files. This makes it easier to preserve user data when reinstalling the OS.
After configuring the partitions, I was prompted to create a user account rather than use the root account for routine administration.
Since the VMs needed to be managed remotely, I selected the option to install the OpenSSH server.
Finally, the installer copied the required files to the disk. I removed the installation media from the VM's virtual DVD drive when prompted and rebooted the system.
After installing Ubuntu Server, I performed several initial configurations to prepare the VM for installing and running services.
The first step was to configure the time zone so that system logs and services would use the appropriate local time.
timedatectl set-timezone Asia/Tehran
timedatectl
Local time: Tue 2026-10-13 00:15:01 +0330
Universal time: Mon 2026-10-12 20:45:01 UTC
RTC time: Mon 2026-10-12 20:45:00
Time zone: Asia/Tehran (+0330, +0330)
System clock synchronized: yes
systemd-timesyncd.service active: yes
RTC in local TZ: no
Next, I checked whether Ubuntu had detected the virtual network interface and received an IP address from the DHCP server.
ifconfig
ens35: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.88.10 netmask 255.255.255.0 broadcast 192.168.88.255
inet6 fe80::20c:29ff:fe86:438a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:86:43:8a txqueuelen 1000 (Ethernet)
RX packets 2948 bytes 2354070 (2.3 MB)
RX errors 0 dropped 378 overruns 0 frame 0
TX packets 1719 bytes 166690 (166.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 122 bytes 11679 (11.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 122 bytes 11679 (11.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
To verify external network connectivity, I pinged Ubuntu's package repository server.
ping archive.ubuntu.com -c 5
PING archive.ubuntu.com (185.125.190.81) 56(84) bytes of data.
64 bytes from ubuntu-mirror-1.ps5.canonical.com (185.125.190.81): icmp_seq=1 ttl=46 time=167 ms
64 bytes from ubuntu-mirror-1.ps5.canonical.com (185.125.190.81): icmp_seq=2 ttl=46 time=143 ms
64 bytes from ubuntu-mirror-1.ps5.canonical.com (185.125.190.81): icmp_seq=3 ttl=46 time=144 ms
64 bytes from ubuntu-mirror-1.ps5.canonical.com (185.125.190.81): icmp_seq=4 ttl=46 time=199 ms
64 bytes from ubuntu-mirror-1.ps5.canonical.com (185.125.190.81): icmp_seq=5 ttl=46 time=207 ms
--- archive.ubuntu.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 143.648/172.584/207.460/26.798 ms
When additional network troubleshooting tools, such as nslookup, were needed, I installed the dnsutils package.
sudo apt install dnsutils
nslookup ubuntu.com
After confirming network connectivity, I updated the package lists and upgraded installed packages to prepare the VM for service installation. I also removed unnecessary packages and cleaned the local package cache to free disk space.
sudo su
apt update && apt upgrade -y
apt autoremove -y
apt autoclean
reboot
When a separate non-root account was needed, I created one with the following command:
sudo adduser user-1
I checked whether the SSH server was installed and running so that administrators could access the VM remotely.
sudo su
systemctl status SSH
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-10-13 00:02:56 +0330; 32min ago
Process: 1131 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 1143 (sshd)
Tasks: 1 (limit: 2287)
CGroup: /system.slice/ssh.service
└─1143 /usr/sbin/sshd -D
Oct 13 00:02:56 moradilab systemd[1]: Starting OpenBSD Secure Shell server...
Oct 13 00:02:56 moradilab sshd[1143]: Server listening on 0.0.0.0 port 22.
Oct 13 00:02:56 moradilab sshd[1143]: Server listening on :: port 22.
Oct 13 00:02:56 moradilab systemd[1]: Started OpenBSD Secure Shell server.
Oct 13 00:03:20 moradilab sshd[1206]: Accepted password for ali from 192.168.88.2 port 50141 ssh2
Oct 13 00:03:20 moradilab sshd[1206]: pam_unix(sshd:session): session opened for user ali by (uid=0)
To restrict new incoming connections, I enabled UFW. Before enabling the firewall, I allowed SSH traffic to avoid blocking remote administration.
sudo su
ufw allow OpenSSH
ufw enable
ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
After completing the initial configurations and verifying that the server was working properly, I assigned a static IP address from the VM network's address range. This allowed services hosted on the VM to use a consistent IP address, which could then be associated with a DNS A record for client and service access.
To configure the network, I edited the Netplan YAML file.
sudo su
nano /etc/netplan/00-installer-config.yaml
network:
version: 2
renderer: networkd
ethernets:
ens35:
dhcp4: false
addresses:
- 192.168.88.10/24
routes:
- to: 0.0.0.0/0
via: 192.168.88.1
nameservers:
addresses:
- 192.168.88.1
- 8.8.8.8
search:
- moradilab.local
After editing the Netplan file, I used the following commands to validate the configuration and test the network changes.
netplan generate
sudo netplan try
Warning: Stopping systemd-networkd.service, but it can still be activated by:
systemd-networkd.socket
Do you want to keep these settings?
Press ENTER before the timeout to accept the new configuration
Changes will revert in 118 seconds
Configuration accepted.
ip -br addre
lo UNKNOWN 127.0.0.1/8 ::1/128
ens35 UP 192.168.88.10/24 fe80::20c:29ff:fe86:438a/64ip -br addr
ip route
default via 192.168.88.1 dev ens35 proto static
192.168.88.0/24 dev ens35 proto kernel scope link src 192.168.88.10