diff --git a/README.md b/README.md index a90d957..9a10a0e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Ilmotunkki + Web application for signups. This project uses Strapi as the CMS and Next.js as the frontend and backend service. The Next.js requires a token from strapi in order to use its API. This means before the website can you used you need to create a token from Strapi. Note that you need `docker` on the target machine. +**Outdated** ## Development @@ -11,93 +13,34 @@ Note that you need `docker` on the target machine. Note that strapi is quite heavy inside docker, so it might be beneficial to just run the database inside docker and run next and strapi outside docker. Remember to update environment variables in this case. -Go set correct domain names inside `nginx/nginx.prod.conf` - Go run `npm install` in `web` and `cms` folders. Copy `.env.sample` to `.env` and fill in: + - Email settings - CMS secrets For generating CMS secrets you can use `npm run generate` inside `cms`-folder. (If you don't have npm installed on target system, you can run `docker run hajoppi/ilmotunkki-generate-strapi-keys` to generate the secrets.) Copy these secrets to the env file. -Start the project: -``` -docker compose up -d -``` - -Import the base settings and content: -``` -docker compose exec cms npx strapi import -f base_content.tar.gz -``` - -Go to [http://localhost:7800/cms/admin](http://localhost:7800/cms/admin), create an account and login. Go to Settings > API Tokens > Add new API Token. Name it something descriptive and set the token type to `full-access`. -Copy the new token and set it to `STRAPI_TOKEN` in `.env` file. - -Then restart the web service -``` -docker compose up web --force-recreate -d -``` - -Now the site should be up and running. - - -## Production - -These instructions should create a working production build. You need to point a domain to the location you are setting up the application. - - -Go run `npm install` in `web` and `cms` folders. - -Copy `.env.sample` to `.env` and fill in: -- Colors -- Paytrail -- CMS -- CMS secrets -- Email settings -- Database settings -- Cerbot settings - +Start the database: -For generating CMS secrets you can use `npm run generate` inside `cms`-folder. (If you don't have npm installed on target system or don't want to install it, you can run `docker run hajoppi/ilmotunkki-generate-strapi-keys` to generate the secrets.) Copy these secrets to the env file. - -Setup the ssl certs -``` -docker compose -f docker-compose.prod.yml --profile setup up --build +```sh +docker compose up -d ``` -After ssl certs have been setup up run: -``` -docker compose -f docker-compose.prod.yml --profile default up --build -d -``` +Import the base settings and content in cms folder: -Import the base settings and content: -``` -docker compose -f docker-compose.prod.yml --profile default exec cms npx strapi import -f base_content.tar.gz +```sh +npx strapi import -f base_content.tar.gz ``` -Go to [https://you-domain/cms/admin](https://you-domain/cms/admin), create an account and login. Go to Settings > API Tokens > Add new API Token. Name it something descriptive and set the token type to `full-access`. - +Go to [http://localhost:1337/admin](http://localhost:1337/admin), create an account and login. Go to Settings > API Tokens > Add new API Token. Name it something descriptive and set the token type to `full-access`. Copy the new token and set it to `STRAPI_TOKEN` in `.env` file. +Now the site should be up and running. -Then restart the web service -``` -docker compose up -f docker-compose.prod.yml --profile default web --force-recreate -d -``` - -In order to update the application after pulling new files use -``` -docker compose -f docker-compose.prod.yml --profile default up --build --force-recreate -d -``` - -To speed things up you can upgrade only the changed service. For example to update `web` use this: -``` -docker compose -f docker-compose.prod.yml --profile default up web --no-deps --build --force-recreate -d -``` - +## CMS -# CMS Short instructions how the cms works. Only fields with non-obvious meanings are listed. @@ -106,6 +49,7 @@ Only fields with non-obvious meanings are listed. ### ContactForm Define what fields you want to collect from the customer. Each language has their own form. + - ContactForm: Array of fields - Label: What is shown to user - Required: Is the field required @@ -114,6 +58,7 @@ Define what fields you want to collect from the customer. Each language has thei - itemTypes: For what items does this form apply to ### Customer + What fields can be currently collected for a customer. You should collect at least the email. In the future most of the fields should be stored into a freeform json object - Uid: With this uid the customer can edit their details for the signup @@ -128,6 +73,7 @@ Each locale has their own template, and the customer receives the email in their - from: Who is the sender. Make sure that the account you use has access to the alias set here. ### Giftcard + A giftcard removes the whole value from the item it is linked to. They are single time use. - code: Gitftcard code that gives the discount @@ -135,6 +81,7 @@ A giftcard removes the whole value from the item it is linked to. They are singl - itemType: Which item type the giftcard applies to ### Group + Not in use. Should remove in the future ### Item @@ -146,6 +93,7 @@ One item in an order. If a customer buys multiple, they each have one correspond - giftCard: Which giftcard is the item linked to if any ### ItemCategory + Categories define the inventories and limits per item type. I agree that the name is a bit misleading. - Name: Name of the category. For example "Main event" or "Sillis" @@ -155,6 +103,7 @@ Categories define the inventories and limits per item type. I agree that the nam - overFlowItem: What itemType is used if the user tries to add an item that has no inventory left. This could be for example a reserve spot if someone cancels their purchase. ### ItemType + The attributes of a purchassable item - Price: The price in Euros @@ -165,7 +114,8 @@ The attributes of a purchassable item - upgradeTarget: If there is an additional **itemType** that can be purchased when buying this item. For example after adding the main event ticket, allow them to purchase sillis. ### Order -When a user adds an item to cart, it is already added to an order. This means the cart and a succesful order are the same differentiated only by their `status` field. + +When a user adds an item to cart, it is already added to an order. This means the cart and a succesful order are the same differentiated only by their `status` field. - status: The state of the order. Not completed orders are expired after some time. - new: All new created orders. Expires after **30 minutes** @@ -182,6 +132,7 @@ When a user adds an item to cart, it is already added to an order. This means th Just strapi internals. No functionality ## Single types + Configurations and page content ### Callback page @@ -195,7 +146,7 @@ The front page content. Remember to fill in the required locales. - bodyText: Main text shown in the page in **markdown** - Header: Hero image shown throughout the site - headerTitle -- showSignups: Enables a button to show signups to all users. +- showSignups: Enables a button to show signups to all users. ### Global @@ -212,13 +163,13 @@ Global settings for the site. - favicon ### Paytrail + NOT IN USE. Should maybe remove or integrate to payment pipeline ### Terms and Conditions Terms and conditions of the page. **You must set these so that they correspond to your association.** Remember to set all locales - ### Translation -All the other translations in the page. **Remember to include the translations for your itemType slugs.** Many of these can be left as is. \ No newline at end of file +All the other translations in the page. **Remember to include the translations for your itemType slugs.** Many of these can be left as is. diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml deleted file mode 100644 index d977df2..0000000 --- a/docker-compose.prod.yml +++ /dev/null @@ -1,86 +0,0 @@ -version: "3" - -services: - db: - image: postgres:14.4 - environment: - POSTGRES_DB: strapi - POSTGRES_PASSWORD: ${DATABASE_PASSWORD} - POSTGRES_USER: ${DATABASE_USERNAME} - volumes: - - ./postgres-data:/var/lib/postgresql/data - profiles: - - default - web: - build: - context: ./web - dockerfile: Dockerfile - args: - PRIMARY_COLOR: ${PRIMARY_COLOR} - SECONDARY_COLOR: ${SECONDARY_COLOR} - environment: - STRAPI_API_URL: http://cms:1337 - STRAPI_PUBLIC_URL: ${STRAPI_URL} - STRAPI_TOKEN: ${STRAPI_TOKEN} - PAYTRAIL_MERCHANT_ID: ${PAYTRAIL_MERCHANT_ID} - PAYTRAIL_SECRET_KEY: ${PAYTRAIL_SECRET_KEY} - URL: ${URL} - profiles: - - default - cms: - build: - context: ./cms - dockerfile: Dockerfile - args: - URL: ${STRAPI_URL} - environment: - HOST: 0.0.0.0 - PORT: 1337 - NODE_ENV: production - DATABASE_CLIENT: postgres - DATABASE_NAME: strapi - DATABASE_HOST: db - DATABASE_PORT: 5432 - URL: ${STRAPI_URL} - DATABASE_USERNAME: ${DATABASE_USERNAME} - DATABASE_PASSWORD: ${DATABASE_PASSWORD} - APP_KEYS: ${APP_KEYS} - API_TOKEN_SALT: ${API_TOKEN_SALT} - ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET} - TRANSER_TOKEN_SALT: ${TRANSFER_TOKEN_SALT} - JWT_SECRET: ${JWT_SECRET} - SMTP_USER: ${SMTP_USER} - SMTP_PASSWORD: ${SMTP_PASSWORD} - depends_on: - - db - profiles: - - default - nginx: - image: nginx:latest - volumes: - - ./nginx/nginx.prod.conf:/etc/nginx/nginx.conf:ro - - ./certbot/conf:/etc/letsencrypt:ro - - ./certbot/www:/var/www/certbot - depends_on: - - web - - cms - ports: - - 80:80 - - 443:443 - profiles: - - default - certbot: - image: certbot/certbot - ports: - - 80:80 - volumes: - - ./certbot/conf:/etc/letsencrypt - - ./certbot/www:/var/www/certbot - profiles: - - setup - command: > - certonly - --standalone - -d ${FQDN} - --email ${CERTBOT_EMAIL} - --agree-tos diff --git a/docker-compose.yml b/docker-compose.yml index 22d52a7..fcfa98d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,8 @@ version: "3" +volumes: + strapi_postgres: + services: db: image: postgres:14.4 @@ -7,60 +10,7 @@ services: POSTGRES_DB: strapi POSTGRES_PASSWORD: ${DATABASE_PASSWORD} POSTGRES_USER: ${DATABASE_USERNAME} - web: - build: - context: ./web - dockerfile: Dockerfile.dev - args: - PRIMARY_COLOR: ${PRIMARY_COLOR} - SECONDARY_COLOR: ${SECONDARY_COLOR} - volumes: - - /app/node_modules - - ./web/:/app - environment: - STRAPI_API_URL: http://cms:1337 - STRAPI_PUBLIC_URL: ${STRAPI_URL} - STRAPI_TOKEN: ${STRAPI_TOKEN} - PAYTRAIL_MERCHANT_ID: ${PAYTRAIL_MERCHANT_ID} - PAYTRAIL_SECRET_KEY: ${PAYTRAIL_SECRET_KEY} - URL: ${URL} - cms: - build: - context: ./cms - dockerfile: Dockerfile.dev - args: - URL: ${STRAPI_URL} - volumes: - - /app/node_modules - - ./cms/:/app - environment: - HOST: 0.0.0.0 - PORT: 1337 - NODE_ENV: development - DATABASE_CLIENT: postgres - DATABASE_NAME: strapi - DATABASE_HOST: db - DATABASE_PORT: 5432 - URL: ${STRAPI_URL} - DATABASE_USERNAME: ${DATABASE_USERNAME} - DATABASE_PASSWORD: ${DATABASE_PASSWORD} - APP_KEYS: ${APP_KEYS} - API_TOKEN_SALT: ${API_TOKEN_SALT} - ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET} - TRANSER_TOKEN_SALT: ${TRANSFER_TOKEN_SALT} - JWT_SECRET: ${JWT_SECRET} - SMTP_USER: ${SMTP_USER} - SMTP_PASSWORD: ${SMTP_PASSWORD} - ports: - - 1337:1337 - depends_on: - - db - nginx: - image: nginx:latest volumes: - - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - depends_on: - - web - - cms + - strapi_postgres:/var/lib/postgresql/data ports: - - 7800:7800 + - "5432:5432" diff --git a/nginx/nginx.conf b/nginx/nginx.conf deleted file mode 100644 index 33f050c..0000000 --- a/nginx/nginx.conf +++ /dev/null @@ -1,59 +0,0 @@ -worker_processes auto; - -events { - worker_connections 1024; - use epoll; - multi_accept on; -} - - -http { - - upstream web { - server web:3000; - keepalive 32; - } - - upstream cms { - server cms:1337; - } - - server { - listen 7800; - - location / { - proxy_pass http://web/; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - } - - location /api/ { - proxy_pass http://web/api/; - - proxy_cache off; - add_header Cache-Control 'no-store'; - - proxy_http_version 1.1; - proxy_set_header "Connection" ""; - } - - # Disallow all calls to /cms/api. The API is only accessed internally - location /cms/api/ { - return 403; - } - - location /cms/ { - proxy_pass http://cms/; - - proxy_cache off; - add_header Cache-Control 'no-store'; - - proxy_http_version 1.1; - proxy_set_header "Connection" ""; - } - } -} \ No newline at end of file diff --git a/nginx/nginx.prod.conf b/nginx/nginx.prod.conf deleted file mode 100644 index 83a6f80..0000000 --- a/nginx/nginx.prod.conf +++ /dev/null @@ -1,79 +0,0 @@ -worker_processes auto; - -events { - worker_connections 1024; - use epoll; - multi_accept on; -} - - -http { - - upstream web { - server web:3000; - keepalive 32; - } - - upstream cms { - server cms:1337; - } - - server { - listen 80; - server_name liput.domain.fi; - - location /.well-known/acme-challenge/ { - root /var/www/certbot; - } - - location / { - return 301 https://$host$request_uri; - } - } - - server { - listen 443 ssl; - http2 on; - server_name liput.domain.fi; - - ssl_certificate /etc/letsencrypt/live/liput.domain.fi/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/liput.domain.fi/privkey.pem; - - gzip on; - gzip_types text/css application/javascript application/json image/svg+xml; - gzip_min_length 1000; - - location / { - proxy_pass http://web/; - - proxy_http_version 1.1; - proxy_set_header "Connection" ""; - } - - location /api/ { - proxy_pass http://web/api/; - - proxy_cache off; - add_header Cache-Control 'no-store'; - - proxy_http_version 1.1; - proxy_set_header "Connection" ""; - } - - # Disallow all calls to /cms/api. The API is only accessed internally - # Remember to change this if the location for the api changes. - location /cms/api/ { - return 403; - } - - location /cms/ { - proxy_pass http://cms/; - - proxy_cache off; - add_header Cache-Control 'no-store'; - - proxy_http_version 1.1; - proxy_set_header "Connection" ""; - } - } -} \ No newline at end of file