Skip to content

Commit 6d7869c

Browse files
authored
Merge pull request #151 from bit-bots/feature/dockerfile
add docker and kubernetes configs
2 parents f767eb2 + f413c16 commit 6d7869c

File tree

11 files changed

+311
-6
lines changed

11 files changed

+311
-6
lines changed

Dockerfile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
FROM docker.io/debian:buster-slim
2+
3+
# install imagetagger system dependencies
4+
RUN apt-get update && \
5+
apt-get install --no-install-recommends -y g++ wget uwsgi-plugin-python3 python3 python3-pip node-uglify make git \
6+
python3-psycopg2 python3-ldap3 gettext gcc python3-dev python3-setuptools libldap2-dev libsasl2-dev nginx
7+
8+
# add requirements file
9+
WORKDIR /app/src
10+
COPY requirements.txt /app/src/requirements.txt
11+
12+
# install python dependencies
13+
RUN pip3 install -r /app/src/requirements.txt
14+
RUN pip3 install sentry-sdk uwsgi django-ldapdb django-auth-ldap
15+
16+
# clean container
17+
RUN apt-get purge -y --auto-remove node-uglify git python3-pip make gcc python3-dev libldap2-dev libsasl2-dev \
18+
python3-setuptools
19+
RUN apt-get clean
20+
21+
# add remaining sources
22+
COPY imagetagger /app/src/imagetagger
23+
24+
# confiure runtime environment
25+
RUN mkdir /app/data /app/static /app/config
26+
RUN cp /app/src/imagetagger/imagetagger/settings.py.example /app/config/settings.py
27+
RUN ln -sf /app/config/settings.py /app/src/imagetagger/imagetagger/settings.py
28+
RUN sed -i 's/env python/env python3/g' /app/src/imagetagger/manage.py
29+
30+
ARG UID_WWW_DATA=5008
31+
ARG GID_WWW_DATA=33
32+
RUN usermod -u $UID_WWW_DATA -g $GID_WWW_DATA -d /app/data/ www-data
33+
RUN chown -R www-data /app
34+
35+
RUN /app/src/imagetagger/manage.py collectstatic --no-input
36+
37+
COPY docker/uwsgi_imagetagger.ini /etc/uwsgi/imagetagger.ini
38+
COPY docker/nginx.conf /etc/nginx/sites-enabled/default
39+
COPY docker/update_points docker/zip_daemon docker/run /app/bin/
40+
RUN ln -sf /app/bin/* /usr/local/bin
41+
ENTRYPOINT ["/usr/local/bin/run"]
42+
ENV IN_DOCKER=true
43+
44+
# add image metadata
45+
EXPOSE 3008
46+
EXPOSE 80
47+
VOLUME /app/config
48+
VOLUME /app/data
49+

docker/nginx.conf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# vim: set filetype=conf:
2+
3+
server {
4+
listen 80;
5+
server_name default_server;
6+
root /var/www/imagetagger;
7+
8+
client_max_body_size 4G;
9+
10+
location / {
11+
include uwsgi_params;
12+
uwsgi_pass localhost:3008;
13+
uwsgi_read_timeout 120;
14+
}
15+
16+
location /static {
17+
expires 1h;
18+
alias /var/www/imagetagger;
19+
}
20+
21+
location /ngx_static_dn/ {
22+
internal;
23+
alias /app/data/images/;
24+
}
25+
26+
27+
location /_internal_auth/ {
28+
rewrite ^/_internal_auth/ngx_std_direct/(\d*)/(.*)$ /images/image_nginx/$1 last;
29+
}
30+
31+
access_log /var/log/nginx/access.log;
32+
error_log /var/log/nginx/error.log;
33+
}
34+

docker/run

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
set -e
3+
4+
/app/src/imagetagger/manage.py migrate
5+
6+
nginx
7+
exec uwsgi /etc/uwsgi/imagetagger.ini
8+

docker/update_points

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
/app/src/imagetagger/manage.py updatepoints
4+

docker/uwsgi_imagetagger.ini

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[uwsgi]
2+
procname-master = uwsgi %n
3+
master = true
4+
socket = :3008
5+
6+
chdir = /app/src/imagetagger
7+
8+
module = imagetagger.wsgi:application
9+
env = DJANGO_SETTINGS_MODULE=imagetagger.settings
10+
11+
; drop privileges
12+
uid = www-data
13+
gid = www-data
14+
umask = 027
15+
16+
; run with at least 1 process but increase up to 4 when needed
17+
processes = 8
18+
cheaper = 2
19+
20+
; reload whenever this config file changes
21+
; %p is the full path of the current config file
22+
touch-reload = %p
23+
24+
; disable uWSGI request logging
25+
disable-logging = true
26+
27+
enable-threads = true
28+
29+
; update points every hour
30+
cron2 = day=-1,unique=1 /usr/local/bin/update_points
31+
smart-attach-daemon2 = /tmp/zipdaemon.pid /usr/local/bin/zip_daemon

docker/zip_daemon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
/app/src/imagetagger/manage.py runzipdaemon
4+

imagetagger/imagetagger/settings.py.example

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SECRET_KEY = 'DEV KEY PLEASE CHANGE IN PRODUCTION INTO SOMETHING RANDOM'
1111
DEBUG = True
1212

1313
# Allowed Host headers this site can server
14-
ALLOWED_HOSTS = ['imagetagger.example.com']
14+
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
1515

1616
# Additional installed apps
1717
INSTALLED_APPS += [
@@ -25,7 +25,7 @@ DATABASES = {
2525
'default': {
2626
# Imagetagger relies on some Postgres features so other Databses will _not_ work
2727
'ENGINE': 'django.db.backends.postgresql_psycopg2',
28-
'HOST': '127.0.0.1',
28+
'HOST': 'imagetagger-postgres',
2929
'NAME': 'imagetagger',
3030
'PASSWORD': 'imagetagger',
3131
'USER': 'imagetagger',
@@ -39,7 +39,7 @@ LANGUAGE_CODE = 'en-us'
3939

4040
# TIME_ZONE = 'Europe/Berlin' #Timezone of your server
4141

42-
# STATIC_URL = '/static/'
42+
STATIC_ROOT = '/var/www/imagetagger'
4343

4444
# EXPORT_SEPARATOR = '|'
4545
# DATA_PATH = os.path.join(BASE_DIR, 'data')
@@ -52,7 +52,8 @@ LANGUAGE_CODE = 'en-us'
5252
# 'jpg',
5353
# }
5454

55-
USE_NGINX_IMAGE_PROVISION = False # defines if images get provided directly via nginx what generally improves imageset download performance
55+
# defines if images get provided directly via nginx which generally improves imageset download performance
56+
USE_NGINX_IMAGE_PROVISION = True if os.getenv("IN_DOCKER", "") != "" else False
5657

5758
# The 'report a problem' page on an internal server error can either be a custom url or a text that can be defined here.
5859
# PROBLEMS_URL = 'https://problems.example.com'
@@ -69,14 +70,18 @@ ACCOUNT_ACTIVATION_DAYS = 7
6970

7071
UPLOAD_FS_GROUP = 33 # www-data on debian
7172

72-
ENABLE_ZIP_DOWNLOAD = False # If enabled, run manage.py runzipdaemon to create the zip files and keep them up to date
73+
# If enabled, run manage.py runzipdaemon to create the zip files and keep them up to date
74+
ENABLE_ZIP_DOWNLOAD = True if os.getenv("IN_DOCKER", "") != "" else False
7375

7476
# Test mail functionality by printing mails to console:
7577
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
7678
TOOLS_ENABLED = True
77-
TOOLS_PATH = os.path.join(BASE_DIR, 'tools')
7879
TOOL_UPLOAD_NOTICE = ''
7980

81+
DATA_PATH = '/app/data'
82+
IMAGE_PATH = DATA_PATH + '/images'
83+
TOOLS_PATH = DATA_PATH + '/tools'
84+
8085
# Use ldap login
8186
#
8287
# import ldap

k8s/namespace.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
kind: Namespace
3+
apiVersion: v1
4+
metadata:
5+
name: imagetagger

k8s/postgres.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
kind: Service
3+
apiVersion: v1
4+
metadata:
5+
name: imagetagger-postgres
6+
labels:
7+
tier: database
8+
spec:
9+
selector:
10+
tier: database
11+
ports:
12+
- name: postgres
13+
port: 5432
14+
targetPort: postgres
15+
16+
---
17+
kind: Deployment
18+
apiVersion: apps/v1
19+
metadata:
20+
name: imagetagger-postgres
21+
labels:
22+
tier: database
23+
spec:
24+
selector:
25+
matchLabels:
26+
tier: database
27+
template:
28+
metadata:
29+
labels:
30+
tier: database
31+
spec:
32+
automountServiceAccountToken: false
33+
volumes:
34+
- name: data
35+
persistentVolumeClaim:
36+
claimName: imagetagger-database
37+
containers:
38+
- name: main
39+
image: docker.io/postgres:12
40+
imagePullPolicy: Always
41+
envFrom:
42+
- configMapRef:
43+
name: imagetagger-postgres
44+
env:
45+
# postgres recommends putting the actual data in a sub-folder if it is mounted from external sources
46+
- name: PGDATA
47+
value: /var/lib/postgresql/data/pgdata
48+
volumeMounts:
49+
- name: data
50+
mountPath: /var/lib/postgresql/data
51+
ports:
52+
- name: postgres
53+
containerPort: 5432
54+
livenessProbe:
55+
tcpSocket:
56+
port: postgres
57+
58+
---
59+
kind: PersistentVolumeClaim
60+
apiVersion: v1
61+
metadata:
62+
name: imagetagger-database
63+
spec:
64+
accessModes:
65+
- ReadWriteMany
66+
resources:
67+
requests:
68+
storage: 1Gi # should be enough even for large instances
69+
selector:
70+
matchLabels:
71+
tier: database

k8s/web_app.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
kind: Service
3+
apiVersion: v1
4+
metadata:
5+
name: imagetagger-web
6+
labels:
7+
tier: web
8+
spec:
9+
selector:
10+
tier: web
11+
ports:
12+
- name: http
13+
port: 80
14+
targetPort: http
15+
16+
---
17+
apiVersion: apps/v1
18+
kind: Deployment
19+
metadata:
20+
name: imagetagger-web
21+
labels:
22+
tier: web
23+
spec:
24+
selector:
25+
matchLabels:
26+
tier: web
27+
template:
28+
metadata:
29+
labels:
30+
tier: web
31+
spec:
32+
volumes:
33+
- name: config
34+
configMap:
35+
name: imagetagger-web
36+
- name: data
37+
persistentVolumeClaim:
38+
claimName: imagetagger-image-data
39+
containers:
40+
- name: main
41+
image: imagetagger:local
42+
ports:
43+
- name: uwsgi
44+
containerPort: 3008
45+
- name: http
46+
containerPort: 80
47+
volumeMounts:
48+
- name: config
49+
mountPath: /app/config
50+
readOnly: true
51+
- name: data
52+
mountPath: /app/data
53+
livenessProbe:
54+
tcpSocket:
55+
port: uwsgi
56+
startupProbe:
57+
tcpSocket:
58+
port: uwsgi
59+
60+
---
61+
kind: PersistentVolumeClaim
62+
apiVersion: v1
63+
metadata:
64+
name: imagetagger-image-data
65+
spec:
66+
accessModes:
67+
- ReadWriteMany
68+
resources:
69+
requests:
70+
storage: 2Gi # in production we need a lot more but this should be enough for a test or dev instance
71+
selector:
72+
matchLabels:
73+
tier: web

kustomization.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
kind: Kustomization
3+
apiVersion: kustomize.config.k8s.io/v1beta1
4+
namespace: imagetagger
5+
commonLabels:
6+
app: imagetagger
7+
8+
resources:
9+
- k8s/namespace.yml
10+
- k8s/postgres.yml
11+
- k8s/web_app.yml
12+
13+
configMapGenerator:
14+
- name: imagetagger-web
15+
files:
16+
- "settings.py=./imagetagger/imagetagger/settings.py.example"
17+
- name: imagetagger-postgres
18+
literals:
19+
- "POSTGRES_PASSWORD=imagetagger"
20+
- "POSTGRES_USER=imagetagger"
21+
- "POSTGRES_DB=imagetagger"

0 commit comments

Comments
 (0)