160 lines
8.3 KiB
Markdown
160 lines
8.3 KiB
Markdown
# About
|
|
|
|
This is a template for building a webapp using the following tech stack:
|
|
|
|
- **Frontend**:
|
|
- [Vue.js](https://vuejs.org/guide/introduction.html) - frontend JS framework
|
|
- [Vue Router](https://router.vuejs.org/guide/) - frontend router for Vue
|
|
- [TailwindCSS](https://tailwindcss.com/docs/configuration) - CSS framework
|
|
- [Axios](https://axios-http.com/docs/intro) - library for making API requests from the frontend
|
|
- [Parcel](https://parceljs.org/docs/) - bundler used for frontend module resolution and asset optimization
|
|
- [npm](https://docs.npmjs.com/cli/v7/configuring-npm/package-json) - node package manager for JavaScript packages
|
|
- **Backend**:
|
|
- [FastAPI](https://fastapi.tiangolo.com/) - Python-framework for backend APIs
|
|
- [Uvicorn](https://www.uvicorn.org/) - Python-ASGI-server used to serve the FastAPI backend
|
|
- **Other**:
|
|
- [Caddy](https://caddyserver.com/docs/) - webserver and reverse proxy used for serving static files and HTTP routing
|
|
- [Dockerfile](https://docs.docker.com/engine/reference/builder/) - recipes for building Docker images
|
|
- [Docker Compose](https://docs.docker.com/compose/compose-file/) - used to deploy interconnected Docker containers for development and/or production
|
|
|
|
Two different configurations are provided and instanced using the docker-related files in this template repository:
|
|
|
|
- The [production configuration](#production-configuration) is used for preformance-optimized production deployments of your web application
|
|
- The [development configuration](#development-configuration) is used during development of your web application, providing features such as hot-reloading and debugging information
|
|
|
|
This should go without saying, but **do not serve the development configuration** on a public production server.
|
|
|
|
## Production Configuration
|
|
|
|
The production-ready configuration can be deployed using the `production.docker-compose.yml` file, by running (as root):
|
|
|
|
```sh
|
|
docker-compose -f production.docker-compose.yml up -d --force-recreate --build --remove-orphans
|
|
```
|
|
|
|
This starts two containers, called `backend` and `frontend`, and exposes the deployed web application on port `8000`.
|
|
You can open a browser and navigate to [http:localhost:8000/](http:localhost:8000/) to try it out.
|
|
|
|
To stop the containers, run the following as root:
|
|
```sh
|
|
docker-compose -f production.docker-compose.yml down
|
|
```
|
|
|
|
### Production Frontend Container
|
|
|
|
The `frontend` production Docker image is built according to `production.frontend.Dockerfile`.
|
|
It is based on Debian and initially installs Caddy, as well as npm, and creates a non-root-user to run Caddy as.
|
|
|
|
Next up, the image copies over and bundles the frontend code and assets using Parcel.
|
|
|
|
Finally, it starts an instance of Caddy, which is a web server used to route HTTP traffic and serve static files.
|
|
|
|
The files bundled by Parcel are then served as static files by Caddy, with `/frontend/src/html/index.html` as the site root (served at
|
|
[http:localhost:8000/](http:localhost:8000/).
|
|
|
|
Caddy is configured to forward any requests with the `/api/`-prefix to the [backend-container](#production-backend-container).
|
|
|
|
Because Parcel renames files when bundling them, Caddy is also configured to serve unbundled static files in this template.
|
|
All files and folders under the `/public/static/` directory are copied into the image and served under the `/static/`-prefix by Caddy,
|
|
without being bundled (and renamed) by Parcel.
|
|
For example: the file `/public/static/images/tux.svg` can be accessed at [http://localhost:8000/static/images/tux.svg](http://localhost:8000/static/images/tux.svg)
|
|
in your browser.
|
|
|
|
The `/robots.txt` and `/sitemap.xml` files are served by Caddy, and are sourced from the `/robots/`-directory, where you should [customize](#customization)
|
|
them as necessary.
|
|
You can view the results at [http://localhost:8000/robots.txt](http://localhost:8000/robots.txt) and
|
|
[http://localhost:8000/sitemap.xml](http://localhost:8000/sitemap.xml) respectively.
|
|
|
|
### Production Backend Container
|
|
|
|
The `backend`-container serves FastAPI-endpoints using [uvicorn](https://www.uvicorn.org/).
|
|
All HTTP requests requesting paths under `/api/` are routed here by Caddy (which runs within the [frontend-container](#production-frontend-container)).
|
|
|
|
Uvicorn's root path is configured such that the backend code does not need to include the `/api/`-prefix of the route.
|
|
As an example, take a look at the `hello()`-endpoint declared in `/backend/main.py`: in the code, it is declared at `/hello/`,
|
|
but in the browser, you access the endpoint at [http://localhost:8000/api/hello/](http://localhost:8000/api/hello/).
|
|
|
|
This prevents repetition when writing your endpoint code and allows you to access the interactive Swagger API documentation at
|
|
[http://localhost:8000/api/docs](http://localhost:8000/api/docs), which is auto-generated by FastAPI.
|
|
|
|
## Development Configuration
|
|
|
|
The development configuration can be deployed using the `development.docker-compose.yml` file, by running (as root):
|
|
|
|
```sh
|
|
docker-compose -f development.docker-compose.yml up -d --build --force-recreate --remove-orphans
|
|
```
|
|
|
|
This starts three containers, called `backend`, `parcel` and `frontend`, and exposes the deployed web application on port `8000`.
|
|
You can open a browser and navigate to [http:localhost:8000/](http:localhost:8000/) to try it out.
|
|
|
|
To stop the containers, run the following as root:
|
|
```sh
|
|
docker-compose -f development.docker-compose.yml down
|
|
```
|
|
|
|
The development containers work very similarly to the production containers, with the exception that hot reloading of configuration
|
|
and sourcecode files is enabled.
|
|
|
|
This means that when you modify the frontend or backend sourcecode while the development container is running, the changes are detected
|
|
and applied automatically, restarting the containers is usually not required.
|
|
|
|
# Customization
|
|
|
|
A number of default configuration files and placeholder assets for the frontend are already present in the repository.
|
|
|
|
You should, at **minimum**, adjust the following things according to your requirements (otherwise things will not work as expected):
|
|
|
|
- [ ] `package.json`
|
|
- [ ] [robots.txt and sitemap.xml](#robots-and-sitemap)
|
|
- [ ] the `<meta>`-tags in `/frontend/src/html/index.html`
|
|
- [ ] [OG Image](#og-image) and [favicon](#favicon)
|
|
|
|
## Assets
|
|
|
|
The template in this repo provides and references some placeholder-assets which you should replace with your own.
|
|
|
|
### Favicon
|
|
|
|
The standards for accepted favicon formats are all over the place and, depending on browser- and OS-vendors, expect a different format.
|
|
|
|
A quick and easy way to create a set of favicons with broad compatibility is to create your favicon as an `.svg`/`.png`-file,
|
|
and then use [realfavicongenerator.net](https://realfavicongenerator.net/) to create a set of relevant files and HTML references
|
|
for your favicon.
|
|
|
|
Place the generated icons into `/frontend/assets/images/common/favicon/` and be sure to adjust the generated HTML to point to
|
|
the files placed under this path. Parcel will resolve the paths accordingly.
|
|
|
|
For reference, I created `/frontend/assets/images/common/favicon/favicon.svg`, and uploaded it to the favicongenerator.
|
|
I placed the resulting files into `/frontend/assets/images/common/favicon/` and updated `/frontend/src/html/index.html` accordingly.
|
|
|
|
### OG Image
|
|
|
|
The OG image should ideally be a `.webp`-file, and its dimensions should be at least 1200 x 630 pixels, as according to the
|
|
[OGP standard](https://developers.facebook.com/docs/sharing/webmasters/images/).
|
|
|
|
A placeholder OG image can be found at `/frontend/assets/images/common/og-image.webp`.
|
|
|
|
### Robots and Sitemap
|
|
|
|
The `/robots/robots.txt` and `/robots/sitemap.xml` files are added to the [frontend docker container](#production-frontend-container)
|
|
and served at the site root upon deployment.
|
|
|
|
Both files are crucial for search engine visibility and SEO, so you should adjust them as necessary (depending on whether you want your site to be indexed).
|
|
|
|
### Fonts
|
|
|
|
Static font files are stored under `/frontend/assets/fonts/` and declared for use in CSS within `/frontend/src/css/fonts.css`.
|
|
The added font families can be accessed using TailwindCSS after configuring them inside `tailwind.config.js`.
|
|
|
|
You can add or remove fonts here as necessary.
|
|
|
|
## Configuration Files
|
|
|
|
Depending on the configuration you wish to customize, please refer to each component's [relevant documentation](#about).
|
|
|
|
# TODOs / Roadmap
|
|
|
|
1. Add sqlite/postgres containers
|
|
2. Minify CSS in prod
|
|
3. Add testing tools
|