From 41c8f2587de188a11a9441bdfd45c37547bd344a Mon Sep 17 00:00:00 2001 From: Gareth Latty Date: Sat, 25 Apr 2020 12:18:07 +0100 Subject: [PATCH] Add deployment examples. --- README.md | 35 +++++++--- deployment/README.md | 9 +++ deployment/memory/docker_compose.yml | 35 ++++++++++ deployment/postgres/config.json5 | 90 ++++++++++++++++++++++++++ deployment/postgres/docker_compose.yml | 62 ++++++++++++++++++ docker-compose.yml | 4 ++ 6 files changed, 225 insertions(+), 10 deletions(-) create mode 100644 deployment/README.md create mode 100644 deployment/memory/docker_compose.yml create mode 100644 deployment/postgres/config.json5 create mode 100644 deployment/postgres/docker_compose.yml diff --git a/README.md b/README.md index 7e917b9..5d3e81c 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,41 @@ # [Massive Decks ![Massive Decks](https://raw.githubusercontent.com/Lattyware/massivedecks/master/client/assets/images/icon.png)][hosted] [![Build Status](https://img.shields.io/github/workflow/status/Lattyware/massivedecks/Build%20and%20publish%20docker%20images.)](https://github.com/Lattyware/massivedecks/actions) -![License](https://img.shields.io/github/license/Lattyware/massivedecks) +[![License](https://img.shields.io/github/license/Lattyware/massivedecks)](LICENSE) -Massive Decks is a comedy party game based on [Cards against Humanity][cah]. Play with friends! It works great with a -bunch of people in the same room on phones, or on voice chat online. +Massive Decks is a free, open source comedy party game based on [Cards against Humanity][cah]. Play with friends! **[Play Massive Decks][hosted]** [hosted]: https://md.rereadgames.com/ [cah]: https://cardsagainsthumanity.com/ +## Features + + - Play together in the same room or online. + - Use any device (Mobile phone, PC, Chromecast, anything with a web browser). + - You can set up a central screen, but you don't need to (no need to stream anything for other players online). + - Custom decks. + - Customise the rules: + - Custom cards. + - House rules. + - AI players. + - Custom time limits if you want them. + - Spectators. + - Keeps your game private by default, you can also set a game password if needed. + ## About -The game is open source software available under [the AGPLv3 license][license]. +The game is open source software available under [the AGPLv3 license](LICENSE). The web client for the game is written in [Elm][elm], while the back-end is written in [Typescript][typescript]. [elm]: https://elm-lang.org/ [typescript]: https://www.typescriptlang.org/ -[license]: https://github.com/Lattyware/massivedecks/blob/master/LICENSE ## Deploying -If you would like to run an instance of Massive Decks, there are a couple of options. +If you would like to run a production instance of Massive Decks, there are a couple of options. It is suggested you read the [deployment guide on the wiki][deployment-guide]. @@ -31,16 +43,19 @@ It is suggested you read the [deployment guide on the wiki][deployment-guide]. ### Docker -[Server](https://hub.docker.com/r/massivedecks/server) / [Client](https://hub.docker.com/r/massivedecks/client) +The Docker images can be found on Docker Hub: [Server](https://hub.docker.com/r/massivedecks/server) / [Client](https://hub.docker.com/r/massivedecks/client). -Also see [`docker-compose.yml`](https://github.com/Lattyware/massivedecks/blob/master/docker-compose.yml). The client image -is an nginx server that both serves the static web client and acts as a proxy for the server. As such, the server should -not be exposed publicly directly. +There are example docker deployments in [the deployment folder](deployment). ### Heroku +You can deploy to Heroku with the button below: + [![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/Lattyware/massivedecks) +If you want to customise the deployment further, you can deploy through heroku from your own fork of the project with +modification (note the button above is hard-coded to this repository). + ## Contributing If you have any problems with the game, please [raise an issue][issue]. If you would like to help develop the game, diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 0000000..de9bc9a --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,9 @@ +# Production Deployment with Docker + +Each directory in this one is an example of how one might create a production deployment of Massive Decks using Docker. + + - [memory](memory) contains a deployment that creates a server that simply stores all the game data and caches in memory. + - [postgres](postgres) contains a deployment that creates a server that uses a postgres database for storage and caching. + +These use [Docker Compose](https://docs.docker.com/compose/), a tool that comes with Docker for running multi-container +applications. diff --git a/deployment/memory/docker_compose.yml b/deployment/memory/docker_compose.yml new file mode 100644 index 0000000..1686abf --- /dev/null +++ b/deployment/memory/docker_compose.yml @@ -0,0 +1,35 @@ +# This docker compose file is for building and running a production version of Massive Decks. +# This uses the built images from the docker hub. + +version: "3" + +networks: + internal: + +services: + server: + container_name: server + # If you want to keep your deployment stable, it would be sensible to specify a specific tag rather than just `latest` here. + # Make sure you always deploy the same tag for client and server. + image: "massivedecks/server:latest" + environment: + - NODE_ENV=production + # This needs to be changed to a secret value. + # You can run `npm run generate-secret` in the server project to generate an appropriate value. + - MD_SECRET=CHANGE ME + networks: + - internal + restart: unless-stopped + + client: + container_name: client + depends_on: + - server + # If you want to keep your deployment stable, it would be sensible to specify a specific tag rather than just `latest` here. + # Make sure you always deploy the same tag for client and server. + image: "massivedecks/client:latest" + ports: + - "80:8080" + networks: + - internal + restart: unless-stopped diff --git a/deployment/postgres/config.json5 b/deployment/postgres/config.json5 new file mode 100644 index 0000000..d600b73 --- /dev/null +++ b/deployment/postgres/config.json5 @@ -0,0 +1,90 @@ +{ + // In a production environment, be sure to change this value to a random secret for security. + // You can use `npm run generate-secret` to generate a suitable value. + // Note that changes to this value will kick all users from all games. + secret: "CHANGE ME", + // This will be overwritten by the environment variable MD_SECRET, if set. + + // The port to serve on. Note this should always be behind a reverse proxy. + listenOn: 8081, + // It is also possible to listen on a unix socket. + // listenOn: "/tmp/sock", + // This will be overwritten by the environment variable MD_LISTEN_ON, if set. + + // The path this is hosted behind - only relevant when behind a reverse proxy, this won't actually host on a different + // path. This should always have a trailing slash if it isn't empty, and never one at the start. + basePath: "", + // This will be overwritten by the environment variable MD_BASE_PATH, if set. + + // Timeouts determine how long the server waits before taking certain actions. + // These values are all ISO 8601 durations. + timeouts: { + // How long to wait in between checking timeouts. + // Note that this will effectively determine the resolution of all other timeouts, so should be kept low. + // Increasing the value will decrease server load, however. + // Zero-durations elsewhere will result in instant execution, regardless of frequency here. + timeoutCheckFrequency: "PT1S", + + // How long to wait before marking a player as disconnected. + disconnectionGracePeriod: "PT2S", + + // How long to wait after everyone has played to begin the revealing phase. Having this as a non-zero value lets + // the last person playing + finishedPlayingDelay: "PT2S" + }, + + // Tasks are things that take some time to happen (e.g: requesting data from external card services). + // These are queued, and the settings here will determine server load and game responsiveness when under load. + tasks: { + // The number of tasks that can be processed at once. Limiting this stops the server getting overloaded, but setting + // too low a value will result in games being slowed down. + rateLimit: 20, + // How often to process queued tasks. Setting this too high will result in games being slowed down a lot when the + // rate limit is hit (an ISO 8601 duration). + processTickFrequency: "PT0.5S" + }, + + // How to store game data. + storage: { + // Example of a configuration using a postgres database. + type: "PostgreSQL", + connection: { + host: "storage", + port: 5432 , + user: "massivedecks", + database: "massivedecks", + password: "CHANGE ME", + keepAlive: false, + }, + + // How long to allow without any activity before garbage collecting the game. + abandonedTime: "PT15M", + // How often to delete abandoned/finished games (an ISO 8601 duration). + garbageCollectionFrequency: "PT5M" + }, + + // How to cache game data. + cache: { + // Example of a configuration using a postgres database. + type: "PostgreSQL", + connection: { + host: "storage", + port: 5432 , + user: "massivedecks", + database: "massivedecks", + password: "CHANGE ME", + keepAlive: false, + }, + + // How old a cached value should be before we check to see if we should update it on a hit. + checkAfter: "PT5M" + }, + + // A file to touch when the server is started. If null, we won't touch any files. + touchOnStart: null, + // This will be overwritten by the environment variable MD_TOUCH_ON_START, if set. + + // The version of Massive Decks. + version: "dev" + // This will be overwritten by the environment variable MD_VERSION, if set. +} diff --git a/deployment/postgres/docker_compose.yml b/deployment/postgres/docker_compose.yml new file mode 100644 index 0000000..5077324 --- /dev/null +++ b/deployment/postgres/docker_compose.yml @@ -0,0 +1,62 @@ +# This docker compose file is for building and running a production version of Massive Decks. +# This uses the built images from the docker hub. +# This version also configures a postgres server for data storage. + +version: "3" + +networks: + internal: + +# You may not want docker to manage your data like this. +# Please see Docker's documentation for more on managing volumes: https://docs.docker.com/compose/compose-file/#volume-configuration-reference +volumes: + storage-volume: + +services: + storage: + container_name: storage + image: "postgres:12" + # See the postgres image's documentation for more on configuring it. + # https://hub.docker.com/_/postgres + environment: + - POSTGRES_USER=massivedecks + # This should be changed to a secret value, matched to the config. + - POSTGRES_PASSWORD=CHANGE ME + networks: + - internal + volumes: + - storage-volume:/var/lib/postgresql/data + restart: unless-stopped + + server: + container_name: server + # If you want to keep your deployment stable, it would be sensible to specify a specific tag rather than just `latest` here. + # Make sure you always deploy the same tag for client and server. + image: "massivedecks/server:latest" + depends_on: + - storage + environment: + - NODE_ENV=production + # This needs to be changed to a secret value. + # You can run `npm run generate-secret` in the server project to generate an appropriate value. + - MD_SECRET=CHANGE ME + networks: + - internal + volumes: + # This mounts a new configuration file over the default one, which is easier than building a whole new image on top of the normal one with a new config file. + # Note the path to the local file will need changing to the real location. + - /host/path/to/config.json5:/md/config.json5:ro + restart: unless-stopped + + client: + container_name: client + # If you want to keep your deployment stable, it would be sensible to specify a specific tag rather than just `latest` here. + # Make sure you always deploy the same tag for client and server. + image: "massivedecks/client:latest" + depends_on: + - server + ports: + - "80:8080" + networks: + - internal + restart: unless-stopped diff --git a/docker-compose.yml b/docker-compose.yml index e599cbb..70c589c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,7 @@ +# This docker compose file is for building and running a development version of Massive Decks. +# If you want to deploy a production instance, please see +# https://github.com/Lattyware/massivedecks/wiki/Deploying for important steps you should take. + version: "3" networks: