aboutsummaryrefslogtreecommitdiff
path: root/entrypoint.sh
blob: 99d88435ec3ab652cdf425248c2e5f495affc286 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/bin/sh
printf "\033[1;31m"
set -e
set -x

# The entrypoint script here takes care of basic setup for the application
# writing out the Nginx config, Uwsgi, and optionally running a local
# postgres instance for the application.
#
# The default configuration is to run postgres locally and start in demo mode.
#
# If you actually want to use this application you'll want to of course
# disable that, which can be done by tweaking the environment variables below.
#
# You can use volumes if you want to persist any of the data. The data directory
# for postgres is `/var/postgres`
#
# Uploaded attachments are stored in `/app/media`
#
# Carefully read the vars below. If you needs help understanding the application
# specific ones check out `app/settigns.py` Though it's pretty much just
# passing things into Django

FULL_NAME="${FULL_NAME:-Default App User}"
APP_SHELL="${APP_SHELL:-/bin/ash}"
# UID and GID used by the `git` user inside of the container
APP_UID="${APP_UID:-3500}"
APP_GID="${APP_GID:-3500}"
APP_NAME=dispatch

# If this is anything other than "yes" local postgres will *NOT* be used
LOCAL_POSTGRES="${LOCAL_POSTGRES:-yes}"

# uwsgi conf
UWSGI_PROCESSES="${UWSGI_PROCESSES:-1}"
UWSGI_THREADS="${UWSGI_THREADS:-4}"
UWSGI_SOCKET="${UWSGI_SOCKET:-0.0.0.0:9200}"

# nginx conf
NGINX_PORT="${NGINX_PORT:-8080}"
NGINX_WORKER_PROCESSES="${NGINX_WORKER_PROCESSES:-1}"
NGINX_WORKER_CONNECTIONS="${NGINX_WORKER_CONNECTIONS:-1024}"
NGINX_UWSGI_PASS="${NGINX_UWSGI_PASS:-127.0.0.1:9200}"
NGINX_MAX_BODY_SIZE="${NGINX_MAX_BODY_SIZE:-20m}"
NGINX_BODY_TIMEOUT="${NGINX_BODY_TIMEOUT:-300s}"

# application specific
INIT_DEMO="${INIT_DEMO:-yes}" # Create demo user, data, etc?

# TEMPLATE_VARS= # Comma seperated list of suffixes to extract into vars
# TEMPLATE_VARS_login_info="bla" # for instance is extracted into:
# #    TEMPLATE_VARS["login_info"] = "bla"

# If you need an example, the same thing is done for APP_DB_CONF below:
APP_DB_CONF="${APP_DB_CONF:-ENGINE,NAME,USER,PASSWORD,PORT}"
APP_DB_CONF_ENGINE="${APP_DB_CONF_ENGINE:-django.db.backends.postgresql}"
APP_DB_CONF_NAME="${APP_DB_CONF_NAME:-dispatch}"
APP_DB_CONF_USER="${APP_DB_CONF_USER:-postgres}"
APP_DB_CONF_PASSWORD="${APP_DB_CONF_PASSWORD:-}"
APP_DB_CONF_PORT="${APP_DB_CONF_PORT:-5432}"

# Sqlite example
# APP_DB_CONF=ENGINE,NAME
# APP_DB_CONF_ENGINE=django.db.backends.sqlite3
# APP_DB_CONF_NAME=/app/database.sqlite3

# MySQL Example
# APP_DB_CONF=ENGINE,NAME,USER,PASSWORD,HOST,PORT
# APP_DB_CONF_ENGINE=django.db.backends.mysql
# APP_DB_CONF_NAME=dispatch_test
# APP_DB_CONF_USER=dispatch
# APP_DB_CONF_PASSWORD=changeme
# APP_DB_CONF_HOST=127.0.0.1
# APP_DB_CONF_PORT=3306

# More normal environment variables
WEBSITE_URI="${WEBSITE_URI:-http://example.com}"
WEBSITE_APP_NAME="${WEBSITE_APP_NAME:-Example dispatch tracker}"
USE_EMAIL="${USE_EMAIL:-no}"
STATIC_ROOT="${STATIC_ROOT:-/static}"
EMAIL_USE_TLS="${EMAIL_USE_TLS:-yes}"
EMAIL_PORT="${EMAIL_PORT:-465}"
EMAIL_HOST_USER="${EMAIL_HOST_USER:-example}"
EMAIL_HOST_PASSWORD="${EMAIL_HOST_PASSWORD:-changeme}"
EMAIL_HOST="${EMAIL_HOST:-mail.example.com}"
DEFAULT_FROM_EMAIL="${DEFAULT_FROM_EMAIL:-app@example.com}"
DEBUG="${DEBUG:-no}"
ALLOWED_HOSTS="${ALLOWED_HOSTS:-}" # Defaults to 127.0.0.1 and localhost
ADMINS="${ADMINS:-Bob\'s Name:bobs.email@example.com,other:other@example.com}"
ACCOUNT_ACTIVATION_DAYS="${ACCOUNT_ACTIVATION_DAYS:-7}"

