Skip to content
Merged
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
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
**/venv
**/node_modules
**/__pycache__
*.env.local
**/.env.local
**/tests
docs/
.github/
.git/
*.md
80 changes: 80 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: docker

on:
push:
branches: ["**"]
tags: ["v*"]
pull_request:
workflow_call:

permissions:
contents: read
packages: write

jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=sha
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}

- name: Build (load locally, no push)
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64
load: true
push: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Smoke test
run: |
IMAGE=$(printf '%s\n' "${{ steps.meta.outputs.tags }}" | head -n1)
echo "Smoke-testing $IMAGE"
docker run -d --name smoke -p 8000:8000 \
-e AGORA_APP_ID=0123456789abcdef0123456789abcdef \
-e AGORA_APP_CERTIFICATE=fedcba9876543210fedcba9876543210 \
"$IMAGE"
set +e
fail=0
for url in http://localhost:8000/get_config; do
ok=""
for i in $(seq 1 40); do
if curl -fsS "$url" -o /dev/null; then ok=1; echo "OK $url"; break; fi
sleep 1
done
if [ -z "$ok" ]; then echo "FAIL $url"; fail=1; fi
done
if [ "$fail" -ne 0 ]; then docker logs smoke; fi
docker rm -f smoke
exit $fail

- name: Log in to GHCR
if: startsWith(github.ref, 'refs/tags/')
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Push tags
if: startsWith(github.ref, 'refs/tags/')
run: |
printf '%s\n' "${{ steps.meta.outputs.tags }}" | while read -r tag; do
[ -n "$tag" ] && docker push "$tag"
done
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

/.vscode
/.vscode
# Superpowers workflow docs (specs/plans) — local only, not tracked
docs/superpowers/
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# syntax=docker/dockerfile:1
FROM python:3.12-slim-bookworm AS runtime

# Run as a non-root user (created before any COPY so --chown can reference it).
RUN useradd --create-home --uid 10001 app
WORKDIR /app

# Python dependencies for the FastAPI backend (installed as root into the
# system site-packages, world-readable for the app user at runtime).
COPY server/requirements.txt /tmp/server-req.txt
RUN pip install --no-cache-dir -r /tmp/server-req.txt

# Backend source, owned by the runtime user.
COPY --chown=app:app server/src /app/server/src

# Drop privileges for the running process.
USER app

# server.py reads $PORT (default 8000) and binds 0.0.0.0.
EXPOSE 8000
CMD ["python", "/app/server/src/server.py"]
Loading