<p>I have an architectural question:
We have a Django project made of multiple apps. There is a core app that holds the main models used for the other sets of apps.
Then, we have a couple apps for user facing APIs. Lastly, we have some internal apps and tools used by developers only that are accessible in Admin UI as extended features.</p>
<p>Our deployment process is very monolithic. We use Kubernetes and we deploy the whole project as a whole. Meaning that if we only had changes in an internal app and we need that in production, we will build a new Docker image and deploy a new release with a new version tag incremented.</p>
<p>I'm not a big fan of this because change in internal tools shouldn't create a new release of the user facing applications.</p>
<p>I have been wondering if there is a way to split those deployments (maybe make them into a microservice architecture?). So we could deploy the user facing applications separate from the internal tools. I know I could build separate images, tags and everything for parts of the project but I'm not sure how they could communicate between each other if <code>internal_app_1</code> depends on the models of <code>core</code> app and potentially the <code>settings.py</code> and <code>manage.py</code> file as well.</p>
<p>Also because in Kubernetes, having to separate applications would mean to separate deployments with two servers running, so this means two separate Django projects isolated from each other but using the same database.</p>
<p>Has anyone worked with something similar or would like to suggest an alternative, if there's any?</p>
<p>Below is a tree example of how our project is structured at the moment:</p>
<pre class="lang-bash prettyprint-override"><code>├── core
|   ├── models.py
|   ├── views.py
|   └── urls.py
├── userapi_1
|   ├── views.py
|   └── urls.py
├── userapi_2
|   ├── views.py
|   └── urls.py
├── insternal_app_1
|   ├── templates
|   |   └── ...
|   ├── models.py
|   ├── views.py
|   └── urls.py
├── manage.py
├── settings.py
└── Dockerfiles
    ├── Dockerfile.core
    └── Dockerfile.internal_app_1
</code></pre>

<p>Django and microservices? Yeah, maybe somewhere in the parallel universe.</p>
<p>Only one thing that I may recommend is to build two identical services like <code>django_container_internal</code> and <code>django_container_production</code>. In this case you will be able to release <code>internal tools</code> without stopping <code>production</code>.</p>
<p>If you want to prevent access to <code>production</code> functionality with <code>internal</code> endpoints you may deactivate <code>production</code> URLs by using <code>ENVs</code>. Usually Django project has common <code>config/urls.py</code> that aggregate all URL endpoints and looks like</p>
<pre class="lang-py prettyprint-override"><code>urlpatterns = [
    url('core/api/v1/', include(core.urls)),
    url('internal/api/v1/', include(internal_app_1.urls)),
    url('user/api/v1/', include(userapi_1.urls))
    ...
]
</code></pre>
<p>For example you may add <code>IS_INTERNAL_TOOLS</code> environment variable and update <code>urls.py</code> like</p>
<pre class="lang-py prettyprint-override"><code>from os import environ

urlpatterns = [
    url('core/api/v1/', include(core.urls)),
    ...
]

if environ.get('IS_INTERNAL_TOOLS', 'false').lower() in ('true', '1', 'yes'):
    urlpatterns.append(url('insternal/api/v1/', include(insternal_app_1.urls)))
else:
    urlpatterns.append(url('user/api/v1/', include(userapi_1.urls)))
</code></pre>
<ul>
<li><p>Pros:</p>
<ul>
<li>All models will be accessible at both services (only one common DAO =&gt; no double developers work to create models twice)</li>
<li>Functionality is separated so only necessary features are accessible</li>
<li>Easy to implement</li>
</ul>
</li>
<li><p>Cons:</p>
<ul>
<li>Whole source code stored inside both of containers even if half of it is not used</li>
<li>If you using two separate databases for internal tools and external API you have to create all tables in both of it (but looks like that is not your case)</li>
<li>Because of it is still monolith <code>internal</code> and <code>production</code> parts heavily dependable on common <code>core</code> and it is impossible to deploy only updated core separately</li>
</ul>
</li>
</ul>
