Skip to content
Snippets Groups Projects
Commit 6e33440b authored by Jussi Mäki-Ikola's avatar Jussi Mäki-Ikola
Browse files

added documentation

parent 31a99518
Branches
Tags
No related merge requests found
# Initial readme # Graph-editor-app
#### A dockerized fullstack web-development project using Vue, Express and Postgres.
## Run in development mode The production version of this app is running on a free-tier Amazon ec2-instance in
``` http://3.125.137.206:3000/ . I will take the app down at some point in the near future.
docker-compose up --build
``` ## Services
In development mode the `ui` and `api` listen to file-changes. (hot-reload) This project includes multiple services:
- [ui](./ui/index.md) is the user-interface.
- [api](./api/index.md) is the express-server that handles requests from the ui.
- [database](./database/index.md) contains a postgres-database used in development and testing. The production database is in AWS.
- [migrate](./migrate/index.md) is a migration and testing tool for the database.
- [e2e](./e2e/index.md) contains end-to-end tests written with `cypress`.
## Dependencies
This project requires an installation of `docker` and `docker-compose`.
- docker: https://docs.docker.com/get-docker/
- docker-compose: https://docs.docker.com/compose/install/
Understanding this project requires a bit of prior experience with docker. It would probably make sense to create some bash-scripts for easier usage.
## CI/CD
The project uses a gitlab-pipeline that:
1. builds the docker-images and saves them to a container-registry on gitlab.
2. Runs the test script.
3. If on `master`, it deploys the changes to the ec2-instance.
Note that the master-branch is protected from other users.
## Running the app
Run these commands from the root-directory of this project.
The app uses different docker-compose*.yml files depending on the environment:
- `docker-compose.yml`: This base-file is the one used in production. Has only the services `api`, `ui` and `migrate`, since the postgres-database is not running with docker in production, and the end-to-end tests aren't run against the production-app.
- `docker-compose.override.yml`: The development-environment file that is merged automatically with the base-file. Has the postgres-service and the other services use docker-volumes for quicker development. When using volumes, we don't need to build the image every time the code is changed. Also the `ui` and `api` listen to file-changes and restart.
- `docker-compose.test.yml`: Like the development environment, but it doesn't use volumes, since volumes break the gitlab-ci. It also runs the `e2e`-service with headless-chrome.
- `docker-compose.preview.yml`: Mimicks the production environment, but still uses the local postgres-service. The `ui` and `api` are bundled and minified to the production versions.
Different environments can be achieved by using different combinations of the compose-files. (https://docs.docker.com/compose/extends/#multiple-compose-files)
### Development environment
```bash
# build the stack
docker-compose build
The --build flag is required only on the first startup, or when installing new npm packages. # run the stack
docker-compose up
## Run in production mode # Restart
docker-compose down
docker-compose up
``` ```
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up --build
### Production-preview environment
```bash
# build the stack
docker-compose -f docker-compose.yml -f docker-compose.preview.yml build
# run the stack
docker-compose -f docker-compose.yml -f docker-compose.preview.yml up
``` ```
In production mode, the `ui` and `api` are bundled and minified. ### Test environment
```bash
# build the stack
docker-compose -f docker-compose.yml -f docker-compose.test.yml build
## Restart # run the stack
docker-compose -f docker-compose.yml -f docker-compose.test.yml up
``` ```
docker-compose down
The test environment is a bit tricky, since the cypress tests need everything else to be running before they can work. A workaround for this is to first start all but the `e2e`-service. Once they are running you can run the tests:
```bash
# STEP-1: run all but the e2e.
# Possible to use dev- or preview-environments here also.
# dev environment
docker-compose up docker-compose up
# OR preview
docker-compose -f docker-compose.yml -f docker-compose.preview.yml up
# STEP-2: run e2e when everything else is ready
docker-compose -f docker-compose.yml -f docker-compose.test.yml run --rm e2e
``` ```
This is a bit verbose. An easy way to run the tests is to use the `test.sh` script. It runs the unit tests and the integration tests for the whole stack. The script is used in the gitlab-pipeline and is also useful for development:
```bash
# Run all tests.
./test.sh
# You may need to give permissions for running this script. If so:
chmod +x test.sh
```
NOTE: After running the test script you may need to rebuild the stack, since it builds the services to a different target.
# Api
An `express` server written with typescript.
The server listens to only one graphql route:
- The requests are handled by the `postgraphile` middleware. (https://www.graphile.org)
- The allowed graphql-queries are whitelisted. Anything that is not from the whitelist will fail.
- Also added `cors` and `rate-limiting` middleware.
Look at the code for more documentation.
A local installation of npm packages is not required, but useful since the `intellisense` features won't work properly without it.
## Run with docker
The docker-image uses multistage builds in order to create a smaller image for production. Look in [README.md](../README.md) for info on how to run different build targets and environments.
```bash
# build
docker-compose build api
# run
docker-compose up api
# tests
docker-compose run --rm api npm run test
```
## Local installation
```bash
npm install
```
## Database
- A postgres-database using docker. This is used for development and testing.
- The real database lives in AWS-rds, but behaves exactly like the database configured here.
- We use the postgres extension `pgtap` for testing the created database-schemas. (https://pgtap.org/)
### Migrations
- The database tests and migrations are handled by the `migrate` service.
### Running the database
`docker-compose up postgres --build`
\ No newline at end of file
## End-to-end tests
We use cypress for creating end-to-end tests.
For now the docker-image supports only running the tests via headless-chrome
The e2e-tests require the whole stack to be running in order to work.
A local installation of npm packages is not required, but useful since the `intellisense` features won't work properly without it.
### Run with docker-compose
```bash
# Build
docker-compose build e2e
# Run
docker-compose run --rm e2e
```
### Run with local npm installation
```
npm install
npm run cypress:open
```
\ No newline at end of file
## Migrate
- A database migration and testing tool using `docker`. (needs a better name)
- This service is strongly linked to the database and requires the database to be running in order to work.
- Is used in production.
### Schema-design
- This project uses `postgraphile`, which is a `graphql` framework created for postgres. The schema is built using the guidelines defined here: https://www.graphile.org/postgraphile/postgresql-schema-design/
- The schema uses some non-standard sql-featues:
1. `Row-level-security` and `row-security-policies`. They enable a schema design that allows every user only to access their own data. Also it revokes every permission by default, and every operation must be explicitly granted. (https://www.postgresql.org/docs/9.5/ddl-rowsecurity.html)
2. `JSONB`-type columns. JSONB is a column type that is used to store JSON-data. It has some basic validation and can be indexed. (https://www.postgresql.org/docs/9.4/datatype-json.html)
### Migrations
- This service uses a migration tool called `golang-migrate` for running the up- and down-migrations. (https://github.com/golang-migrate/migrate)
- Every database migration should have an `up.sql` file that contains the changes, and then a `down.sql` file that reverts the changes. When running a new migration, we can then revert to the previous version if the changes had some issues.
- The down-migrations should rarely be used. Instead, when something goes wrong, we should write a new migration that fixes the broken things in the previous version.
- The migrations should be written using environment variables for the secrets. The variables get substituted to the real values when the migrations are run.
### Tests
- The database has a postgres extension `pgtap` installed. We use that for running some basic tests on the database. (https://pgtap.org/)
- The tests contain schema-validation and sanity-testing.
### Commands
Normally the compose files handle the correct environment and entrypoint. If you need to run the migrations separately you can use the commands below.
The dockerfile has three different entrypoints depending on the environment:
- `run.sh` is the default and is used in production. It just runs the commands and fails if it doesn't have access to the database.
- `dev.sh` is used in development and waits for the database to start before running the migrations. (TODO: needs a timeout.)
- `test.sh` runs the migration up and down and then runs the test-files.
Before you run these make sure that the database is running.
Running migrations up:
```
docker-compose run --rm migrate up
```
Running migrations down:
```
docker-compose run --rm migrate down -all
```
Running the tests:
```
docker-compose run --rm --entrypoint ./test.sh migrate
```
# ui
> My bee's knees Nuxt.js project
## Build Setup
```bash
# install dependencies
$ npm install
# serve with hot reload at localhost:3000
$ npm run dev
# build for production and launch server
$ npm run build
$ npm run start
# generate static project
$ npm run generate
```
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
# Ui
A `Nuxt.js` (Vue.js framework) project. The app is written with typescript and uses some additional modules:
- `Vuetify` is a component-library for Vue. https://vuetifyjs.com/en/
- `nuxt-typed-vuex` is a typescript friendly add-on for Vuex. https://nuxt-typed-vuex.danielcroe.com/
- `nuxt-property-decorator` is a typescript add-on for writing vue-components in a class style. https://www.npmjs.com/package/nuxt-property-decorator
- `cookie-universal-nuxt` is a cookie helper. https://www.npmjs.com/package/cookie-universal-nuxt
A local installation of npm packages is not required, but useful since the `intellisense` features won't work properly without it.
## Run with docker
The docker-image uses multistage builds in order to create a smaller image for production. Look in [README.md](../README.md) for info on how to run different build targets and environments.
```bash
# build
docker-compose build ui
# run
docker-compose up ui
```
## Local Setup
```bash
# install dependencies
$ npm install
# serve with hot reload at localhost:3000
$ npm run dev
# build for production and launch server
$ npm run build
$ npm run start
```
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment