{"id":2402,"date":"2018-08-16T16:47:47","date_gmt":"2018-08-16T11:17:47","guid":{"rendered":"https:\/\/pheonixsolutions.com\/blog\/?p=2402"},"modified":"2026-09-28T17:29:57","modified_gmt":"2026-09-28T11:59:57","slug":"configure-multiple-uwsgi-application-on-nginx","status":"publish","type":"post","link":"https:\/\/pheonixsolutions.com\/blog\/configure-multiple-uwsgi-application-on-nginx\/","title":{"rendered":"Configure multiple uwsgi application on nginx"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Post Date: <\/strong>August 16, 2018 <br><strong>Last Updated:<\/strong> September 22, 2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This guide explains how to configure multiple uWSGI applications behind Nginx, using uWSGI&#8217;s <strong>Emperor<\/strong> mode to manage several apps at once, each with its own Nginx server block.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The original version of this guide only showed a single app configured \u2014 this update adds a genuine second app example so the &#8220;multiple applications&#8221; part is actually demonstrated, along with the Emperor mechanism that makes running many apps this way possible in the first place.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Nginx and uWSGI installed<\/li>\n\n\n\n<li>One or more Python\/Django applications ready to deploy<\/li>\n\n\n\n<li>Root or sudo access<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">uWSGI&#8217;s <strong>Emperor<\/strong> mode is what makes &#8220;multiple applications&#8221; work cleanly:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <strong>Emperor<\/strong> process watches a specific directory (<code>\/etc\/uwsgi\/vassals\/<\/code>) for <code>.ini<\/code> files<\/li>\n\n\n\n<li>Each <code>.ini<\/code> file found there automatically becomes a running <strong>vassal<\/strong> \u2014 its own independent uWSGI worker process, with its own socket<\/li>\n\n\n\n<li>Adding a new app is as simple as dropping a new <code>.ini<\/code> file (or symlink) into that directory \u2014 no need to restart the Emperor itself<\/li>\n\n\n\n<li>Nginx then routes incoming requests to the correct app&#8217;s socket based on the domain\/server block that matched the request<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM.png\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM-1024x683.png\" alt=\"\" class=\"wp-image-11882\" srcset=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM-1024x683.png 1024w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM-300x200.png 300w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM-768x512.png 768w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM-272x182.png 272w, https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2018\/08\/ChatGPT-Image-Sep-22-2026-03_27_17-PM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is also why the original guide&#8217;s directory structure matters: it&#8217;s not just a config location, it&#8217;s the mechanism Emperor uses to discover and manage every app automatically.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Steps<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Create the First App&#8217;s uWSGI Vassal Config<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Symlink the app&#8217;s <code>.ini<\/code> file into the vassals directory so Emperor picks it up:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cd \/etc\/uwsgi\/vassals\/\nln -s \/var\/www\/app1\/app1\/demo.ini .\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Contents of <code>demo.ini<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[uwsgi]\nchdir           = \/var\/www\/app1\/app1\nmodule          = app1.wsgi\nenable-threads  = true\nmaster          = true\nprocesses       = 10\nlisten          = 100\nsocket          = \/var\/www\/app1\/app1\/app1.sock\nchmod-socket    = 660\nvacuum          = true\nmax-requests    = 1000\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Note:<\/strong> The original used <code>chmod-socket = 666<\/code>, which makes the socket world-writable \u2014 readable and writable by any user or process on the system. <code>660<\/code> (owner and group only) is safer, as long as the socket&#8217;s group matches the user Nginx runs as.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">2. Create the Second App&#8217;s uWSGI Vassal Config<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the part the original guide skipped \u2014 here&#8217;s a second, independent app configured the same way, to actually demonstrate &#8220;multiple&#8221;:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cd \/etc\/uwsgi\/vassals\/\nln -s \/var\/www\/app2\/app2\/demo2.ini .\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Contents of <code>demo2.ini<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[uwsgi]\nchdir           = \/var\/www\/app2\/app2\nmodule          = app2.wsgi\nenable-threads  = true\nmaster          = true\nprocesses       = 5\nlisten          = 100\nsocket          = \/var\/www\/app2\/app2\/app2.sock\nchmod-socket    = 660\nvacuum          = true\nmax-requests    = 1000\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Because Emperor watches the whole directory, this second app starts running automatically as soon as its <code>.ini<\/code> file is symlinked in \u2014 no separate command needed to &#8220;add&#8221; it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Configure Nginx for the First App<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">File: <code>\/etc\/nginx\/conf.d\/app1.conf<\/code><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">upstream app1 {\n    server unix:\/\/\/var\/www\/app1\/app1\/app1.sock;\n}\n\nserver {\n    listen      80;\n    server_name app1.yourdomain.com;\n    charset     utf-8;\n    client_max_body_size 75M;\n\n    location \/static {\n        alias \/var\/www\/app1\/app1\/static;\n    }\n\n    location \/ {\n        uwsgi_pass  app1;\n        include     \/etc\/nginx\/uwsgi_params;\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Configure Nginx for the Second App<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">File: <code>\/etc\/nginx\/conf.d\/app2.conf<\/code><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">upstream app2 {\n    server unix:\/\/\/var\/www\/app2\/app2\/app2.sock;\n}\n\nserver {\n    listen      80;\n    server_name app2.yourdomain.com;\n    charset     utf-8;\n    client_max_body_size 75M;\n\n    location \/static {\n        alias \/var\/www\/app2\/app2\/static;\n    }\n\n    location \/ {\n        uwsgi_pass  app2;\n        include     \/etc\/nginx\/uwsgi_params;\n    }\n}\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Note:<\/strong> Each app gets its own <code>upstream<\/code> block and <code>server_name<\/code>, so Nginx routes each domain to the correct app&#8217;s socket. This is the actual &#8220;multiple applications&#8221; pattern \u2014 two independent Nginx server blocks pointing at two independent uWSGI sockets.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">5. Verify Nginx Configuration<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">nginx -t\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see <code>syntax is ok<\/code> and <code>test is successful<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">6. Restart Nginx<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">systemctl restart nginx\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">7. Reload the uWSGI Apps<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To reload a <strong>single<\/strong> app without restarting everything, touch its <code>.ini<\/code> file \u2014 Emperor detects the change and reloads just that vassal:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">touch \/etc\/uwsgi\/vassals\/demo.ini\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To restart the Emperor process itself (all apps):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">systemctl restart uwsgi-emperor\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Note:<\/strong> The original guide referenced a custom script (<code>\/opt\/scripts\/uwsgi_restart.sh<\/code>) with no explanation of what it actually does. If your server doesn&#8217;t have a systemd-managed Emperor service, check how uWSGI&#8217;s Emperor was originally started on your system before assuming either command above applies directly.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Running multiple uWSGI applications behind Nginx relies on Emperor mode automatically managing every <code>.ini<\/code> file placed in the vassals directory, paired with a separate Nginx server block per app pointing at each app&#8217;s own socket. Adding a third, fourth, or further app follows the exact same pattern \u2014 a new vassal <code>.ini<\/code> file, plus a new Nginx server block.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently Asked Questions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Do I need to restart Emperor every time I add a new app?<\/strong> No \u2014 that&#8217;s the point of Emperor mode. It watches the vassals directory continuously, so a new <code>.ini<\/code> file symlinked in starts running automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why use separate socket files instead of one shared socket?<\/strong> Each app needs its own independent uWSGI process and socket so they don&#8217;t interfere with each other \u2014 sharing a socket between unrelated apps isn&#8217;t supported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What if two apps need to share the same domain but different paths?<\/strong> Use a single Nginx <code>server<\/code> block with multiple <code>location<\/code> blocks, each with its own <code>uwsgi_pass<\/code> pointing at a different app&#8217;s upstream, instead of separate <code>server_name<\/code> entries.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Related Articles<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pheonixsolutions.com\/blog\/how-to-setup-ssl-certificate-in-nginx-on-ubuntu-20-04\/\">How to setup SSL Certificate in Nginx on Ubuntu 20.04<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pheonixsolutions.com\/blog\/how-to-install-and-configure-php-with-nginx-on-centos7\/\">How to install and configure PHP with Nginx on centos7<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Talk to Our Technology Experts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Deploying multiple applications on a single server or need help with your Nginx\/uWSGI setup? Our team can help with application deployment, server architecture, and ongoing infrastructure support.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/pheonixsolutions.com\/contact\">Connect with our technology experts.<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Post Date: August 16, 2018 Last Updated: September 22, 2026 Introduction This guide explains how to configure multiple uWSGI applications [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1022],"tags":[],"class_list":["post-2402","post","type-post","status-publish","format-standard","hentry","category-web-architecture","psol-cat-web-architecture"],"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/phn2x7-CK","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2402","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=2402"}],"version-history":[{"count":2,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2402\/revisions"}],"predecessor-version":[{"id":11959,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2402\/revisions\/11959"}],"wp:attachment":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=2402"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=2402"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=2402"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}