Photo Gallery for Teknologföreningen
See live version of the latest release at: https://foto.tf.fi
The development tool heavily used is Make.
You may find all the commands and variables specified here in the Makefile
.
There are two ways to change environmental variables:
- Copy the file
fotogalleri/.env.example
asfotogalleri/.env
and change values as needed in the newly copiedfotogalleri/.env
file. - Change the default values for environmental variables in
fotogalleri/fotogalleri/settings.py
- E.g. to enable thumbnail generation in production do the following change
ENABLE_THUMB_QUEUE = env('ENABLE_THUMB_QUEUE', True) -> ENABLE_THUMB_QUEUE = env('ENABLE_THUMB_QUEUE', False)
If one wishes to run thumbnail generation when in development one has to set the ENABLE_THUMB_QUEUE
environmental variable to true.
The variable is false by default to avoid accidental thumbnail generations during production.
To run the development server:
make serve
To run tests:
make test
To run the linter:
make lint
To make Django migrations run:
make migrations
To migrate the database:
make migrate
To clean the project:
make clean
To clean everything in the project (includes the virtualenvironment):
make clean-all
To create a virtualenvironment for the project:
make bin/python
This will also install all requirements from the requirements file specified by the REQUIREMENTS_FILE
variable (defaults to requirements.txt
).
This is set as a prerequisite to other rules, so you do not need to explicitly run it, it is always checked before any other command.
Note: the rule uses a variable named PYTHON_EXECUTABLE
to determine which Python version to use (defaults to /usr/bin/python3
).
If you want to change this (e.g. your /usr/bin/python3
points to another version than in the requirements) you may specify it as follows:
make PYTHON_EXECTUABLE=<path/to/python/executable> bin/python
Let's say you just cloned this repository and want to start hacking. What you want to do first is to create the virtual environment:
make bin/python
Then you want to apply all migrations
make migrate
And finally you can serve the project locally:
make serve
Now you're ready to start hacking!
For completeness sake here is a quick copy-paste for the setup:
# Create virtual environment
make bin/python
# Apply migrations
make migrate
# Serve locally
make serve
Before a PR it is good to check that your local code will pass our reviews. To do that with your local setup you have to run our tests and then check the linting. Run the following snippet and your code will be tested and checked for linting errors, run them separately in case something fails:
# Run tests
make test
# Run lint-check
make lint
Note: these production configurations have had the production environment of TF in mind, note that your environment might be setup differently (e.g. deployment).
The ENABLE_THUMB_QUEUE
variable cannot be set dynamically.
To change the variable (and thus enabling thumbnail generation) one has to temporarily turn off the production application while changing the variable.
First and foremost you have to deploy the repository to your server.
There are multiple ways to do this, one way would be to have a production Git remote on your server, to which you can push every release and automate deployment through a post-receive
hook.
The deployment strategy below assumes you have deployed the application to /var/www/fotogalleri
and that you've setup a Python virtual environment in the root the of the application directory.
Before starting the production application, check whether your desired and required options are set in fotogaller/.env
.
An example configuration can be found under fotogaller/.env.example
.
Anything that spins up a Django application should work, however, only WSGI
through Gunicorn has been tested.
The application is pre-configured to run with WSGI
, the accompanying file can be found under fotogalleri/fotogalleri/fotogalleri/wsgi.py
.
To run the WSGI
application use a WSGI HTTP server
, in this deployment strategy we use Gunicorn.
You can spin up a Gunicorn instance with, e.g., a SystemD
service and socket file, and then configure a proxy to this instance from your webserver.
[Unit]
Description=gunicorn3 daemon for fotogalleri
Requires=fotogalleri.socket
After=network.target
[Service]
PermissionsStartOnly=True
RuntimeDirectory=fotogalleri
PIDFile=/run/fotogalleri/pid
User=www-data
Group=www-data
WorkingDirectory=/var/www/fotogalleri/fotogalleri
Environment=PYTHONPATH=/var/www/fotogalleri/lib/python3.5/site-packages
ExecStart=/usr/bin/gunicorn3 --pid /run/fotogalleri/pid --timeout 90 fotogalleri.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[Unit]
Description=gunicorn3 socket for fotogalleri
[Socket]
ListenStream=/run/fotogalleri/socket
ListenStream=0.0.0.0:8888
[Install]
WantedBy=sockets.target
Note the port you set for ListenStream
.
In production mode Django does not serve static files nor images. The distinction this project uses is that static files are files for the interface itself (e.g. CSS and icons) while images are the images that the gallery actually serves. This makes the whole project less cluttered and enables you have separation of concerns regarding static images and served images.
The root of all static files are assumed to be under fotogalleri/gallery/static/
.
Thus move all static files there if you have additional ones, or you have, e.g., a new app with static files that you want served as well.
Note: this could be circumvented if one configured the STATICFILES_DIRS
variable in the project settings.
Currently, however, we only have one app, so this is not used.
As this project is a interface for a flat-file directory of images (the Django models are only concerned with metadata) you have to setup a server for serving images.
The project is agnostic to how this is done, the only thing assumed is that the images can be found under the endpoint /images
as a directory structure.
One solution for serving images could be symlinking the images directory to the root of the application (i.e. /images
) and serving this directory with Apache2.
This would allow you to use the images directory itself for other tasks (e.g. having an ftp
server).
For symlinking you could do this (replacing <IMAGE_DIRECTORY_PATH>
with the path to your image directory):
ln --symbolic --relative <IMAGE_DIRECTORY_PATH> /var/www/fotogalleri/images
And then append this to you Apache site configuration:
Alias /images/ /var/www/fotogalleri/images/
<Directory /var/www/fotogalleri/images>
Require all granted
Options -Indexes
</Directory>
ProxyPass "/images" !
ProxyPassReverse "/images" !
Note: this deployment strategy assumes that the project is setup according to First time setup.
Deploying a release is quite simple once the application is setup once:
- Deploy the new version code to your server. This can, again, be done with, e.g., a Git solution: push the new version to the server.
- Check that code deployment went as expected.
- Check that your environmental variables are setup as you want them.
- Check that images are still available through the setup directory.
- Move any needed static files to
fotogalleri/gallery/static/
.
- Restart the
SystemD
service (e.g.systemctl restart fotogalleri.service
).