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

Add docker support #2

Open
wants to merge 2 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
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.git/
*.pyc
.pydevproject
.settings
.project
log/django.osqa.log
tmp/*
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
58 changes: 58 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: ci

on:
push:
branches:
- "**"
tags:
- "v*.*.*"
pull_request:
branches:
- "master"

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/openstreetmap/osqa
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
type=sha

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
61 changes: 61 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# hadolint global ignore=DL3008
FROM debian:buster
Firefishy marked this conversation as resolved.
Show resolved Hide resolved

# Set Docker User and Group IDs for matching with host
ARG UID=510
ARG GID=510

# Install OSQA dependencies and cleanup apt cache
RUN apt-get update && apt-get install -y --no-install-recommends \
python \
python-pip \
python-dev \
python-setuptools \
ca-certificates \
gcc \
libpq-dev \
curl \
gunicorn \
gettext \
&& rm -rf /var/lib/apt/lists/*

# Ensure terminate if pipefail
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Create OSQA user and group
RUN groupadd --system --gid ${GID} osqa && useradd --system --gid osqa --uid ${UID} osqa

# Create OSQA working directory
WORKDIR /srv/app
# Set OSQA user as owner of working directory to allow .pyc files can be created
RUN chown osqa:osqa /srv/app

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

# Copy OSQA source code into container
COPY --chown=osqa . .
Firefishy marked this conversation as resolved.
Show resolved Hide resolved

# Set Container Default Environment Variables. Override as appropriate at runtime.
ENV OSQA_DB_ENGINE=django.db.backends.postgresql_psycopg2
ENV OSQA_DB_NAME=osqa
ENV OSQA_DB_USER=osqa
ENV OSQA_DB_PASSWORD=osqa
Firefishy marked this conversation as resolved.
Show resolved Hide resolved
ENV OSQA_DB_HOST=postgres
ENV OSQA_ALLOWED_HOSTS=localhost
ENV OSQA_CACHE_BACKEND=memcached://memcached:11211/
ENV OSQA_APP_URL=http://localhost:8080/
ENV OSQA_TIME_ZONE=UTC

# Set container entrypoint script for runtime container setup
ENTRYPOINT ["./docker/entrypoint.sh"]

# Switch to underprivileged OSQA user
USER osqa

# Expose port 8080 for OSQA
EXPOSE 8080

# Run OSQA
CMD ["python", "manage.py", "runserver", "0.0.0.0:8080"]
35 changes: 35 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: "2.1"

services:

osqa:
build:
context: .
environment:
OSQA_DB_USER: osqa
OSQA_DB_PASSWORD: osqa
OSQA_DB_NAME: osqa
OSQA_DB_HOST: postgres

ports:
- 8080:8080
depends_on:
postgres:
condition: service_healthy
memcached:
condition: service_started
Firefishy marked this conversation as resolved.
Show resolved Hide resolved

postgres:
image: postgres:14
environment:
POSTGRES_USER: osqa
POSTGRES_PASSWORD: osqa
Firefishy marked this conversation as resolved.
Show resolved Hide resolved
POSTGRES_DB: osqa
healthcheck:
test: ["CMD-SHELL", "pg_isready -U osqa"]
interval: 10s
timeout: 5s
retries: 5

memcached:
image: memcached:1
10 changes: 10 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
set -ex

# Build the settings_local.py file from the template using environment variables
envsubst < docker/settings_local.py.template > settings_local.py

python manage.py syncdb --all --noinput
python manage.py migrate --fake --noinput

exec "$@"
79 changes: 79 additions & 0 deletions docker/settings_local.py.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# encoding:utf-8
import os.path

SITE_SRC_ROOT = os.path.dirname(__file__)
LOGGING = {
'version': 1,
'formatters': {
'default': {
'format': '[OSQA] TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'default',
},
},
'loggers' : {
# ensure that all log entries are propagated to root
'django': { 'propagate': True },
'django.request': { 'propagate': True },
'django.security': { 'propagate': True },
'py.warnings': { 'propagate': True },
},
'root': {
'handlers': ['console'],
'level': 'DEBUG',
},
}

#ADMINS and MANAGERS
ADMINS = ()
MANAGERS = ADMINS

DEBUG = False
DEBUG_TOOLBAR_CONFIG = {
'INTERCEPT_REDIRECTS': True
}
TEMPLATE_DEBUG = DEBUG
INTERNAL_IPS = ('127.0.0.1',)
ALLOWED_HOSTS = ('${OSQA_ALLOWED_HOSTS}',)

DATABASES = {
'default': {
'ENGINE': '${OSQA_DB_ENGINE}',
'NAME': '${OSQA_DB_NAME}',
'USER': '${OSQA_DB_USER}',
'PASSWORD': '${OSQA_DB_PASSWORD}',
'HOST': '${OSQA_DB_HOST}',
'PORT': '',
'CONN_MAX_AGE': 600,
}
}

CACHE_BACKEND = '${OSQA_CACHE_BACKEND}'
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
# Customize the values below if OSQA is in a subfolder and especially you're planning on
# running multiple Django applications (OSQA or others) on the same domain in different
# subfolders
#SESSION_COOKIE_PATH = '/'
#CSRF_COOKIE_PATH = '/'

# This should be equal to your domain name, plus the web application context.
# This shouldn't be followed by a trailing slash.
# I.e., http://www.yoursite.com or http://www.hostedsite.com/yourhostapp
APP_URL = '${OSQA_APP_URL}'

#LOCALIZATIONS
TIME_ZONE = '${OSQA_TIME_ZONE}'

#OTHER SETTINGS

USE_I18N = True
LANGUAGE_CODE = 'en'

OSQA_DEFAULT_SKIN = 'default'

DISABLED_MODULES = ['books', 'recaptcha', 'project_badges', 'stats', 'localauth', 'facebookauth', 'oauthauth', 'mysqlfulltext']
13 changes: 7 additions & 6 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
markdown
html5lib
python-openid
South
python-memcached
django==1.6.0
markdown==2.4.1
html5lib<0.99999999
python-openid==2.2.5
South==0.7.6
python-memcached==1.53
django==1.6.11
django-debug-toolbar
django-endless-pagination
pytz
psycopg2==2.7.7