Dockerfile support
							parent
							
								
									999d0e0bfb
								
							
						
					
					
						commit
						8547434c31
					
				@ -0,0 +1,15 @@
 | 
			
		||||
./tests
 | 
			
		||||
./scripts
 | 
			
		||||
.ruff_cache
 | 
			
		||||
.coveragerc
 | 
			
		||||
.dockerignore
 | 
			
		||||
.git
 | 
			
		||||
.gitignore
 | 
			
		||||
.pre-commit-config.yaml
 | 
			
		||||
dev-requirements.in
 | 
			
		||||
dev-requirements.txt
 | 
			
		||||
pyproject.toml
 | 
			
		||||
.profile
 | 
			
		||||
Dockerfile
 | 
			
		||||
requirements.in
 | 
			
		||||
tasks.py
 | 
			
		||||
@ -0,0 +1,55 @@
 | 
			
		||||
# syntax = docker/dockerfile:1.4
 | 
			
		||||
 | 
			
		||||
# Best practice: Choose a stable base image and tag.
 | 
			
		||||
FROM python:3.11-slim-bookworm
 | 
			
		||||
 | 
			
		||||
# Install security updates, and some useful packages.
 | 
			
		||||
#
 | 
			
		||||
# Best practices:
 | 
			
		||||
# * Make sure apt-get doesn't run in interactive mode.
 | 
			
		||||
# * Update system packages.
 | 
			
		||||
# * Pre-install some useful tools.
 | 
			
		||||
# * Minimize system package installation.
 | 
			
		||||
RUN export DEBIAN_FRONTEND=noninteractive && \
 | 
			
		||||
  apt-get update && \
 | 
			
		||||
  apt-get -y upgrade && \
 | 
			
		||||
  apt-get install -y --no-install-recommends tini procps net-tools && \
 | 
			
		||||
  apt-get -y clean && \
 | 
			
		||||
  rm -rf /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
# Install dependencies.
 | 
			
		||||
#
 | 
			
		||||
# Best practices:
 | 
			
		||||
# * `COPY` in files only when needed.
 | 
			
		||||
# * Reduce disk usage from `pip` installs.
 | 
			
		||||
COPY requirements.txt .
 | 
			
		||||
RUN pip install --no-cache-dir -r requirements.txt
 | 
			
		||||
 | 
			
		||||
# Create a new user to run as.
 | 
			
		||||
#
 | 
			
		||||
# Best practices: Don't run as root.
 | 
			
		||||
RUN useradd --create-home appuser
 | 
			
		||||
USER appuser
 | 
			
		||||
WORKDIR /home/appuser
 | 
			
		||||
 | 
			
		||||
# Copy in the code.
 | 
			
		||||
#
 | 
			
		||||
# Best practices: Avoid extra chowns.
 | 
			
		||||
COPY --chown=appuser . .
 | 
			
		||||
 | 
			
		||||
# Best practices: Prepare for C crashes.
 | 
			
		||||
ENV PYTHONFAULTHANDLER=1
 | 
			
		||||
ENV PYTHONUNBUFFERED=0
 | 
			
		||||
 | 
			
		||||
ARG COMMIT_SHA
 | 
			
		||||
 | 
			
		||||
LABEL io.runcible.repo-sha="${COMMIT_SHA}"
 | 
			
		||||
 | 
			
		||||
# Run the code when the image is run:
 | 
			
		||||
#
 | 
			
		||||
# Best practices:
 | 
			
		||||
# * Add an `init` process.
 | 
			
		||||
# * Make sure images shut down correctly (via ENTRYPOINT [] syntax).
 | 
			
		||||
# * '-g' option means killing the container kills all processes, not just the
 | 
			
		||||
#   entrypoint shell.
 | 
			
		||||
ENTRYPOINT ["tini", "-g", "--", "./entrypoint.sh"]
 | 
			
		||||
@ -0,0 +1,8 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Best practice: Bash strict mode.
 | 
			
		||||
set -euo pipefail
 | 
			
		||||
 | 
			
		||||
# Best practice: Make sure the image shuts down correctly by using `exec` in
 | 
			
		||||
# entry point shell scripts.
 | 
			
		||||
exec "$@"
 | 
			
		||||
@ -0,0 +1,15 @@
 | 
			
		||||
from litestar import Litestar
 | 
			
		||||
from litestar import get
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@get("/")
 | 
			
		||||
async def index() -> str:
 | 
			
		||||
    return "Hello, world!"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@get("/books/{book_id:int}")
 | 
			
		||||
async def get_book(book_id: int) -> dict[str, int]:
 | 
			
		||||
    return {"book_id": book_id}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
app = Litestar([index, get_book])
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
class Example:
 | 
			
		||||
    """An example class"""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
@ -0,0 +1,24 @@
 | 
			
		||||
from invoke import task
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@task
 | 
			
		||||
def serve(c):
 | 
			
		||||
    """Serves the speech-collect application locally."""
 | 
			
		||||
    c.run("LITESTAR_APP=speech_collect.app:app litestar run --port 8888 --host 0.0.0.0 --reload")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@task
 | 
			
		||||
def build_image(c, dev=True):
 | 
			
		||||
    """Builds the speech-collect container image."""
 | 
			
		||||
    context_dir = c.run("pwd", hide=True).stdout.strip()
 | 
			
		||||
    commit_sha = c.run("git rev-parse --short HEAD", hide=True).stdout.strip()
 | 
			
		||||
    c.run(
 | 
			
		||||
        f"docker build --build-arg='COMMIT_SHA={commit_sha}' -t speech-collect:{commit_sha}{'-dev' if dev else ''} {context_dir}"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@task
 | 
			
		||||
def delint(c):
 | 
			
		||||
    """Applies automated linters to project"""
 | 
			
		||||
    c.run("isort ./speech_collect ./tests", pty=True)
 | 
			
		||||
    c.run("black ./speech_collect ./tests", pty=True)
 | 
			
		||||
@ -1,6 +0,0 @@
 | 
			
		||||
from speech_collect.example import Example
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_example():
 | 
			
		||||
    my_example = Example(name="dirp")
 | 
			
		||||
    assert my_example.name == "dirp"
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue