When developing a server with Django, it's common to connect to a remote server via SSH instead of working in a local environment. However, due to the nature of SSH sessions, connections frequently drop after a certain period of inactivity. This can be cumbersome as the development server may stop, requiring you to reconnect and restart the server. Here, I will share my experience in resolving this issue while keeping the SSH session active.

Problem: Automatic SSH Session Termination

When working on a remote server connected via SSH, if there is no activity for a long time, the session will automatically terminate. While this is useful for security, as it disconnects after a specific duration of network inactivity set in SSH, it can be quite inconvenient for developers.

Solution: SSH Configuration, tmux, and systemd

To address this issue, I applied three methods.

1. Modify SSH Configuration

In the SSH client, I set up the ~/.ssh/config file to send keep-alive packets at regular intervals. This configuration helps maintain the SSH connection by sending packets periodically.

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 5

Here, ServerAliveInterval refers to the interval (in seconds) at which the client sends packets to the server, and ServerAliveCountMax indicates the number of failed attempts. With this setting, the session connection can remain active.

2. Use tmux or screen

To prevent the Django development server from stopping even if the SSH session disconnects, I utilized terminal multiplexer programs like tmux or screen. When starting the Django server using tmux, the server continues to run even if the SSH session ends. For instance, launching the Django server through tmux can be done as follows.

# Create a new tmux session
tmux new -s django_session

# Run the Django development server
python manage.py runserver

Once you've launched the Django server this way, you can reconnect to the session with tmux attach -t django_session after the SSH session has ended.

3. Set Up as a Background Service via systemd

The method I found most satisfactory was creating a service to manage the Django server with systemd. Using systemd allows the application under development to run in the background continuously, independent of the SSH session, thus ensuring server stability. Additionally, it provides considerable advantages by allowing development and testing in an environment nearly identical to the deployment setup. To set up a Django application as a service using systemd, follow these steps.

First, create the file /etc/systemd/system/my_django_app.service and input the following content.

[Unit]
Description=My Django Application
After=network.target

[Service]
User=myuser
Group=mygroup
WorkingDirectory=/path/to/my/django/project
ExecStart=/path/to/my/venv/bin/python manage.py runserver 0.0.0.0:8000
Restart=always

[Install]
WantedBy=multi-user.target

After setting this up, you can start the service with the command systemctl start my_django_app and configure it to start automatically on server reboot with systemctl enable my_django_app. After changing code, you can restart the service with systemctl restart my_django_app to reflect the changes. Notably, once set, the server won't need to be manually started under normal circumstances, which is a significant advantage.

This approach not only provides a feeling of testing in an environment similar to actual deployment, but also eliminates the need for ongoing server management once set up, making it efficient. If you haven't tried this method before, I highly recommend giving it a go.

Conclusion

By employing the above methods, I was able to resolve the SSH session termination issue while ensuring a stable operation of the Django development server. In particular, running it as a background service via systemd has greatly enhanced work efficiency since it allows development and testing in an environment close to actual deployment conditions. It will be a useful tip for those working in a remote development environment.

SSH, tmux, and systemd illustration