Skip to content

Commit ad130d1

Browse files
committed
part 2
1 parent e6a6489 commit ad130d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1065
-9
lines changed

.coverage

52 KB
Binary file not shown.

.coveragerc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[run]
2+
omit =
3+
tests/*

.env/.prod-sample

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FLASK_ENV=production
2+
FLACK_CONFIG=production
3+
DATABASE_URL=postgresql://flask_celery:flask_celery@db/flask_celery
4+
SECRET_KEY=my_precious
5+
CELERY_BROKER_URL=amqp://admin:admin@rabbitmq:5672/
6+
CELERY_RESULT_BACKEND=redis://redis:6379/0
7+
SOCKETIO_MESSAGE_QUEUE=redis://redis:6379/0
8+
9+
RABBITMQ_DEFAULT_USER=admin
10+
RABBITMQ_DEFAULT_PASS=admin
11+
12+
CELERY_FLOWER_USER=admin
13+
CELERY_FLOWER_PASSWORD=admin

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
celerybeat.pid
22
.DS_Store
33
__pycache__
4+
upload

compose/auto_deploy_do.sh

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#! /bin/bash
2+
3+
# This shell script quickly deploys your project to your
4+
# DigitalOcean Droplet
5+
6+
# generate TAR file from git
7+
git archive --format tar --output ./project.tar master
8+
9+
echo 'Uploading project...'
10+
rsync ./project.tar root@$DIGITAL_OCEAN_IP_ADDRESS:/tmp/project.tar
11+
echo 'Uploaded complete.'
12+
13+
echo 'Building image...'
14+
ssh -o StrictHostKeyChecking=no root@$DIGITAL_OCEAN_IP_ADDRESS << 'ENDSSH'
15+
mkdir -p /app
16+
rm -rf /app/* && tar -xf /tmp/project.tar -C /app
17+
docker-compose -f /app/docker-compose.prod.yml build
18+
supervisorctl restart flask-celery-app
19+
ENDSSH
20+
echo 'Build complete.'

compose/production/flask/Dockerfile

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
FROM python:3.9-slim-buster
2+
3+
ENV PYTHONUNBUFFERED 1
4+
ENV PYTHONDONTWRITEBYTECODE 1
5+
6+
RUN apt-get update \
7+
# dependencies for building Python packages
8+
&& apt-get install -y build-essential \
9+
# psycopg2 dependencies
10+
&& apt-get install -y libpq-dev \
11+
# Additional dependencies
12+
&& apt-get install -y telnet netcat \
13+
# cleaning up unused files
14+
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
15+
&& rm -rf /var/lib/apt/lists/*
16+
17+
RUN addgroup --system flask \
18+
&& adduser --system --ingroup flask flask
19+
20+
# Requirements are installed here to ensure they will be cached.
21+
COPY ./requirements.txt /requirements.txt
22+
RUN pip install -r /requirements.txt
23+
24+
COPY ./compose/production/flask/entrypoint /entrypoint
25+
RUN sed -i 's/\r$//g' /entrypoint
26+
RUN chmod +x /entrypoint
27+
RUN chown flask /entrypoint
28+
29+
COPY ./compose/production/flask/start /start
30+
RUN sed -i 's/\r$//g' /start
31+
RUN chmod +x /start
32+
RUN chown flask /start
33+
34+
COPY ./compose/production/flask/celery/worker/start /start-celeryworker
35+
RUN sed -i 's/\r$//g' /start-celeryworker
36+
RUN chmod +x /start-celeryworker
37+
RUN chown flask /start-celeryworker
38+
39+
COPY ./compose/production/flask/celery/beat/start /start-celerybeat
40+
RUN sed -i 's/\r$//g' /start-celerybeat
41+
RUN chmod +x /start-celerybeat
42+
RUN chown flask /start-celerybeat
43+
44+
COPY ./compose/production/flask/celery/flower/start /start-flower
45+
RUN sed -i 's/\r$//g' /start-flower
46+
RUN chmod +x /start-flower
47+
48+
RUN mkdir /app
49+
RUN mkdir /app/upload
50+
RUN mkdir /app/flower_db
51+
WORKDIR /app
52+
53+
# copy project code
54+
COPY . .
55+
56+
RUN chown -R flask:flask /app
57+
58+
USER flask
59+
60+
ENTRYPOINT ["/entrypoint"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o nounset
5+
6+
celery beat -A project.wsgi.celery -l info
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o nounset
5+
6+
worker_ready() {
7+
celery -A project.wsgi.celery inspect ping
8+
}
9+
10+
until worker_ready; do
11+
>&2 echo 'Celery workers not available'
12+
sleep 1
13+
done
14+
>&2 echo 'Celery workers is available'
15+
16+
flower --persistent=1 --db=/app/flower_db/flower.db \
17+
--app=project.wsgi.celery \
18+
--broker="${CELERY_BROKER_URL}" \
19+
--basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o nounset
5+
6+
celery worker -A project.wsgi.celery --loglevel=info

compose/production/flask/entrypoint

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/bash
2+
3+
# if any of the commands in your code fails for any reason, the entire script fails
4+
set -o errexit
5+
# fail exit if one of your pipe command fails
6+
set -o pipefail
7+
# exits if any of your variables is not set
8+
set -o nounset
9+
10+
postgres_ready() {
11+
python << END
12+
import sys
13+
14+
import psycopg2
15+
import urllib.parse as urlparse
16+
import os
17+
18+
url = urlparse.urlparse(os.environ['DATABASE_URL'])
19+
dbname = url.path[1:]
20+
user = url.username
21+
password = url.password
22+
host = url.hostname
23+
port = url.port
24+
25+
try:
26+
psycopg2.connect(
27+
dbname=dbname,
28+
user=user,
29+
password=password,
30+
host=host,
31+
port=port
32+
)
33+
except psycopg2.OperationalError:
34+
sys.exit(-1)
35+
sys.exit(0)
36+
37+
END
38+
}
39+
until postgres_ready; do
40+
>&2 echo 'Waiting for PostgreSQL to become available...'
41+
sleep 1
42+
done
43+
>&2 echo 'PostgreSQL is available'
44+
45+
rabbitmq_ready() {
46+
echo "Waiting for rabbitmq..."
47+
48+
while ! nc -z rabbitmq 5672; do
49+
sleep 1
50+
done
51+
52+
echo "rabbitmq started"
53+
}
54+
55+
rabbitmq_ready
56+
57+
exec "$@"

compose/production/flask/start

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
set -o nounset
6+
7+
flask db upgrade
8+
gunicorn project.wsgi:app -k eventlet -w 1 --bind 0.0.0.0:5000 --chdir=/app

compose/production/nginx/Dockerfile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM nginx:1.19-alpine
2+
3+
RUN rm /etc/nginx/conf.d/default.conf
4+
COPY nginx.conf /etc/nginx/conf.d

compose/production/nginx/nginx.conf

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
upstream hello_flask {
2+
server web:5000;
3+
}
4+
5+
upstream celery_flower {
6+
server flower:5555;
7+
}
8+
9+
upstream rabbitmq {
10+
server rabbitmq:15672;
11+
}
12+
13+
server {
14+
listen 80;
15+
location / {
16+
proxy_pass http://hello_flask;
17+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
18+
proxy_set_header Host $host;
19+
proxy_redirect off;
20+
client_max_body_size 20M;
21+
}
22+
location /upload/ {
23+
alias /app/uploadfiles/;
24+
}
25+
26+
location /socket.io {
27+
proxy_pass http://hello_flask;
28+
proxy_http_version 1.1;
29+
proxy_set_header Upgrade $http_upgrade;
30+
proxy_set_header Connection "upgrade";
31+
proxy_set_header Host $http_host;
32+
proxy_set_header X-Real-IP $remote_addr;
33+
}
34+
}
35+
36+
server {
37+
listen 5555;
38+
location / {
39+
proxy_pass http://celery_flower;
40+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
41+
proxy_set_header Host $host;
42+
proxy_redirect off;
43+
}
44+
}
45+
46+
47+
server {
48+
listen 15672;
49+
location / {
50+
proxy_pass http://rabbitmq;
51+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
52+
proxy_set_header Host $host;
53+
proxy_redirect off;
54+
}
55+
}

docker-compose.prod.yml

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
version: '3.8'
2+
3+
services:
4+
5+
nginx:
6+
build: ./compose/production/nginx
7+
volumes:
8+
- mediafiles:/app/upload
9+
ports:
10+
- 80:80
11+
- 5559:5555
12+
- 15672:15672
13+
depends_on:
14+
- web
15+
- flower
16+
17+
web:
18+
build:
19+
context: .
20+
dockerfile: ./compose/production/flask/Dockerfile
21+
command: /start
22+
volumes:
23+
24+
- mediafiles:/app/upload
25+
env_file:
26+
- ./.env/.prod-sample
27+
depends_on:
28+
- redis
29+
- db
30+
31+
db:
32+
image: postgres:13.0-alpine
33+
volumes:
34+
- postgres_data:/var/lib/postgresql/data/
35+
environment:
36+
- POSTGRES_DB=flask_celery
37+
- POSTGRES_USER=flask_celery
38+
- POSTGRES_PASSWORD=flask_celery
39+
40+
redis:
41+
image: redis:6-alpine
42+
43+
rabbitmq:
44+
image: rabbitmq:3-management
45+
env_file:
46+
- ./.env/.prod-sample
47+
48+
celery_worker:
49+
build:
50+
context: .
51+
dockerfile: ./compose/production/flask/Dockerfile
52+
image: flask_celery_example_celery_worker
53+
command: /start-celeryworker
54+
volumes:
55+
- mediafiles:/app/upload
56+
env_file:
57+
- ./.env/.prod-sample
58+
depends_on:
59+
- redis
60+
- db
61+
62+
celery_beat:
63+
build:
64+
context: .
65+
dockerfile: ./compose/production/flask/Dockerfile
66+
image: flask_celery_example_celery_beat
67+
command: /start-celerybeat
68+
volumes:
69+
- mediafiles:/app/upload
70+
env_file:
71+
- ./.env/.prod-sample
72+
depends_on:
73+
- redis
74+
- db
75+
76+
flower:
77+
build:
78+
context: .
79+
dockerfile: ./compose/production/flask/Dockerfile
80+
image: flask_celery_example_celery_flower
81+
command: /start-flower
82+
volumes:
83+
- mediafiles:/app/upload
84+
- flower_db:/app/flower_db
85+
env_file:
86+
- ./.env/.prod-sample
87+
depends_on:
88+
- redis
89+
- db
90+
91+
prometheus:
92+
image: prom/prometheus
93+
ports:
94+
- 9090:9090
95+
command:
96+
- --config.file=/etc/prometheus/prometheus.yml
97+
volumes:
98+
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
99+
depends_on:
100+
- cadvisor
101+
102+
cadvisor:
103+
image: google/cadvisor
104+
container_name: cadvisor
105+
volumes:
106+
- /:/rootfs:ro
107+
- /var/run:/var/run:rw
108+
- /sys:/sys:ro
109+
- /var/lib/docker/:/var/lib/docker:ro
110+
111+
volumes:
112+
postgres_data:
113+
mediafiles:
114+
flower_db:

docker-compose.yml

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ services:
4040
dockerfile: ./compose/local/flask/Dockerfile
4141
image: flask_celery_example_celery_worker
4242
command: /start-celeryworker
43+
# logging:
44+
# driver: syslog
45+
# options:
46+
# syslog-address: "tcp+tls://logs2.papertrailapp.com:45883"
47+
# tag: "{{.Name}}/{{.ID}}"
4348
volumes:
4449
- .:/app
4550
env_file:

0 commit comments

Comments
 (0)