Manage Local Development and Remote Production Environment
As the last topic of this course, we'll explain how to efficiently manage the local development environment and the remote production environment. When you launch your new web service and work with other developers, you'll need to manage both environments simultaneously. As explained earlier, there are three key points in managing the differences between the deployment and production environments.
- Do not share irrelevant files (.gitignore)
- Do not install irrelevant dependencies (requiremetns.txt)
- Do not set irrelevant configurations (settings.py)
This sounds easy, but it is troublesome in practice. Here, we'll summarize the key approaches using our case.
Requirements
We haven't yet explained how to differentiate the requirements files for development and production. We can use the same approach as the one used for settings files. Create the requirements directory and add three files to manage requirements: base.txt, development.txt, and production.txt. Here are the examples of the three files used in our app example.
base.txt
Rename the original requirements.txt, and keep the requirements that are commonly used for both environments.
development.txt
In our case, we are not using any specific library for development. Just get the list from base.txt by writing -r base.txt
.
production.txt
Use -r base.txt
to get the list from base.txt, and add production-specific requirements — just like you did for development.txt.
- gunicorn : application server
- psycopg2-binary : PostgreSQL adapter (PostgreSQL itself is directly installed on Linux)
- django-sendgrid-v5 : for SendGrid
In practice, we usually use more libraries. This approach will be helpful in organizing your requirements for different environments.
The pip command
When you run the pip
command, you need to adjust the file path. For example, when you run the command in the local development environment, run the command like shown below.
pip install -r requirements/development.txt
When you run the command in the remote production environment, run the command below.
pip install -r requirements/production.txt
Settings
We have already explained how to structure the settings files with an example for production settings. Here, we'll summarize the final version of both files.
development.py
Bring key settings specific to the local development environment. If you have the data that you want to manage confidentially, use the .env file. You can also ignore this development.py file using the .gitignore file instead of creating the .env file for development.
SECRET_KEY
is the same for both development and production, but we put it in each requirement file to create a consistent structure.
For EMAIL_BACKEND
, keep two options – console and Gmail, but one setting should be commented out.
Here is an example of an .env file for development. ALLOWED_HOSTS
can be directly written in the development.py file. This is the case when you are using your private IP address for a mobile UI design, which is explained before (Check Developing App UI on Mobile Device).
production.py
Here is the final version of the productino.py example. Put confidential information in the .env file, just like you did for development.py.
In the .env file, we defined the following settings:
SECRET_KEY
ALLOWED_HOSTS
DB
settingsSENDGRID
settings
Managing the .gitignore file
Managing the .gitignore file is very important in practice. If you forget to list files that should be ignored and push your code to a Git repository, reversing this action requires a lot of effort. Thus, you need to be very careful to list all the key files that should not be shared before pushing your code.
You can use gitignore.io to create your .gitignore file, but you need to make sure that you add your virtual environment directory to the list as you define the directory name. As the development and production environments are different, sharing this directory can create several problems.
Frequently used commands
As key commands for the local environment and the production environment are slightly different (e.g., file path), it is beneficial to list them up so that you can copy and paste them when you run the command.
Local development environment
Here is a list of frequently used commands for the local environment that uses our example project (you need to update the commands based on your file name or path setting).
rm -r d_env
python3 -m venv d_env
source d_env/bin/activate
python -m pip install --upgrade pip
pip install -r requirements/development.txt
python manage.py makemigrations --settings config.settings.development
python manage.py migrate --settings config.settings.development
python manage.py createsuperuser --settings config.settings.development
python manage.py runserver --settings config.settings.development
Production environment
Here is a list of frequently used commands for the production environment. The key differences with the list above are the requirement file path and the way of running the Django app. As you cannot use the runserver
command in the production environment, you need to use systemctl
commands.
rm -r d_env
python3 -m venv d_env
source d_env/bin/activate
python -m pip install --upgrade pip pip install -r requirements/production.txt
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic
sudo systemctl restart project_d
systemctl status project_d