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
16 changes: 16 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env/
venv/
.env
.git
.gitignore
.pytest_cache
.coverage
htmlcov/
dist/
build/
*.egg-info/
122 changes: 122 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Deploy to Server

on:
push:
tags:
- 'v*'

permissions:
contents: read
packages: write

env:
REGISTRY: ghcr.io
REPOSITORY_NAME: NetVault
IMAGE_NAME: topnik073/netvault

jobs:
prepare:
name: Extract version from tag
runs-on: ubuntu-latest
outputs:
version: ${{ steps.extract-version.outputs.version }}
image_tag: ${{ steps.extract-version.outputs.image_tag }}
steps:
- name: Extract version from tag
id: extract-version
run: |
TAG_NAME=${GITHUB_REF#refs/tags/}
VERSION=${TAG_NAME#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "image_tag=$TAG_NAME" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"
echo "Image tag: $TAG_NAME"

build:
name: Build & Push Docker image
runs-on: ubuntu-latest
needs: prepare
environment: prod

steps:
- name: Checkout repository
uses: actions/checkout@v4

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

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
build-args: |
APP_VERSION=${{ needs.prepare.outputs.version }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }}
cache-from: type=gha
cache-to: type=gha,mode=max

deploy:
name: Deploy to Server
runs-on: ubuntu-latest
needs: [prepare, build]
environment: prod

steps:
- name: Checkout only docker-compose file
uses: actions/checkout@v4
with:
sparse-checkout: |
docker-compose.prod.yml
sparse-checkout-cone-mode: false

- name: Upload .env to server
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script_stop: true
script: |
echo "${{ vars.ENV_FILE }}" | grep -v "DRONE_SSH" > /root/${{ env.REPOSITORY_NAME }}/.env
echo ".env uploaded to server"

- name: Copy docker-compose file to server
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
source: "docker-compose.prod.yml"
target: "/root/${{ env.REPOSITORY_NAME }}/"

- name: Deploy on remote server
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
echo "Starting deployment with version: ${{ needs.prepare.outputs.version }}"
echo "Image tag: ${{ needs.prepare.outputs.image_tag }}"

docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.SERVER_GHCR_TOKEN }}

cd /root/${{ env.REPOSITORY_NAME }}

echo "Pulling application image..."
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }}

IMAGE_TAG=${{ needs.prepare.outputs.image_tag }} docker compose -f docker-compose.prod.yml pull
IMAGE_TAG=${{ needs.prepare.outputs.image_tag }} docker compose -f docker-compose.prod.yml up -d --remove-orphans

echo "Deployment complete"
26 changes: 26 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Lint with Ruff

on:
push:
branches:
- '**'

jobs:
ruff-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Install Ruff and Just
run: |
pip install ruff
curl -LSfs https://just.systems/install.sh | bash -s -- --to /usr/local/bin

- name: Run lint via Just
run: just lint
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM python:3.13-slim AS base

ENV PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PIP_DEFAULT_TIMEOUT=100 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=1 \
PYTHONPATH=/app_dir/src
RUN apt-get update && \
apt-get install --yes --no-install-recommends netcat-openbsd && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app_dir

FROM base AS builder

RUN pip install --upgrade "uv>=0.6,<1.0" && rm -rf /root/.cache/*
ADD pyproject.toml uv.lock ./
RUN uv sync --locked --no-install-project --verbose --no-progress

FROM base AS final

ARG APP_VERSION=unknown
ENV APP_VERSION=${APP_VERSION}

RUN pip install --upgrade "uv>=0.6,<1.0"
COPY --from=builder /app_dir/.venv ./.venv
COPY src/ ./src
COPY alembic.ini ./
COPY migrations/ ./migrations/

# Run migrations and start the application
CMD while ! nc -z db 5432; do sleep 0.1; done && \
./.venv/bin/alembic upgrade head && \
./.venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000
16 changes: 8 additions & 8 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ sync:
# Automatically format code
[group('linters')]
ruff-format:
uv run ruff check --fix --unsafe-fixes {{ SOURCE_DIR }}
uv run ruff format .
python -m ruff check --fix --unsafe-fixes {{ SOURCE_DIR }}
python -m ruff format .

# Lint code using Ruff
[group('linters')]
ruff-check:
uv run ruff check {{ SOURCE_DIR }}
python -m ruff check {{ SOURCE_DIR }}

run-server:
uv run python -m src.main server

run-cli:
uv run python -m src.main interactive
# --- Building ---
# Build local
[group('building')]
build-local:
docker compose -f docker-compose.local.yml up -d --build
Loading
Loading