diff --git a/.env b/.env new file mode 100644 index 0000000..1d5f734 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +DB_NAME=tailfin +MONGO_USERNAME=tailfin +MONGO_PASSWORD=tailfin-api-password diff --git a/README.md b/README.md new file mode 100644 index 0000000..44b4642 --- /dev/null +++ b/README.md @@ -0,0 +1,199 @@ +

+ + Tailfin Logo +

+ +

Tailfin

+ +

A self-hosted digital flight logbook

+ +![Screenshots](img/mockup.png) + +

+ Python + MongoDB + FastAPI + TypeScript + React + Remix-Run + TanStack Query +

+

+ +

+ +## Table of Contents + +- [About](#about) +- [Getting Started](#getting_started) + - [Docker](#docker) + - [From Source](#from_source) +- [Configuration](#configuration) +- [Usage](#usage) +- [Roadmap](#roadmap) + +## About + +Tailfin is a digital flight logbook designed to be hosted on a personal server, computer, or cloud solution. + +I created this because I was disappointed with the options available for digital logbooks. The one provided by +ForeFlight is likely most commonly used, but my proclivity towards self-hosting drove me to seek out another solution. +Since I could not find any ready-made self-hosted logbooks, I decided to make my own. + +## Getting Started + +### Docker + +|:exclamation: Note :exclamation: | +|---------------------------------| +| Docker builds are considered unstable at this point and cannot be guaranteed to work without customization. Proceed at your own risk | + +1. Clone the repo + +``` +$ git clone https://git.github.com/azpsen/tailfin.git +$ cd tailfin +``` + +2. Configure `docker-compose.yml` and `.env` + +3. Build/pull the images and start the service + +``` +$ docker compose build +$ docker compose pull +$ docker compose up -d +``` + +4. Log in to the web UI at `localhost:3000` + +### From Source + +#### Prerequisites + +- nodejs +- npm +- python 3.11 +- mongodb 7.0.4 + +#### Installation + +##### 1. Clone the repo + +``` +$ git clone https://git.github.com/azpsen/tailfin.git +$ cd tailfin +``` + +##### 2. Set up database + +[Install MongoDB](https://www.mongodb.com/docs/manual/installation/) + +[Enable Authentication](https://www.geeksforgeeks.org/how-to-enable-authentication-on-mongodb/) + +Add the `tailfin` user: + +``` +$ mongosh -u "yourAdminUsername" -p +> use tailfin +> db.createUser( + { + user: "tailfin-api", + pwd: "tailfin-api-password", // or passwordPrompt() for secure entry + db: "tailfin", + roles: [ { role: "readWrite", db: "tailfin" } ] + } +) +``` + +##### 3. Set up backend + +``` +$ cd api +``` + +(Optional) Create and activate python virtual environment: + +``` +$ python -m venv tailfin-env +$ source +``` + +Install python requirements: + +``` +$ pip install -r requirements.txt +``` + +[Configure the backend](#backend_configuration) + +##### 4. Set up frontend + +Install NPM requirements: + +``` +cd ../web +$ npm install +``` + +Build and run the web app: + +``` +$ npm run build && npm run start +``` + +5. Access the web UI at `localhost:3000` + +## Configuration + +The URL for the Tailfin API can be set with the environment variable `TAILFIN_API_URL`. It defaults to `http://localhost:8081`, which assumes the API runs on the same machine and uses the default port. + +### Backend + + +To configure Tailfin, modify the `.env` file. Some of these options should be changed before running the server. All +available options are detailed below: + +`DB_URI`: Address of MongoDB instance. Default: `localhost` +
+`DB_PORT`: Port of MongoDB instance. Default: `27017` +
+`DB_NAME`: Name of the database to be used by Tailfin. Default: `tailfin` + +`DB_USER`: Username for MongoDB authentication. Default: `tailfin-api` +
+`DB_PWD`: Password for MongoDB authentication. Default: `tailfin-api-password` + +`REFRESH_TOKEN_EXPIRE_MINUTES`: Duration in minutes to keep refresh token active before invalidating it. Default: +`10080` (7 days) +
+`ACCESS_TOKEN_EXPIRE_MINUTES`: Duration in minutes to keep access token active before invalidating it. Default: `30` + +`JWT_ALGORITHM`: Encryption algorithm to use for access and refresh tokens. Default: `HS256` +
+`JWT_SECRET_KEY`: Secret key used to encrypt and decrypt access tokens. Default: `please-change-me` +
+`JWT_REFRESH_SECRET_KEY`: Secret key used to encrypt and decrypt refresh tokens. Default: `change-me-i-beg-of-you` + +`TAILFIN_ADMIN_USERNAME`: Username of the default admin user that is created on startup if no admin users exist. +Default: `admin` +
+`TAILFIN_ADMIN_PASSWORD`: Password of the default admin user that is created on startup if no admin users exist. +Default: `change-me-now` + +`TAILFIN_PORT`: Port to run the local Tailfin API server on. Default: `8081` + +Once the backend is running, full API documentation is available at `localhost:8081/docs` + +## Roadmap + +- [x] Create, view, edit, and delete flight logs +- [x] Aircraft managment and association with flight logs +- [x] Dashboard with statistics +- [x] Attach photos to log entries +- [ ] Import from other log applications (partially working for MyFlightBook) +- [ ] Admin dashboard to manage all users and server configuration +- [ ] GPS track recording and map display +- [ ] Calendar view +- [ ] PDF Export +- [ ] Integrate database of airports and waypoints that can be queried to find nearest diff --git a/api/dockerfile b/api/dockerfile new file mode 100644 index 0000000..1662025 --- /dev/null +++ b/api/dockerfile @@ -0,0 +1,18 @@ +# Use an official Python runtime as a parent image +FROM python:3.9 + +# Set the working directory in the container to /app +WORKDIR /app + +# Copy the current directory contents into the container at /app +COPY . /app + +# Install any needed packages specified in requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +# Make port 8081 available to the world outside this container +EXPOSE 8081 + +# Run app.py when the container launches +CMD ["python", "app.py"] + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..006bf38 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,36 @@ +version: '3' +services: + web: + build: ./web + container_name: tailfin-web + ports: + - 3000:3000 + depends_on: + - api + api: + build: ./api + container_name: tailfin-api + environment: + - TAILFIN_DB_URI=db + - TAILFIN_DB_PORT=27017 + - TAILFIN_DB_NAME=${DB_NAME} + - TAILFIN_DB_USER=${MONGO_USERNAME} + - TAILFIN_DB_PWD=${MONGO_PASSWORD} + - JWT_SECRET_KEY="please-change-me" + - JWT_REFRESH_SECRET_KEY="change-me-i-beg-of-you" + - TAILFIN_ADMIN_USERNAME="admin" + - TAILFIN_ADMIN_PASSWORD="change-me-now" + - TAILFIN_PORT=8081 + depends_on: + - db + ports: + - 8081:8081 + db: + image: mongo + container_name: tailfin-db + environment: + - MONGO_INITDB_ROOT_USERNAME=${MONGO_USERNAME} + - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD} + - MOGNO_INITDB_DATABASE=${DB_NAME} + ports: + - 27017:27017 diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000..18e04e3 Binary files /dev/null and b/img/logo.png differ diff --git a/img/mockup.png b/img/mockup.png new file mode 100644 index 0000000..b564a21 Binary files /dev/null and b/img/mockup.png differ diff --git a/web/dockerfile b/web/dockerfile new file mode 100644 index 0000000..720a4e4 --- /dev/null +++ b/web/dockerfile @@ -0,0 +1,22 @@ +# Use an official Node runtime as a parent image +FROM node:21-alpine + +# Set the working directory in the container to /app +WORKDIR /app + +# Copy package.json and package-lock.json before other files +# Utilise Docker cache to save re-installing dependencies if unchanged +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy all files +COPY . . + +# Build the app +RUN npm run build + +# Serve the app on port 3000 +EXPOSE 3000 +CMD ["npm", "start"]