{"id":19081848,"url":"https://github.com/tacone/loki","last_synced_at":"2025-04-30T07:45:35.404Z","repository":{"id":77313294,"uuid":"352201462","full_name":"tacone/loki","owner":"tacone","description":"A docker / react / svelte / graphql / postgraphile starter app","archived":false,"fork":false,"pushed_at":"2023-01-21T20:46:58.000Z","size":3913,"stargazers_count":11,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-18T23:59:32.585Z","etag":null,"topics":["brotli","frontend","graphql-backend","postgraphile"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tacone.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-27T23:37:56.000Z","updated_at":"2024-08-07T03:13:10.000Z","dependencies_parsed_at":"2023-07-09T05:32:06.339Z","dependency_job_id":null,"html_url":"https://github.com/tacone/loki","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacone%2Floki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacone%2Floki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacone%2Floki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacone%2Floki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tacone","download_url":"https://codeload.github.com/tacone/loki/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251665142,"owners_count":21624233,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brotli","frontend","graphql-backend","postgraphile"],"created_at":"2024-11-09T02:39:31.645Z","updated_at":"2025-04-30T07:45:35.397Z","avatar_url":"https://github.com/tacone.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Loki\n\nA simple Docker / Frontend / Backend starter app, with a meaningless name.\n\n- 👍 No-config first run\n- 👍 Development mode with hot reloading everywhere\n- 👍 Production mode with optional static file compilation\n- 👍 Two alternative frontends: Svelte and NextJS\n- 👍 GraphQL backend with Postgraphile + Migrations\n- 👍 Unpriviledged user + readonly filesystem\n- 👍 Small images + fast build\n\n## Installation\n\nClone the project, then run:\n\n```shell\nscripts/dev up\n```\n\nWhen everything is up (it will take some time for the first run) these ports\nwill be exposed on your localhost:\n\n- frontend: [7000](http://localhost:7000)\n- svelte frontend: [7002](http://localhost:7002)\n- backend: [7011](http://localhost:7011)\n- postgres: 7040\n\nTo connect with postgres use:\n\n- user: `postgres`\n- password: `postgrespassword`\n- host: `localhost`\n- port: `7040`\n\nThe `scripts/dev` script wraps `docker-compose` so you can use it in the same\nway (i.e. `scripts/dev build`, `scripts/dev down`, `scripts/dev ps`).\n\nThere is an additional command, `scripts/dev ports` that shows the configured ports.\n\nThe database files will be written in `data/`, so you can start from scratch by deleting `data/` along with `frontend/node_modules` and `backend/node_modules`.\n\n## Production environment\n\nTo run the production environment, write:\n\n```shell\nscripts/production --build up\n```\n\nYou should then access the frontend using [https://localhost:7443](https://localhost:7443).\n\n\u003e **Heads up!**\n\u003e\n\u003e You should always build when switching from dev to production mode.\n\u003e\n\u003e Also, since the application building process runs while building\n\u003e the docker container, you need to build the containers to have the\n\u003e latest changes applied.\n\u003e\n\u003e Summing up, **when you start the production environment, build**.\n\nThe production environment features:\n\n- a container with Nginx webserver, exposing _HTTP_ (7080) and _HTTPS_ (7443) ports. HTTP/2 enabled. Capable of _gzip_ and _brotli_ compression.\n- the postgres DB does not expose a public port while using the production envinroment.\n- the GraphQL backend, will not expose the development console.\n- the frontend is exported to a static website. All the files are pre-compressed with _brotli_ during build. All timestamped files have far future expiration headers to allow proxy caching.\n\nPlease note that, at this time, frontend and backend still keep publishing their own ports (7000, 7011).\n\n## Stack\n\nThe stack consists of a few docker containers.\n\n**Frontend:**\n\n- Nginx\n- Node\n- NextJS / Svelte Kit\n- React / Svelte\n- Alpine Linux\n\n**Backend:**\n\n- Node\n- Postgraphile\n\n**Database:**\n\n- Postgres\n- Alpine Linux\n\n### Frontend\n\nThe frontend is build in React + NextJS in order to make it easy to generate a\nstatic website. The forms use Final Forms. All the communication with the\nbackend is done using GraphQL.\n\n### Svelte\n\nAn alternative frontend with Svelte + SvelteKit. Page payload ridiculously small. The forms use Felte. All the communication with the backend in done using GraphQL.\n\n### Backend\n\nWe use [Postgraphile][postgraphile] for the backend. Take a look at the [documentation](./backend/readme.md).\n\nPostgraphile automatically generates the GraphQL schema for us by looking at the db schema.\n\nThe port 7011 exposes a [GraphQL Console](http://localhost:7011/graphiql).\n\nDatabase migrations: in development mode, they are automatically run only the first time. In production mode, migrations are always run at start up.\n\n[postgraphile]: https://github.com/graphile/postgraphile\n\n### Database\n\nThe good old postgres.\n\n### Security\n\nWhile security is not the focus of this starter app, by default we mount the root filesystem as readonly and run the containers with an unprivileged user.\n\n## Filesystem Layout\n\n| Folder      |                                                                    |\n| ----------- | ------------------------------------------------------------------ |\n| `config/`   | use this directory to store your configs                           |\n| `data/`     | the db data, and npm cache is saved here                           |\n| `docker/`   | the docker-compose files for the various containers                |\n| `frontend/` | the frontend application code                                      |\n| `svelte/`   | alternative frontend based on Svelte Kit                           |\n| `backend/`  | the backend application code                                       |\n| `scripts/`  | the starting scripts (`dev`) and everything needed to make it work |\n\n## Roadmap\n\nNot a real roadmap, just a list of missing features I'd like to add.\n\n### Backend\n\n- use PM2 or any other tool to make use of all the CPU's.\n- proper auth with custom `aud`\n- find out how to handle uploads\n\n### Frontend/Svelte\n\n- image and static assets handling\n- use urql to fetch from graphql\n- persisted queries and typescript types\n\n### Nginx\n\n- read-only fs\n- templating / docker-gen / env vars in the confs\n\n## Caveats\n\n1. While Postgraphile is incredibly cool, it may not be your piece of cake.\n   Take a look to the `typeorm` branch to see how implement something more\n   traditional (then do yourself a favor and use Prism instead).\n\n1. While the GraphQL server validates pretty much everything, the email\n   validation is currently performed on the client, while it would be better\n   to also validate the mail on the server as well.\n\n1. If you specify a custom `USER_ID` in development mode, you may have issues with next (see [#1](https://github.com/tacone/loki/issues/1))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftacone%2Floki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftacone%2Floki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftacone%2Floki/lists"}