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.
Add a New Comment