set +x
if [ -z "$SECRET_KEY" ] ; then
	_l="##################################################"
	printf "\n%s\nSET THE SECRET KEY IF YOU'RE IN PRODUCTION\n%s\n" \
		$_l $_l
fi
set -x

printf "\033[0m"

# This is only run once in the container's lifetime unless /setup is removed
setup() {
if [ -e /setup ] ; then return ; fi

addgroup -g "${APP_GID}" $APP_NAME
adduser -h /var/$APP_NAME --gecos "$FULL_NAME" -D -s "${APP_SHELL}" \
	-u "${APP_UID}" -G $APP_NAME $APP_NAME
passwd -u $APP_NAME
addgroup nginx $APP_NAME

chown -R $APP_NAME:$APP_NAME /app /static

touch /setup
}

run_nginx() {
cat > /etc/nginx/nginx.conf <<NGINX
worker_processes $NGINX_WORKER_PROCESSES;
error_log /dev/fd/2;
events {
	worker_connections  $NGINX_WORKER_CONNECTIONS;
}
http {
	access_log /dev/fd/1;
	include	   mime.types;
	default_type  application/octet-stream;
	sendfile		on;
	keepalive_timeout  65;
	gzip  on;
	server_tokens off;
	server {
		listen $NGINX_PORT; listen [::]:$NGINX_PORT;
		root /var/www;
	
		location / {
			include uwsgi_params;
			client_max_body_size ${NGINX_MAX_BODY_SIZE};
			client_body_timeout ${NGINX_BODY_TIMEOUT};
			uwsgi_pass ${NGINX_UWSGI_PASS};
		}

		# Pass through the static directory
		# This should match whatever is in your config file
		location /static {
			alias /static;
		}
		location /robots.txt {
			alias /static/robots.txt;
		}
	}
}
NGINX

mkdir -p /run/nginx
nginx -g 'daemon off;' &
}

run_uwsgi() {
cat > /app/uwsgi.ini <<UWSGI
[uwsgi]
processes = ${UWSGI_PROCESSES}
threads = ${UWSGI_THREADS}

socket = ${UWSGI_SOCKET}
module = wsgi:application
UWSGI

su $APP_NAME -c sh -c "cd /app; exec uwsgi --ini /app/uwsgi.ini" &
}

run_postgres() {
pgdir=/var/postgres
if ! [ -d $pgdir ] ; then
	mkdir $pgdir
	chown postgres:postgres /var/postgres
	su -l -s /bin/sh postgres /bin/sh -c "pg_ctl -D $pgdir initdb"
fi
chown -R postgres:postgres /var/postgres

su -l -s /bin/sh postgres /bin/sh -c "exec postgres -k /tmp -D $pgdir" &

sleep 2
if ! echo "\\l" | psql -U postgres | grep -q dispatch ; then
	echo "create database dispatch" | psql -U postgres
fi

}

init_demo() {
[ -e /init_demo ]  && return
su $APP_NAME -c "./demo.sh"
touch /init_demo
}

watchServices() {
interval="$1"; shift
while true ; do
	services="nginx uwsgi"
	if [ "$LOCAL_POSTGRES" = "yes" ] ; then
		services="$services postgres"
	fi

	for service in $services; do
		if ! pgrep "$service" >/dev/null ; then
			echo "Service $service has stopped... quitting!"
			exit 1
		fi
	done
	sleep "$interval"
done
}

setup
chown -R $APP_NAME:$APP_NAME /app
[ "$LOCAL_POSTGRES" = "yes" ] && run_postgres
[ "$INIT_DEMO" = "yes" ] && init_demo
run_uwsgi
run_nginx

set +x

sleep 10 # Wait around a little bit before we start checking for the
         # services since they don't start that quickly on slow systems.

# Bail out if a service stops, poll it every 30 seconds
watchServices 30

# or if you comment out the above, you can drop into a shell
# exec /bin/ash "$@"