Score:2

How do I create a python 3 service that uses socket with systemd?

us flag

I am trying to create a service with systemd, where I use python3 to create a simple socket and leave it as a daemon, but I have made several attempts but in both cases without any success. For today systemd has beaten me, but tomorrow is another day to try.

Server

import socket 
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024 

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
    socket_tcp.bind((host, port)) 
    socket_tcp.listen(5) # Esperamos la conexión del cliente 
    conn, addr = socket_tcp.accept() # Establecemos la conexión con el cliente 
    with conn:
        print('[*] Conexión establecida') 
        while True:
            # Recibimos bytes, convertimos en str
            data = conn.recv(BUFFER_SIZE)
            # Verificamos que hemos recibido datos
            if not data:
                break
            else:
                print('[*] Datos recibidos: {}'.format(data.decode('utf-8'))) 
            conn.send(data) # Hacemos echo convirtiendo de nuevo a bytes

Client

import socket
# El cliente debe tener las mismas especificaciones del servidor
host = '127.0.0.1'
port = 9999

BUFFER_SIZE = 1024 MESSAGE = 'Hola, mundo!' # Datos que queremos enviar with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
    socket_tcp.connect((host, port))
    # Convertimos str a bytes
    socket_tcp.send(MESSAGE.encode('utf-8'))
    data = socket_tcp.recv(BUFFER_SIZE)

Config Unit File

sudo nano /etc/systemd/system/socket_prueba.service
sudo rm -r /etc/systemd/system/socket_prueba.service
[Unit]
Description= Server Relay System: Manager
After=multi-user.target

[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/pipenv run python /path/test_server.py

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload
sudo systemctl enable socket_prueba.service
sudo systemctl start socket_prueba.service
sudo systemctl status socket_prueba.service

Result:

● socket_prueba.service - Server Relay System: Manager
     Loaded: loaded (/etc/systemd/system/socket_prueba.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sat 2021-09-25 16:07:17 -05; 58min ago
    Process: 25771 ExecStart=/usr/local/bin/pipenv run python 

/home/path>
   Main PID: 25771 (code=exited, status=2)

sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Scheduled restart job, restart counter is >
sep 25 16:07:17 serversaas systemd[1]: Stopped Server Relay System: Manager.
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Start request repeated too quickly.
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Failed with result 'exit-code'.
sep 25 16:07:17 serversaas systemd[1]: Failed to start Server Relay System: Manager.

Intento 2 Sourcer: systemd and python

socket con python y systemd

● socket_prueba.socket - Socket prueba
     Loaded: loaded (/etc/systemd/system/socket_prueba.socket; disabled; vendor preset: enabled)
     Active: failed (Result: service-start-limit-hit) since Sat 2021-09-25 17:00:47 -05; 4s ago
   Triggers: ● socket_prueba.service
     Listen: 127.0.0.1:9999 (Stream)

sep 25 17:00:47 vidm-OMEN systemd[1]: Listening on Socket prueba.
sep 25 17:00:47 vidm-OMEN systemd[1]: socket_prueba.socket: Failed with result 'service-start-limit-hit'.
Michael Hampton avatar
cz flag
Check the journal to find out what happened, e.g. `journalctl -l -u socket_prueba.service`
Score:3
us flag

Here is ready to go simple shell deploy commands for your case, you can change directories, name, description of service or script and so on, description is below:

Make directory and script itself

mkdir /usr/src/python-socket -p

cat > /usr/src/python-socket/python-socket.py << 'EOL'
import socket 
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024 

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
    socket_tcp.bind((host, port)) 
    socket_tcp.listen(5) # Esperamos la conexión del cliente 
    conn, addr = socket_tcp.accept() # Establecemos la conexión con el cliente 
    with conn:
        print('[*] Conexión establecida') 
        while True:
            # Recibimos bytes, convertimos en str
            data = conn.recv(BUFFER_SIZE)
            # Verificamos que hemos recibido datos
            if not data:
                break
            else:
                print('[*] Datos recibidos: {}'.format(data.decode('utf-8'))) 
            conn.send(data) # Hacemos echo convirtiendo de nuevo a bytes
EOL

Set up variables for create systemd service

SERVICE_NAME=python-socket
SERVICE_DESCRIPTION="Test python service"
SERVICE_COMMAND="/usr/bin/python3 /usr/src/python-socket/python-socket.py"
SERVICE_WORK_DIR=/usr/src/python-socket/
SERVICE_USER=root

Deploy systemd service config

cat > /etc/systemd/system/${SERVICE_NAME}.service << EOL
[Unit]
Description=${SERVICE_DESCRIPTION}
After=multi-user.target

[Service]
Environment="FROM=SYSTEMD"
WorkingDirectory=${SERVICE_WORK_DIR}
Type=simple
User=${SERVICE_USER}
ExecStart=${SERVICE_COMMAND}
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
KillMode=process

[Install]
WantedBy=multi-user.target
EOL

Apply new service, start it and check

systemctl daemon-reload
systemctl enable ${SERVICE_NAME}
systemctl stop ${SERVICE_NAME}
systemctl start ${SERVICE_NAME}
systemctl status ${SERVICE_NAME}

As a result your systemd service config will looks like

[Unit]
Description=Test python service
After=multi-user.target

[Service]
Environment="FROM=SYSTEMD"
WorkingDirectory=/usr/src/python-socket/
Type=simple
User=root
ExecStart=/usr/bin/python3 /usr/src/python-socket/python-socket.py
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
KillMode=process

[Install]
WantedBy=multi-user.target

Where:

Environment="FROM=SYSTEMD" - some env variable if you want pass to your python script

Type=simple - simple systemd service it will work while script is up

RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0

These parameters will not allow your script being down in any conditions it will start on fail continiously

KillMode=process - This is how your script will stop, if you have not special SIG events in your python script it is universal

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.