DevOps Architecture
├── .github/
│ └── ISSUE_TEMPLATE/
├── app/
│ ├── config/
│ └── settings.py
│ ├── frontend/
│ ├── server/
│ ├── .babelrc
│ ├── manage.py
│ ├── requirements.txt
│ ├── package.json
│ ├── package-lock.json
│ └── webpack.config.js
├── dev/ # DevOps
│ ├── django.dockerfile
│ ├── webpack.dockerfile
│ └── dev.env
├── .dockerignore # DevOps
├── .gitignore
├── jsconfig.json
├── CONTRIBUTING.md
├── docker-compose.yml # DevOps
├── LICENSE
└── README.md
Overall project structure
├── dev/
│ ├── django.dockerfile
│ ├── webpack.dockerfile
│ └── dev.env.example
├── .dockerignore
├── docker-compose.yml
├── alias-config.txt
└── alias.sh
DevOps Architecture
Summary
DevOps Tech Stack: Docker, Gunicorn, Nginx, PostgreSQL, test
Our devops files can be thought of as a set of files needed to create an exact replica of our environments for our developers. Although the overall structure appears deceptively basic, it only represents a fraction of our devops files. Several of our files, such as the ones that construct our staging environment, contains sensitive information, and as such as not placed in our public repository. For most frontend and backend work, there is never a need to access these files.
*Note: On the rare occasions that there is a need to access the sensitive files for environments other than development, please consult the development lead of the project. They will know exactly what files you need, and what permissions you need to access them.
Overview of Directories and Files
- dev/: contains two dockerfiles and an env file.
django.dockerfile
contains information for our Django server setup.webpack.dockerfile
contains information to start our webpack watch plugin.dev.env.example
is an example of the env file needed to configure our dev environment. - .dockerignore: This file tells Docker to ignore certain files when building the container. These are usually files that pertain to docker or git, which are not important when building the webserver.
- docker-compose.yml: Contains instructions for docker when we run "docker compose". To know more about what each line does, please consult Docker's documentation.
- alias.sh: Contains a shell script that allows for cumbersome commands to be executed with less typing by leveraging the aliases listed in
alias-config.txt
Docker
Docker is a platform that allows packaging and virtualizing applications within a container. This gives developers the powerful ability to collaborate in a stable, synchonized environment, and deploying web applications with the greatest of ease. We will not be going too much into Docker here, but we will explain in greater depth some of the Docker configurations we have made.
docker-compose.yml
This file contains configuration directions for docker compose. It consists of three services: pgdb (our database), webpack (our webpack bundler), and django (our django server). The webpack and django service relies in separate dockerfiles, located in the dev
directory to build the container. This separation of dockerfiles enable each container to be build with its own set of dependencies. It also makes rebuilding the container simple when dependencies are migrated to a newer version.
For those of you used to creating applications without Docker, most would run webpack and django in separate terminals, so that they can both run at the same time. For the purposes of brevity, the different services can be considered to be Docker's way of running separate terminals.
One will also notice that the Django command uses a placeholder server name, 0.0.0.0:8000. This placeholder is important, since Docker creates an isolated environment. As a result, servers that are run in Docker does not recognize a browser from outside of that environment. Without this server name, localhost:8000 will not reach the server, as the server would recognize your browser as coming from a foreign machine. Therefore, all warnings related to 0.0.0.0, should they pop-up, should be ignored.
*.dockerfile
Dockerfiles are files that define how a container is built. Although containerization is a deep concept, to put it briefly, you can think of containers as separate "mini-computers", each programmed to do one thing. Some containers, such as our pgdb
container does not require a dockerfile to configure it, as it works out of the box. On the otherhand, our webpack
and django
containers need dockerfile to built out the files we need to run it effectively.
FROM node:latest
WORKDIR /code
# install app dependencies
COPY ./package.json ./
COPY ./package-lock.json ./
RUN npm install
# add app
COPY . .
Sample dockerfile that copies the package.json from a project and installs all dependencies.
Dockerfiles are usually named as just dockerfile
, as that is the default name that docker looks for when constructing our builds. Since our project requires multiple dockerfiles, we name them with .dockerfile
extensions, a convention that allows VSCode to detect dockerfiles and use appropriate syntax highlighting.
Do note that docker and dockerfiles can be fickle to work with, especially on old devices. Further down this documentation are various tips and commands that can be used with docker to help debug your code. But as always, consulting official documentation is the best way to get accurate, up-to-date information.
Environments
Development
Our development environment is entirely defined by our docker-compose.yml
, and the files inside of dev/
. More information about those files can be found above.
Of note, however, is the dev.env.example file. This file is only a sample, but lists out all the environmental variables needed to run our site. While most of them are prefilled, some uses <>
to indicate placeholders, which must be filled in by the developer.
Staging
More information on our staging files can be found with our staging files. To access this information, please ask for the required permissions from the development lead.
Useful Commands
docker compose down -v
Useful to completely remove a container and related volumes. This is helpful when fiddling with database settings, which often breaks the database. This command allows the container to be restarted fresh.
docker compose -f <filename> <docker command>
Use this to specify an alternate docker-compose file to run your commands, such as docker-compose-other.yml. This is useful if you want to test out docker for yourself.
docker compose run <container> <command>
This is useful to run one time commands inside your container. Some good commands to run are:
- python manage.py makemigrations
- python manage.py migrate
- python manage.py createsuperruser
- pip install -r requirements.txt
- npm install
docker exec -it <container> sh
Use this to do heavier debugging inside of your container. What this does is open the shell inside of the container's "mini-computer". This allows you to explore the files inside the container to see if it matches what you would expect after building is finished. This command only works when a container is running, so use docker compose run -d
to run your container in the background beforehand.
docker compose build --progress=plain
Sometimes when a build is happening, the logs are too opaque to debug if a step goes wrong. This commands makes the logs a bit more verbose so that you might have an easier time debugging.
Alias Shell Script
For convenience, we have created a shell script that allows for longer commands to be executed with less typing. The script is capable of executing any of the commands listed in alias-config.txt
without having to type out the entire command.
alias.sh
To use this script, run bash alias.sh $arg
or ./alias.sh $arg
where $arg
is the alias of the command you wish to execute. For example, try running bash alias.sh test
.
alias-config.txt
This file contains many of the important commands you will need when developing for this project. Note that each command starts with a single word followed by a :
and then a command. You must follow this pattern when adding additional commands to the file. Please note that any docker run
commands must use the -T
flag to allocate a pusedo-TTY or the command will not work.