You deploy your Flask app on Alma Linux, everything looks perfect, you hit your URL and... BAM! 502 Bad Gateway.
You check configs, permissions, logs. Nothing works. Then you try sudo setenforce 0 and... it works! ๐
But now you're stuck running with SELinux disabled, and you know that's not the solution.
Sound familiar? Let me show you how to fix this properly.
The Real Problem
SELinux isn't your enemy - it's just doing its job. By default, it blocks:
- nginx connecting to your Gunicorn Unix socket
- systemd launching Gunicorn from
/home - Your app sending emails via SMTP
Basically, everything a modern web app needs to do. ๐ค
Quick Diagnosis
# See what SELinux is blocking
sudo ausearch -m avc -ts recent
# Check your service logs
sudo journalctl -u your-service -n 50 --no-pager
If you see Permission denied with code 203/EXEC, that's SELinux blocking you.
The Solution (Step by Step)
1. Move to /var/www (seriously, do it)
SELinux hates /home for web apps. Move to the standard location:
sudo systemctl stop your-service
sudo mkdir -p /var/www
sudo mv /home/user/my-app /var/www/my-app
sudo chown -R user:user /var/www/my-app
sudo restorecon -Rv /var/www/my-app # SELinux magic!
2. Update systemd service
Edit /etc/systemd/system/your-service.service:
[Unit]
Description=Gunicorn for Flask app
After=network.target
[Service]
User=your-user
Group=your-group
WorkingDirectory=/var/www/my-app
ExecStartPre=/usr/bin/mkdir -p /var/run/my-app
ExecStartPre=/usr/bin/chown your-user:nginx /var/run/my-app
ExecStartPre=/usr/bin/chmod 755 /var/run/my-app
Environment="PATH=/var/www/my-app/venv/bin"
ExecStart=/var/www/my-app/venv/bin/gunicorn \
--workers 4 \
--bind unix:/var/run/my-app/my-app.sock \
--umask 007 \
wsgi:app
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
3. Configure SELinux contexts
# Tell SELinux the socket is legitimate
sudo semanage fcontext -a -t httpd_var_run_t "/var/run/my-app(/.*)?"
sudo restorecon -Rv /var/run/my-app
# Allow nginx to connect
sudo setsebool -P httpd_can_network_connect 1
4. Create a custom SELinux policy (THE game changer!)
This is the crucial step:
# Temporary permissive mode
sudo setenforce 0
# Start your app to generate violations
sudo systemctl restart your-service
sleep 5
curl http://localhost
# Generate custom policy from violations
sudo ausearch -m avc -ts recent | audit2allow -M my_policy
# Install the policy
sudo semodule -i my_policy.pp
# Back to enforcing mode
sudo setenforce 1
# Restart and verify
sudo systemctl restart your-service
What just happened? audit2allow analyzed all SELinux denials and created a policy that allows them. SELinux just learned what your app needs!
5. Configure nginx
upstream app_server {
server unix:/var/run/my-app/my-app.sock fail_timeout=0;
}
server {
listen 80;
server_name my-domain.com;
location / {
proxy_pass http://app_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
sudo nginx -t
sudo systemctl reload nginx
Common Issues & Quick Fixes
Emails not sending?
sudo setsebool -P httpd_can_sendmail 1
External database connection blocked?
sudo setsebool -P httpd_can_network_connect_db 1
API calls failing?
sudo setsebool -P httpd_can_network_connect 1
Verify It Works
# Check SELinux mode (should show "Enforcing")
getenforce
# Service status
sudo systemctl status your-service
# No more violations?
sudo ausearch -m avc -ts recent
# Test your site
curl -I http://your-domain.com
If everything's green, congratulations! ๐ You've tamed SELinux!
Golden Rules
- NEVER disable SELinux in production - create policies instead
-
Always use
/var/wwwfor web apps -
Save your
.tefiles - you'll need them later -
Use
restoreconafter moving files - saves hours of debugging
Want the Full Guide?
This is just the quick version! For a complete, detailed walkthrough with troubleshooting tips, deployment automation scripts, and more real-world scenarios, check out the full article on my blog:
๐ Read the complete guide on codewithmpia.com
You'll learn:
- How to debug SELinux violations like a pro
- Setting up automated deployment scripts
- Handling edge cases and specific scenarios
- Best practices for production deployments
Have you struggled with SELinux? Share your experience in the comments below!
And if this helped you fix that annoying 502 error, don't forget to share it with others who might be stuck in the same situation. ๐
May the SELinux be with you! ๐งโจ
๐ About Me
Hi! I'm Mpia M., a computer science student passionate about web development. I created codewithmpia.com to share coding tutorials and make programming knowledge accessible to everyone.
Want more content like this?
- ๐ Visit my blog: https://codewithmpia.com
- ๐ง Subscribe to my newsletter for Python, Django, Flask, Svelte tips
- ๐ฌ Let's connect and share our dev experiences!
Topics I cover: Python, Django, Flask, SvelteKit, Vue.js, and DevOps.
Top comments (0)