Foodgram is an online service where users can post recipes, subscribe to other users' publications, add favorite recipes to their "Favorites" list, and download a summary list of products needed to prepare one or more selected dishes before going to the store.
- For
Django 3.2
- Works with
Python 3.10
- 12-Factor based settings via django-environ
Django REST framework 3.13
- Supports
Postgres
- Optimized development and production settings
- Poetry for managing dependencies
- Docker support using docker-compose for development and production
- Using Nginx on development and Caddy on production
mypy
anddjango-stubs
for static typingflake8
for linting- Tests
- GitHub Actions with full build, test, and deploy pipeline
- Serve static files on production from Yandex Object Storage
On development uses Nginx in conjunction with Gunicorn.
Static content is serving by nginx.
The following tools should be installed:
Download the code and go into the repository:
$ git clone [email protected]:Alex-Men-VL/foodgram.git
$ cd foodgram
Create an .env file based on a template:
$ cp src/.envs/.env.template src/.envs/.env
Start the project:
$ docker-compose up --build
Check container status:
$ docker ps -a
Expected result:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91bb9f1e2f4d foodgram_nginx "/docker-entrypoint.…" 8 seconds ago Up Less than a second 0.0.0.0:80->80/tcp foodgram-nginx-1
ab13c1bb8a07 foodgram_backend:dev "/docker-entrypoint.…" 9 seconds ago Up 2 seconds foodgram-backend-1
90e56294f31e postgres:12.0-alpine "docker-entrypoint.s…" 9 seconds ago Up 5 seconds 0.0.0.0:5432->5432/tcp foodgram-db-1
8823462d857c foodgram_frontend:dev "docker-entrypoint.s…" 9 seconds ago Up 5 seconds 127.0.0.1:3000->3000/tcp foodgram-frontend-1
In the new terminal, without shutting down the site, load test data into the database:
$ docker-compose exec db psql -U <db user name, default - foodgram_db_user> -f /backups/foodgram-test-data.sql
The site is available via links:
Run flake8
linter:
$ docker compose run --rm backend flake8
Run mypy
:
$ docker compose run --rm backend mypy .
Tests cover API and models.
Run Django tests
:
$ docker compose run --rm backend pytest
On development uses Caddy in conjunction with Gunicorn.
Static content is serving by Yandex Object Storage.
The following tools should be installed:
To use existing images:
$ export BACKEND_IMAGE=ghcr.io/alex-men-vl/foodgram/backend:prod
$ export FRONTEND_IMAGE=ghcr.io/alex-men-vl/foodgram/frontend:prod
Download the code and go into the repository:
$ git clone [email protected]:Alex-Men-VL/foodgram.git
$ cd foodgram
Create an .env file based on a template:
$ cp src/.envs/.env.template src/.envs/.env
Start the project:
$ docker-compose -f docker-compose.yaml -f docker-compose.prod.yaml up
Check container status:
$ docker ps -a
Expected result:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
227915090d1f caddy:2.5.2 "caddy run --config …" About a minute ago Up 19 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 2019/tcp foodgram-caddy-1
c433ba699f05 foodgram_backend:prod "/docker-entrypoint.…" About a minute ago Up 37 seconds foodgram-backend-1
c690c3735e12 postgres:12.0-alpine "docker-entrypoint.s…" About a minute ago Up 48 seconds 5432/tcp foodgram-db-1
4f61422d6ab6 foodgram_frontend:prod "docker-entrypoint.s…" About a minute ago Up 48 seconds 127.0.0.1:3000->3000/tcp foodgram-frontend-1
The site is available via links:
Instructions written for deployment via Minikube.
The following tools should be installed:
- kubectl;
- Minikube;
- VirtualBox;
- Database deployed separately from the Kubernetes cluster or via helm.
Download the code and go into the repository:
$ git clone [email protected]:Alex-Men-VL/foodgram.git
$ cd foodgram/kubernetes/prod
Start minikube cluster with VirtualBox driver:
$ minikube start --driver=virtualbox
Get all worker nodes:
$ kubectl get nodes
Expected result:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 2h v1.23.3
Create namespace:
$ kubectl create namespace foodgram-prod
Create Secrets:
Set encoded environment variables from .env.template in secrets.yaml.
Variables must be encoded as shown below.
$ echo -n 'variable_value' | base64
You would see the encoded value as outputs as shown below.
YWRtaW5fcGFzc3dvcmQ=
Enter these values in yaml file.
...
secret_key: YWRtaW5fcGFzc3dvcmQ=
...
Execute the below command so that the secrets are available within the Kubernetes cluster during run time.
kubectl apply -f secrets.yaml
You would see the below message.
secret/django created
secret/aws created
Enable the minikube ingress addon:
$ minikube addons enable ingress
Start the project:
$ ./deploy.sh
You would see the below message.
Run deploy
configmap/web-configmap created
job.batch/django-job created
cronjob.batch/django-clearsessions created
deployment.apps/django-deployment created
service/django-service created
deployment.apps/react-deployment created
service/react-service created
ingress.networking.k8s.io/ingress-service created
Project deployed successfully
List all pods in the namespace:
$ kubectl get pods
Expected result:
NAME READY STATUS RESTARTS AGE
django-deployment-cf468dbc5-hcwmg 1/1 Running 0 48s
django-job-b2p58 0/1 Completed 0 49s
react-deployment-654f4749b-vwxx5 1/1 Running 0 47s
Add the following line to the end of the hosts
file on your computer (requires admin rights):
<minikube ip> star-burger.test
Path to the hosts
file:
Windows10
- C:\Windows\System32\drivers\etc\hostsLinux
- /etc/hostsMac OS X
- /private/etc/hosts
To get minikube ip
use the following command:
minikube ip
The site is available via links:
To get pod logs use the following command:
$ kubectl logs <POD name>
Also, you can use the web-based Kubernetes user interface for troubleshoot your containerized application:
$ minikube dashboard
If possible, it is better to use external databases, put them on a separate VPS, or order a separate Managed Database service from the host.
Install helm.
Add the necessary chart and install it with the following commands.
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install <host name> bitnami/postgresql
The terminal will display an instruction to get the password from the database and a command to connect to it. Connect to the database following the instructions.
Create a new database and user:
CREATE DATABASE <db_name>;
CREATE USER <db_user> WITH ENCRYPTED PASSWORD <'db_password'>;
GRANT ALL PRIVILEGES ON DATABASE <db_name> TO <db_user>;
Specify this values in the file with secrets.
The list of used environment variables is specified in .env.template.
- Menshikov Aleksandr — Site backend — GitHub
MIT licensed. See the LICENSE file for more details.
Yandex practicum for the provided front for the site.