-
Notifications
You must be signed in to change notification settings - Fork 3
Sample Django Deployment
Here is a step-by-step demonstration of how to use deploy-scripts with a brand new Django project.
If you already have an existing project, you can skip to step 4 to see how to add deployment support to it.
- Installing python virtual env
- Create a fresh Django project
- Push the project to your repo
- Install deploy scripts
- Add deploy scripts to project
- Set deploy-scripts variables
- Execute the deployment
- Dockerization (optional)
First, we need to install python virtualenv. On Debian or Ubuntu Linux, we start by installing the python3-venv package
$ sudo apt install python3-venv
Then we create a virtual environment and initialize a basic Django project. We also add our SSH key to our own authorized_keys file since we are doing the demo deployment on our local machine instead of a remote server
# Add your SSH public key to allow access to your own user account
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# We start by creating a directory for the demo
$ cd ~ && mkdir ds_test && cd ds_test
# Following which we initialize a pyvenv environment in the directory
$ python3 -m venv venv
# Activate the virtual environment
$ source venv/bin/activate
# Update pip and install django in the virtual env
(venv) ~/ds_test $ pip install -U pip && pip install "django<3"
# Now we can create a fresh Django project which we will attempt to deploy
(venv) ~/ds_test $ django-admin startproject django_project
(venv) ~/ds_test $ cd django_project/
(venv) ~/ds_test $ python manage.py migrate
# Run the project and see that it is properly accessible through the browser at http://127.0.0.1:8000/
(venv) ~/ds_test $ python manage.py runserver
# Stop the server and add a requirements.txt file listing the dependencies that will be needed by the deployment.
# We will use uwsgi to serve the app on the server side
(venv) ~/ds_test/django_project $ printf "uwsgi\ndjango<3" > requirements.txt
Here is a screenshot of the above steps being executed:
Push the newly created project to your repo on github or another git host. If you don't want to create a new repository online, you can just create a local one in /tmp with these following steps:
(venv) ~/ds_test/django_project $ mkdir /tmp/django_project.git && cd /tmp/django_project.git && git init --bare && cd ~/ds_test/django_project/
(venv) ~/ds_test/django_project $ git init && git add . && git commit . -m "demo project commit"
(venv) ~/ds_test/django_project $ git remote add origin ssh://$USER@localhost/tmp/django_project.git
(venv) ~/ds_test/django_project $ git push -u origin master
Here is a screenshot of a push to a locally created repo using the above steps:
Install the stable version of deploy-scripts to your home directory
(venv) ~/ds_test/django_project $ git clone --single-branch --branch 0.6.0 https://github.com/loanstreet/loanstreet/deploy-scripts.git $HOME/.deploy-scripts/0.6.0
Here is a screenshot of deploy-scripts being downloaded to the home directory
Add deploy scripts to your project
# Run the command to install deploy scripts to the project. The usage is
# sh install.sh [project-type] [project-root]
(venv) ~/ds_test/django_project $ sh ~/.deploy-scripts/0.6.0/installer/install.sh python ~/ds_test/django_project
Here is a screenshot showing the addition of deploy-scripts file to your project. By default, it's installed under a directory called deploy/ in the root of the project
Deployment is configured mainly through editing project-wide variables in deploy/app-config.sh
, and environment-specific variables in deploy/environments/[environment name]/config.sh
.
In our case we will use 'development' as the environment name.
Any other project specific configuration may be done in files placed in the assets/
directory in deploy/environments/[environment name]/assets/
. In this example, we are using uwsgi to serve the app, and we configure the relevant uwsgi.ini
in the assets directory that will be used for it.
# Set the variables in deploy/app-config.sh
TYPE=python
SERVICE_NAME=example.com
# Use either your own project repo on github, or for this example, the local repo you configured in step 3
#[email protected]:user/django_project.git
REPO="ssh://$USER@localhost/tmp/django_project.git"
# The server where your application is to be deployed
DEPLOYMENT_SERVER=localhost
# The ssh user to use when accessing the server to send your deployment to
DEPLOYMENT_SERVER_USER=$USER
RESTART_COMMAND="sh deploy/run.sh restart"
FORMAT=django
LINKED_FILES=""
LINKED_DIRS="venv uploads logs public tmp/sockets tmp/pids"
# Set the variables in deploy/environments/[environment name]/config.sh
# In this case we are using 'development' as the [environment name]
GIT_BRANCH=master
# Let uwsgi run the app on port 9000 instead of a unix socket, so we can check after deployment at the url http://127.0.0.1:9000/
SERVICE_PORT=9000
# Setup deploy/environments/<environment name>/assets/uwsgi.ini with the proper details. In our case, we only need to edit the 'module' value for our project
[uwsgi]
module = django_project.wsgi:application
master = true
processes = 5
chmod-socket = 666
vacuum = true
die-on-term = true
Here is a screenshot of the variables and uwsgi.ini being configured for the demo project
Finally, execute the deployment for the environment we have configured and it should deploy to your server and start the uwsgi process to serve the app.
In our example, we may verify that the app has been deployed and is being served by going to http://127.0.0.1:9000/
# Execute the deployment
# The usage is to execute the deploy.sh script with the environment name as the argument
# sh deploy/deploy.sh [environment name]
(venv) ~/ds_test/django_project $ sh deploy/deploy.sh development
Here are the screenshots that show the demo project being deployed.
- The deploy-scripts project is updated and the branch to be deployed is checked out and prepared for the push to the server
- The files to be sent to the server are pushed to a bare repo on the server and a post-receive hook is triggered on the server to configure the deployment
- Finally, the app server is started to serve the app (using uswgi in this case)
You can verify that the app is being served by going to http://127.0.0.1:9000/
If you wish to dockerize the project on the server, you need to install the docker
and docker-compose
command line tools on the server and configure 2 files in the project
-
deploy/docker/Dockerfile
-
deploy/docker/docker-compose.yml
and add a variable DOCKERIZE=true
to deploy/environments/development/config.sh
Set Dockerfile
and docker-compose.yml
to dockerize the project and serve it with docker-compose on the server. For the demo project we are working with, the files would look something like this:
deploy/docker/Dockerfile
FROM python:3.8-alpine
ENV APP_HOME /app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
COPY requirements.txt ${APP_HOME}/
RUN apk update && apk add --no-cache libpq libstdc++ \
&& apk add --no-cache --virtual .build-deps \
postgresql-dev \
gcc \
musl-dev \
linux-headers \
alpine-sdk \
&& pip install -U pip \
&& pip install --no-cache-dir -r requirements.txt \
&& apk del --no-cache .build-deps
ADD . $APP_HOME
RUN rm -rf Dockerfile docker-compose.yml && echo $'cd /app\npython manage.py runserver 0.0.0.0:80' > start.sh
EXPOSE 80
CMD ["sh", "start.sh"]
deploy/docker/docker-compose.yml
version: '2'
services:
default:
image: django_project:latest
restart: always
build:
context: .
dockerfile: Dockerfile
volumes:
- ./../../shared:/shared
ports:
- 8000:80
env_file:
- ./deploy/config.sh
deploy/environments/development/config.sh
GIT_BRANCH=master
SERVICE_PORT=9000
# Dockerize the project on the server after deployment
DOCKERIZE=true
Once the files have been configured, we can execute the deployment again and see that it dockerizes the app after deployment, and can be accessed at http://127.0.0.1:8000
(or whichever relevant port you configured in docker-compose.yml)
$ sh deploy/deploy.sh development
Here are the screenshots that show the app being dockerized on the server during deployment: