We successfully built our Linux software or package in the previous article. In this article, I'll show you how I made it run on an Ubuntu Server. This can be applied to any Linux OS since they all have the same base.
I will start the package to keep it running by using Systemd, which is at the core of almost all Linux packages. You might be familiar with the command
systemctl, which is a part of the Systemd command that we use for starting our database and Nginx. Additionally, we will also update our Python source code. Lastly, we will install our package inside a venv (virtual environment) and make it available outside of the venv.
Create a Systemd unit file named
time-tracking-pkg.service, it is a configuration file used by Systemd to define how a service should be managed. Place it into
Description=Time Tracking Service After=syslog.target network.target [Service] User=root ExecStart=/usr/local/bin/time-tracking-pkg Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
Run the following commands:
- Enable the service to start automatically at boot. This is useful for services that need to run continuously.
sudo systemctl enable time-tracking-pkg.service
- Start our package to keep it running in the background as a daemon or service. Adding its extension is not necessary.
sudo systemctl start time-tracking-pkg.service
- Check whether it's currently active or not.
sudo systemctl status time-tracking-pkg
Now that the service is up and running, in order to track it, I'm going to adjust our Python code and add a socket. Additionally, I will add an argument to make it run only its specified task.
import time import socket import argparse localhost_network = "127.0.0.1" socket_port = 52000 # Sender Data to socket def send_data(): try: # Create a socket object s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to Receiver s.connect((localhost_network, socket_port)) current_time = time.strftime("%Y-%m-%d %H:%M:%S") s.send(current_time.encode()) # Close the connection s.close() except Exception: pass # Receive Data from socket def receive_data(): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Set the SO_REUSEADDR option s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Bind and listen s.bind((localhost_network, socket_port)) s.listen() # Accept connections while True: (clientConnected, _) = s.accept() try: data_from_client = clientConnected.recv(1024) data_to_print = data_from_client.decode() print(data_to_print) finally: # Close the connection clientConnected.close() except socket.error: pass except KeyboardInterrupt: pass except Exception: pass finally: s.close() def main_func(): try: parser = argparse.ArgumentParser(allow_abbrev=False) # Define start argument parser.add_argument( '--start', action='store_true', help="Use this argument on systemd" ) args = parser.parse_args() # Condition when user pass argument start if args.start: while True: send_data() time.sleep(5) else: receive_data() except KeyboardInterrupt: pass if __name__ == '__main__': main_func()
I used argparse to add an argument named "--start" for calling a function that will initiate sending the datetime data over a socket.
After that, we will compile our project as we did in the previous article. Then, we are going to update our Systemd script to start our service with this argument.
After updating, we are going to reload our service with the following commands:
sudo systemctl reenable time-tracking-pkg sudo systemctl stop time-tracking-pkg sudo systemctl start time-tracking-pkg
sudo systemctl reenable time-tracking-pkg sudo systemctl daemon-reload sudo systemctl restart time-tracking-pkg
Now, we can still use
time-tracking-pkg command to see the current time.
Open a new tab to access the server and run the following command.
ps aux | grep time-tracking-pkg
You will see two working processes and their Process IDs:
As you can see, even though we didn't run
time-tracking-pkg --start, we still see it because Systemd runs it in the background. You can think of it as another program/process.
Now, terminate the tab that is running
time-tracking-pkg and then re-run it again; you will notice that its process ID changes. Meanwhile,
--start is still running, and its Process ID remains the same.
We finally have the service up and running. However, there's a problem with our distribution package setup file. You won't be able to install it on Debian, and in some cases, even further, some of the package versions on the server are incompatible with our package, which would result in errors.
To prevent this from happening, we're going to use a venv. Please ensure that you have
python3.XX-venv installed on your Ubuntu Server. If you haven't, please run
apt install python3.<enter your python3 version>-venv.
python3 -m venv "time-tracking"
Before activating the venv, I'm going to stop our service and uninstall the package.
systemctl stop time-tracking-pkg pip3 uninstall -y time-tracking-pkg
The directory named
time-tracking will be created at the current directory level where we are currently located. We are going to activate the venv that we just created.
Even though we can still run the command normally within the venv, we still need to make the command available outside of the venv. As you can see in the image below, once we exit the venv, we can no longer run the command.
So, I'm going to create a symlink (symbolic link) or a shortcut of the binary file of our package from inside the venv to
ln -s /root/time-tracking/bin/time-tracking-pkg /usr/local/bin/time-tracking-pkg
Finally, we have our service up and running within Systemd and venv. Additionally, You can check the source code in my repository.
Thank you for reading up to this point. Please feel free to leave a comment.
Looking for qualify software with affordable price? contact: email@example.com