Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shift to Quart for ASGI support #38

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
FROM python:3.7-slim-buster

# Install Nginx
# Ref: https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/install-nginx-debian.sh
COPY scripts/install-nginx-debian.sh /
RUN bash /install-nginx-debian.sh

# Remove default configuration from Nginx
RUN rm /etc/nginx/conf.d/default.conf

# Install depedencies like supervisord, curl, etc.
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential git supervisor curl python3-dev \
&& apt-get purge -y --auto-remove \
&& rm -rf /var/lib/apt/lists/*

# Install Python requirements
COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt

# Copy configurations to the container
WORKDIR /app
COPY config/nginx-sharq.conf /etc/nginx/conf.d/sharq.conf
COPY config/nginx.conf /etc/nginx/nginx.conf
COPY config/sharq-local.conf /app/config/sharq.conf
COPY config/sharq-server-basicauth /etc/nginx/conf.d/sharq-server-basicauth
COPY config/supervisord.conf /etc/supervisord.conf

# Copy application code to the container
COPY sharq_server /app/sharq_server

# Start supervisord with Nginx and uvicorn
COPY scripts/start.sh /app/start.sh
RUN chmod +x /app/start.sh
CMD ["/app/start.sh"]
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
@Library('plivo_standard_libs@production') _

deliveryPipeline ([
buildContainer: 'plivo/jenkins-ci/python/2.7.14/ci-base/ubuntu/trusty:18.02.01.139',
buildContainer: 'plivo/jenkins-ci/python:buster-3.8.9',
disableQAStages: true
])
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: clean build install uninstall test run
.PHONY: clean build install uninstall test run docker-build docker-run start

all: clean

Expand All @@ -22,3 +22,13 @@ test:

run:
sharq-server --config sharq.conf

docker-build:
docker build -f docker/Dockerfile -t sharq .

docker-run:
docker run -p 8000:8000 sharq

start:
docker-compose up start-dependencies
docker-compose up --build --remove-orphans
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ $curl http://127.0.0.1:8080/
}
```

## Development

### With Docker & Docker Compose

> Pre-requisites: Install latest stable versions of Docker and Docker Compose.

1. Clone the repository locally.
2. From repository root, run:

```bash
make start
```

3. Sharq server will be up and running at `http://localhost:8000`.

> Note: Try out `/status/` & `/deepstatus/` (checks connectivity with Redis) endpoints.

## Documentation

Check out [sharq.io](http://sharq.io) for documentation.
Expand Down
57 changes: 33 additions & 24 deletions ci/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
FROM python:3.6-slim-buster
FROM python:3.7-slim-buster

ENV CONSUL_TEMPLATE_VERSION 0.19.5

# Install Nginx
# Ref: https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/install-nginx-debian.sh
COPY scripts/install-nginx-debian.sh /
RUN bash /install-nginx-debian.sh

RUN mkdir -p /opt/sharq-server
WORKDIR /opt/sharq-server
COPY . /opt/sharq-server
RUN mkdir /etc/supervisord && mkdir /etc/supervisord/conf.d && mkdir /var/log/supervisord && pip install supervisor
RUN apt-get update && apt-get install -y nginx g++ git curl && pip install virtualenv envtpl
# Remove default configuration from Nginx
RUN rm /etc/nginx/conf.d/default.conf

RUN curl -L https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.tgz | tar -C /usr/sbin -xzf -
RUN virtualenv /opt/sharq-server
RUN . /opt/sharq-server/bin/activate && /opt/sharq-server/bin/pip install --no-cache-dir -r /opt/sharq-server/requirements.txt && /opt/sharq-server/bin/python setup.py install -f

ADD src/config /etc/sharq-server/config
ADD src/config/nginx.conf /etc/nginx/nginx.conf
ADD src/config/nginx-sharq.conf /etc/nginx/conf.d/sharq.conf
ADD src/config/sharq-server-basicauth /etc/nginx/conf.d/sharq-server-basicauth
# Install depedencies like supervisord, curl, etc.
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential git supervisor curl python3-dev \
&& apt-get purge -y --auto-remove \
&& rm -rf /var/lib/apt/lists/*

COPY src/config/sharq.conf.ctmpl /etc/sharq-server/config/sharq.conf.ctmpl
COPY src/config/sharq.ini.ctmpl /etc/sharq-server/config/sharq.ini.ctmpl
COPY src/config/sharq.ini.ctmpl /etc/sharq-server/config/sharq.ini
COPY src/config/supervisord.conf /etc/supervisord.conf
RUN mkdir /var/run/sharq/

COPY ci/entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh && \
chown root:root /entrypoint.sh
# Install consul-template
RUN curl -L https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.tgz | tar -C /usr/sbin -xzf -

ENTRYPOINT ["/entrypoint.sh"]
# Install Python requirements
COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt

# Copy configurations to the container
WORKDIR /app
COPY config/nginx-sharq.conf /etc/nginx/conf.d/sharq.conf
COPY config/nginx.conf /etc/nginx/nginx.conf
COPY config/sharq-server-basicauth /etc/nginx/conf.d/sharq-server-basicauth
COPY config/sharq.conf.ctmpl /app/config/
COPY config/supervisord.conf /etc/supervisord.conf

# Copy application code to the container
COPY sharq_server /app/sharq_server

# Start supervisord with Nginx and uvicorn
COPY ci/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
CMD ["/app/entrypoint.sh"]
6 changes: 3 additions & 3 deletions ci/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ echo "

/usr/sbin/consul-template \
-consul-addr "$CONSUL" \
-template "/etc/sharq-server/config/sharq.conf.ctmpl:/etc/sharq-server/config/sharq.conf" \
-template "/etc/sharq-server/config/sharq.ini.ctmpl:/etc/sharq-server/config/sharq.ini" \
-template "/app/config/sharq.conf.ctmpl:/app/config/sharq.conf" \
-consul-retry-attempts=0 -once

echo "All templates are rendered. Starting sharq-server..."

supervisord -c /etc/supervisord.conf
# Start Supervisor, with Nginx and sharq-server
exec /usr/bin/supervisord -n -c /etc/supervisord.conf
31 changes: 31 additions & 0 deletions config/nginx-sharq.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
server {
listen *:8000;
server_name _;

keepalive_timeout 120;

location /status/ {
rewrite ^/status/$ / break;
proxy_pass http://localhost:8080;
}

location / {
log_not_found off;
auth_basic "gO AwAy!";
auth_basic_user_file /etc/nginx/conf.d/sharq-server-basicauth;

proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://localhost:8080;
}
}

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
File renamed without changes.
22 changes: 22 additions & 0 deletions config/sharq-local.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; NOTE: Only to be used for local development with Docker and Docker Compose.

[sharq]
job_expire_interval = 1000
job_requeue_interval = 1000
default_job_requeue_limit = -1
enable_requeue_script = false

[sharq-server]
host = 127.0.0.1
port = 8080
accesslog = /tmp/sharq.log

[redis]
db = 0
key_prefix = sms
conn_type = tcp_sock
unix_socket_path = /tmp/redis.sock
port = 7000
host = redis-clustered
clustered = true
password =
File renamed without changes.
File renamed without changes.
9 changes: 6 additions & 3 deletions src/config/supervisord.conf → config/supervisord.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
nodaemon=true
user=root

[program:uwsgi]
command=/opt/sharq-server/bin/uwsgi --ini /etc/sharq-server/config/sharq.ini --die-on-term
[fcgi-program:uvicorn]
socket=tcp://localhost:8080
command=/usr/local/bin/uvicorn --fd 0 --forwarded-allow-ips='*' --no-access-log sharq_server:app --port 8080
numprocs=4
process_name=uvicorn-%(process_num)d
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
Expand All @@ -15,4 +18,4 @@ command=nginx -g 'daemon off;'
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stderr_logfile_maxbytes=0
37 changes: 37 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
version: '3'

services:
sharq-server:
build:
context: .
dockerfile: Dockerfile # Use ci/Dockerfile to test CI build
image: sharq-server
container_name: sharq-server
environment:
- LOG_LEVEL=warning
- ACCESS_LOG=
# Uncomment following to test build with ci/Dockerfile
aayush-plivo marked this conversation as resolved.
Show resolved Hide resolved
# - CONSUL=https://consul.non-prod.plivops.com
# - REGION=us-east-1
# - ENVIRONMENT=dev
# - TEAM=sms
# - SHARQ_TYPE=sharq-clustered
ports:
- 8000:8000
depends_on:
- redis-clustered

redis-clustered:
image: grokzen/redis-cluster:5.0.4
ports:
- '7000-7005:7000-7005'
environment:
- IP=0.0.0.0
logging:
driver: none

start-dependencies:
image: dadarek/wait-for-dependencies
depends_on:
- redis-clustered
command: redis-clustered:7000 redis-clustered:7001 redis-clustered:7002 redis-clustered:7003 redis-clustered:7004 redis-clustered:7005
6 changes: 2 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
Flask==0.10.1
Jinja2==2.7.2
MarkupSafe==0.23
Werkzeug==0.9.4
argparse==1.2.1
gevent==20.5.0
greenlet==0.4.15
gunicorn==19.0.0
itsdangerous==0.24
msgpack==0.5.6
ujson==2.0.0
uWSGI==2.0.19.1
SharQ==1.2.0
quart==0.17.0
uvicorn==0.17.6
80 changes: 80 additions & 0 deletions scripts/install-nginx-debian.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#! /usr/bin/env bash

# From official Nginx Docker image, as a script to re-use it, removing internal comments
# Ref: https://github.com/nginxinc/docker-nginx/blob/f958fbacada447737319e979db45a1da49123142/mainline/debian/Dockerfile

# Standard set up Nginx
export NGINX_VERSION=1.21.6
export NJS_VERSION=0.7.3
export PKG_RELEASE=1~buster

set -x \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates \
&& \
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
found=''; \
for server in \
ha.pool.sks-keyservers.net \
hkp://keyserver.ubuntu.com:80 \
hkp://p80.pool.sks-keyservers.net:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \
&& dpkgArch="$(dpkg --print-architecture)" \
&& nginxPackages=" \
nginx=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} \
" \
&& case "$dpkgArch" in \
amd64|i386|arm64) \
echo "deb https://nginx.org/packages/mainline/debian/ buster nginx" >> /etc/apt/sources.list.d/nginx.list \
&& apt-get update \
;; \
*) \
echo "deb-src https://nginx.org/packages/mainline/debian/ buster nginx" >> /etc/apt/sources.list.d/nginx.list \
\
&& tempDir="$(mktemp -d)" \
&& chmod 777 "$tempDir" \
\
&& savedAptMark="$(apt-mark showmanual)" \
\
&& apt-get update \
&& apt-get build-dep -y $nginxPackages \
&& ( \
cd "$tempDir" \
&& DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \
apt-get source --compile $nginxPackages \
) \
\
&& apt-mark showmanual | xargs apt-mark auto > /dev/null \
&& { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \
\
&& ls -lAFh "$tempDir" \
&& ( cd "$tempDir" && dpkg-scanpackages . > Packages ) \
&& grep '^Package: ' "$tempDir/Packages" \
&& echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list \
&& apt-get -o Acquire::GzipIndexes=false update \
;; \
esac \
\
&& apt-get install --no-install-recommends --no-install-suggests -y \
$nginxPackages \
gettext-base \
curl \
&& apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list \
\
&& if [ -n "$tempDir" ]; then \
apt-get purge -y --auto-remove \
&& rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \
fi \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
# Standard set up Nginx finished
5 changes: 5 additions & 0 deletions scripts/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#! /usr/bin/env sh
set -e

# Start Supervisor, with Nginx and sharq-server
exec /usr/bin/supervisord -n -c /etc/supervisord.conf
Loading