Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
1 change: 1 addition & 0 deletions .github/workflows/build-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ jobs:
with:
push: ${{ startsWith(github.ref, 'refs/tags/') }} # only push to ghcr.io on tags
tags: ghcr.io/${{github.repository}}:latest
file: docker/lnt.dockerfile
context: . # use the current directory as context, as checked out by actions/checkout -- needed for setuptools_scm
23 changes: 0 additions & 23 deletions Dockerfile

This file was deleted.

35 changes: 0 additions & 35 deletions docker-compose.yaml

This file was deleted.

65 changes: 65 additions & 0 deletions docker/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This file composes a full service running LNT. A LNT service is comprised
# of a container running a Postgres database and a container running a
# production LNT webserver.
#
# In order to build the full service, some secrets are required. They are taken
# as environment variables, which means they can be stored in a file and included
# via `--env-file <secrets-file>`. These environment variables are:
#
# LNT_DB_PASSWORD
# The password to use for logging into the database.
#
# LNT_AUTH_TOKEN
# The authentication token used to require authentication to
# perform destructive actions.

name: llvm-lnt

services:
webserver:
container_name: webserver
build:
context: ../
dockerfile: docker/lnt.dockerfile
environment:
- DB_USER=lntuser
- DB_HOST=dbserver
- DB_NAME=lnt.db
- DB_PASSWORD_FILE=/run/secrets/lnt-db-password
- AUTH_TOKEN_FILE=/run/secrets/lnt-auth-token
secrets:
- lnt-db-password
- lnt-auth-token
depends_on:
- db
deploy:
restart_policy:
condition: on-failure
ports:
- "8000:8000"
volumes:
- instance:/var/lib/lnt
- logs:/var/log/lnt

db:
container_name: dbserver
image: docker.io/postgres:18-alpine
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you land the postgres upgrade in a separate commit just in case the upgrade causes any issues and we want to revert?

environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/lnt-db-password
- POSTGRES_USER=lntuser
- POSTGRES_DB=lnt.db
secrets:
- lnt-db-password
volumes:
- database:/var/lib/postgresql

volumes:
instance:
logs:
database:

secrets:
lnt-db-password:
environment: "LNT_DB_PASSWORD"
lnt-auth-token:
environment: "LNT_AUTH_TOKEN"
22 changes: 12 additions & 10 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
#!/bin/sh

DB_PATH=${DB_ENGINE:-postgresql}://${DB_USER:-lntuser}:${DB_PWD:?}@${DB_HOST:?}
DB_BASE=${DB_BASE:-lnt}
set -u

if [ ! -r /etc/lnt/lnt.cfg ]; then
DB_BASE_PATH="${DB_PATH}/${DB_BASE}" wait_db
password="$(cat ${DB_PASSWORD_FILE})"
token="$(cat ${AUTH_TOKEN_FILE})"
DB_PATH="postgres://${DB_USER}:${password}@${DB_HOST}"

# Set up the instance the first time this gets run.
if [ ! -e /var/lib/lnt/instance/lnt.cfg ]; then
lnt-wait-db "${DB_PATH}/${DB_NAME}"
lnt create /var/lib/lnt/instance \
--config /etc/lnt/lnt.cfg \
--wsgi lnt_wsgi.py \
--tmp-dir /tmp/lnt \
--db-dir "${DB_PATH}" \
--default-db "${DB_BASE}"
if [ -n "${LNT_AUTH_TOKEN:-}" ]; then
sed -i "s/# \(api_auth_token =\).*/\1 '${LNT_AUTH_TOKEN}'/" /etc/lnt/lnt.cfg
fi
--default-db "${DB_NAME}"
sed -i "s/# \(api_auth_token =\).*/\1 '${token}'/" /var/lib/lnt/instance/lnt.cfg
fi

# Run the server under gunicorn.
cd /var/lib/lnt/instance
exec gunicorn lnt_wsgi:application \
--bind 0.0.0.0:8000 \
Expand All @@ -24,4 +26,4 @@ exec gunicorn lnt_wsgi:application \
--name lnt_server \
--log-file /var/log/lnt/lnt.log \
--access-logfile /var/log/lnt/gunicorn_access.log \
--max-requests 250000 "$@"
--max-requests 250000
10 changes: 6 additions & 4 deletions docker/wait_db → docker/lnt-wait-db
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!/usr/bin/env python

import os
from sqlalchemy import create_engine
import sys
import sqlalchemy

db_base_path = os.environ['DB_BASE_PATH']
if len(sys.argv) != 2:
raise "Missing db path for lnt-wait-db"

engine = create_engine(db_base_path)
db = sys.argv[1]
engine = sqlalchemy.create_engine(db)
started = False

while not started:
Expand Down
41 changes: 41 additions & 0 deletions docker/lnt.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This Dockerfile defines an image that contains a production LNT server.
# This image is intended to be built from a Docker Compose file, as it
# requires additional information passed as environment variables:
#
# DB_USER
# The username to use for logging into the database.
#
# DB_HOST
# The hostname to use to access the database.
#
# DB_NAME
# The name of the database on the server.
#
# DB_PASSWORD_FILE
# File containing the password to use for logging into the database.
#
# AUTH_TOKEN_FILE
# File containing the authentication token used to require authentication
# to perform destructive actions.

FROM python:3.10-alpine

# Install dependencies
RUN apk update \
&& apk add --no-cache --virtual .build-deps git g++ postgresql-dev yaml-dev \
&& apk add --no-cache libpq

# Install LNT itself, without leaving behind any sources inside the image.
RUN --mount=type=bind,source=.,target=./lnt-source \
cp -R lnt-source /tmp/lnt-src && \
cd /tmp/lnt-src && \
pip3 install -r requirements.server.txt && apk --purge del .build-deps && \
rm -rf /tmp/lnt-src

# Prepare volumes that will be used by the server
VOLUME /var/lib/lnt /var/log/lnt

# Set up the actual entrypoint that gets run when the container starts.
COPY docker/docker-entrypoint.sh docker/lnt-wait-db /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 8000
11 changes: 11 additions & 0 deletions docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ To install the extra packages for the server config::
gunicorn app_wrapper:app --bind 0.0.0.0:8000 --workers 8 --timeout 300 --name lnt_server --log-file /var/log/lnt/lnt.log --access-logfile /var/log/lnt/gunicorn_access.log --max-requests 250000


Running a LNT Server via Docker
-------------------------------

We provide a Docker Compose setup with Docker containers that can be used to
easily bring up a fully working production server within minutes. The container
can be built and run with::

docker compose --file docker/compose.yaml --env-file <secrets> up

``<secrets>`` should be the path to a file containing environment variables
required by the containers. Please refer to the Docker Compose file for details.