freedomofpress / securedrop.org

Code for the SecureDrop project website
https://securedrop.org
GNU Affero General Public License v3.0
40 stars 9 forks source link

SecureDrop.org

.. image:: https://circleci.com/gh/freedomofpress/securedrop.org.svg?style=svg&circle-token=ae1bdad92b508cea5a86c6a84374af0ae3cf9706 :target: https://circleci.com/gh/freedomofpress/securedrop.org

.. note::

By contributing to this project, you agree to abide by our Code of Conduct <https://github.com/freedomofpress/.github/blob/main/CODE_OF_CONDUCT.md>_.

Table of Contents

Prerequisites

The installation instructions below assume you have Docker on your machine. The easiest way to achieve this is to install Docker Desktop <https://www.docker.com/products/docker-desktop/>_ for your operating system by following the instructions in the appropriate link below:

The instructions also assume you have cloned this repository and are in a shell environment in the base directory of the clone. If this is not the case, run these commands:

.. code:: bash

git clone https://github.com/freedomofpress/securedrop.org.git
cd securedrop.org

Getting Started: The Quick Version

To start the website running in your local environment, run these commands:

.. code:: bash

make dev-init  # one-time command
docker compose up  # long-running process to run application server, every time

# In a separate shell:
make dev-createdevdata  # one-time command

Visit http://localhost:8000/ to see the site.

The URL of the admin area is http://localhost:8000/admin/ for the Wagtail admin. Running the dev data creation command will create login credentials of username "test" and password "test".

Getting Started: The Unabridged Edition

The development environment uses Docker Compose to run the application server, database, and webpack compilation processes.

Before development you must run this one-time command.

.. code:: bash

make dev-init

To start the environment, run the following your first run:

.. code:: bash

docker compose up

This is how you start the server every time you are working on the project. This will start a long-running process. You can exit this process with ctl-c. You may wish to open a second shell to run one-off commands while the server is running.

To populate the project with data suitable for development and testing.

.. code:: bash

make dev-createdevdata

.. important:: Though your database will persist between most runs, it is recommended that you consider it ephemeral and do not use it to store data you don't wish to lose.

You should be able to hit the web server interface at http://localhost:8000/. You can access the Wagtail admin at http://localhost:8000/admin/.

To learn more about Docker Compose, see the docker compose CLI docs <https://docs.docker.com/compose/reference/overview/>_

Management Commands

In addition to the management commands provided by Django <https://docs.djangoproject.com/en/stable/ref/django-admin/>_ and Wagtail <http://docs.wagtail.io/en/stable/reference/management_commands.html>_, the project has a set of its own custom management commands. All commands listed should be prefaced by docker compose exec django ./manage.py.

Dev Data Commands +++++++++++++++++

These commands are meant to be used once at the beginning of development. They can be run individually or all at once using the createdevdata command. They should not be run in production as they create fake data.

Scanner Commands ++++++++++++++++

Search Commands +++++++++++++++

Dependency Management

Adding new requirements +++++++++++++++++++++++

New requirements should be added to *requirements.in files, for use with pip-compile. There are two Python requirements files:

Add the desired dependency to the appropriate .in file, then run:

.. code:: bash

make compile-pip-dependencies

All requirements files will be regenerated based on compatible versions. Multiple .in files can be merged into a single .txt file, for use with pip. The Makefile target handles the merging of multiple files.

This process is the same if a requirement needs to be changed (i.e. its version number restricted) or removed. Make the appropriate change in the correct requirements.in file, then run the above command to compile the dependencies.

Upgrading existing requirements +++++++++++++++++++++++++++++++

There are separate commands to upgrade a package without changing the requirements.in files. The command

.. code:: bash

make pip-update PACKAGE=package-name

will update the package named package-name to the latest version allowed by the constraints in requirements.in and compile a new dev-requirements.txt and requirements.txt based on that version.

Advanced Actions Against the Database

Database import +++++++++++++++

Drop a Postgres database dump into the root of the repo and rename it to import.db. To import it into a running dev session (ensure docker compose up has already been started) run make dev-import-db. Note that this will not pull in images that are referenced from an external site backup.

Connect to PostgreSQL service from host +++++++++++++++++++++++++++++++++++++++

The postgresql service is exposed to your host on a port that will be displayed to you in the output of docker compose port postgresql 5432. If you have a GUI database manipulation application you'd like to utilize point it to localhost with the correct port, username securedrop, password securedroppassword, dbname securedropdb

Mimic production environment +++++++++++++++++++++++++++++++++++

You can mimic a production environment where django is deployed with gunicorn, a reverse nginx proxy, and debug mode off using the ci-docker-compose.yaml file. Note that build time for this container takes much longer than the developer environment:

.. code:: bash

docker compose -f prod-docker-compose.yaml up

It is not run using live-code refresh so it's not a great dev environment but is good for replicating issues that would come up in production.

Database snapshots ++++++++++++++++++

When developing, it is often required to switch branches. These different branches can have mutually incompatible changes to the database, which can render the application inoperable. It is therefore helpful to be able to easily restore the database to a known-good state when making experimental changes. There are two commands provided to assist in this.

make dev-save-db: Saves a snapshot of the current state of the database to a file in the db-snapshots folder. This file is named for the currently checked-out git branch.

make dev-restore-db: Restores the most recent snapshot for the currently checked-out git branch. If none can be found, that is, make dev-save-db has never been run for the current branch, this command will do nothing. If a saved database is found, all data in database will be replaced with that from the file. Note that this command will terminate all connections to the database and delete all data there, so care is encouraged.

Workflow suggestions. I find it helpful to have one snapshot for each active branch I'm working on or reviewing, as well as for master. Checking out a new branch and running its migrations should be followed by running make dev-save-db to give you a baseline to return to when needed.

When checking out a new branch after working on another, it can be helpful to restore your snapshot from master, so that the migrations for the new branch, which were presumably based off of master, will have a clean starting point.

Other Commands

In order to ensure that all commands are run in the same environment, we have added a make flake8 command that runs flake8 in the docker environment, rather than on your local env.

Troubleshooting

Docker Container Woes +++++++++++++++++++++

Sometimes when dependencies are changed or a Docker image needs to be updated for other reasons, the containers will need to be manually triggered to rebuild. These commands, listed in order of destructiveness can resolve most container issues:

.. code:: shell

docker compose up --build

Adding the --build flag tells Docker Compose to detect and update any images that require new changes. You can safely add the --build flag under most circumstances without adverse effects.

.. code:: shell

docker compose up --build --force-recreate

Adding the --force-recreate flag tells Docker Compose to recreate all containers that are part of the application.

If neither of the above fix the issues you're encountering, ensure all docker containers are stopped (ctl-c if containers are running in a shell, docker compose kill if they are running detached) and run the following commands. These commands will remove all images ad containers and rebuild from scratch. Any data in your database will be wiped.

.. code:: shell

docker compose rm
docker compose up --build

Debugging +++++++++

If you want to use the PDB <https://docs.python.org/3/library/pdb.html>_ program for debugging, it is possible. First, add this line to an area of the code you wish to debug:

.. code:: python

import ipdb; ipdb.set_trace()

Second, attach to the running Django container. This must be done in a shell, and it is within this attached shell that you will be able to interact with the debugger. The command to attach is docker attach <ID_OF_DJANGO_CONTAINER>, and on UNIX-type systems, you can look up the ID and attach to the container with this single command:

.. code:: bash

docker attach $(docker compose ps -q django)

Once you have done this, you can load the page that will run the code with your import ipdb and the debugger will activate in the shell you attached. To detach from the shell without stopping the container press Control+P followed by Control+Q.