{"id":27165029,"url":"https://github.com/mocdaniel/guestbook-demo","last_synced_at":"2026-01-20T08:01:52.601Z","repository":{"id":134108886,"uuid":"584320301","full_name":"mocdaniel/guestbook-demo","owner":"mocdaniel","description":"A simple anonymous Guestbook web-app, written in Go and VueJS. ","archived":false,"fork":false,"pushed_at":"2023-01-09T09:43:06.000Z","size":397,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T02:51:13.594Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mocdaniel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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":"2023-01-02T08:16:19.000Z","updated_at":"2023-01-02T08:20:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"144ef705-e5aa-45d4-a5fe-873d92a5d7a3","html_url":"https://github.com/mocdaniel/guestbook-demo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mocdaniel/guestbook-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocdaniel%2Fguestbook-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocdaniel%2Fguestbook-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocdaniel%2Fguestbook-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocdaniel%2Fguestbook-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mocdaniel","download_url":"https://codeload.github.com/mocdaniel/guestbook-demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocdaniel%2Fguestbook-demo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28598874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T02:08:49.799Z","status":"ssl_error","status_checked_at":"2026-01-20T02:08:44.148Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-04-09T02:50:49.473Z","updated_at":"2026-01-20T08:01:52.592Z","avatar_url":"https://github.com/mocdaniel.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Guestbook Demo\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://vuejs.org/logo.svg\" width=\"20\"/\u003e \u003cimg src=\"https://tailwindcss.com/favicons/favicon-16x16.png?v=3\" width=\"20\"/\u003e \u003cimg src=\"https://go.dev/favicon.ico\" width=\"20\"/\u003e\u003c/p\u003e\n\nThis repository is my attempt of creating a project to use for various demos/workshops on different topics,\ne.g. containerization, CI/CD, or various dev-tooling. **Therefore, development happens on an as-needed basis, \nand this code should not be used for anything else than demonstration purposes**.\n\nThe project is licensed under the **MIT License** - for more information, please head over to the [LICENSE](LICENSE).\n\n\n![Screenshot of the application](public/thumbnail.png)\n\n\n## Architecture\n\n### Frontend \u003cimg src=\"https://vuejs.org/logo.svg\" width=\"20\"/\u003e \u003cimg src=\"https://tailwindcss.com/favicons/favicon-16x16.png?v=3\" width=\"20\"/\u003e\n\n\n\nThe application's **frontend** is written in **HTML/CSS/Typescript**, using **[VueJS](https://vuejs.org)**\nas framework and **[TailwindCSS](https://tailwindcss.com)** for class-based styling.\n\n### Backend \u003cimg src=\"https://go.dev/favicon.ico\" width=\"20\"/\u003e\n\nThe application's **backend** is written in [Go](https://golang.org).\n\n### Building\n\nThe whole application gets built as a single Go-binary embedding the pre-built, static frontend files. For this, \nthe correct **[build tag](https://pkg.go.dev/go/build#hdr-Build_Constraints)** needs to be set\n(for more information, see [Building the application](https://github.com/mocdaniel/guestbook-demo#building-the-application)).\n\nDuring development, the backend will serve the frontend from your local filesystem instead. For more information see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n### Data Persistence\n\nThe application itself is **stateless**, i.e. all information gets pulled/saved from/to external services. \nTherefore, a working **PostgreSQL** database and **Redis** cache need to be available and referenced at runtime \n(see [Running the Application](https://github.com/mocdaniel/guestbook-demo#running-the-application)).\n\nThe application saves entries to a **PostgreSQL database** after checking, if the anonymous user has already entered feedback before. \nFor this to work, the application establishes an anonymous session for each visitor, \ncaching their session and whether they have provided feedback before using **Redis**.\n\nA session's lifetime is **24 hours**, entering additional feedback after 24 hours or by manually deleting the session cookie is possible **by design**.\n\n## Building the Application\n\nBuilding the application requires two separate steps - first building the VueJS frontend, then building the Go-binary\nand embedding the pre-built, static frontend files.\n\n### Building the Frontend\n\nThe frontend can be built by navigating to `./app/frontend` within the project's repository folder and issuing the following command:\n\n```\nnpm run build\n\n\u003e guestbook-demo@1.0.0 build\n\u003e run-p type-check build-only\n\n\n\u003e guestbook-demo@1.0.0 type-check\n\u003e vue-tsc --noEmit\n\n\n\u003e guestbook-demo@1.0.0 build-only\n\u003e vite build\n\nvite v3.1.8 building for production...\n✓ 676 modules transformed.\ndist/index.html                  0.42 KiB\ndist/assets/index.476f5aef.css   10.35 KiB / gzip: 2.61 KiB\ndist/assets/index.0ed272a2.js    93.31 KiB / gzip: 36.47 KiB\n```\n\nThe static files can then be found at `./app/frontend/dist`.\n\n### Building the Go Binary\n\nAs mentioned in the [Architecture](https://github.com/mocdaniel/guestbook-demo#architecture) section, the source code utilizes build tags\nto differentiate between development environment and production behaviour. Therefore, building the Go binary looks like this:\n\n```\ngo build -o guestbook -tags prod ./app\n```\n\nThe output directory/name of the Go binary can be set by passing the `-o` flag, the `-tags prod` part is **mandatory**.\n\n## Running the Application\n\nThe application exposes multiple settings which can be set using either **command line arguments** or **environment variables**.\n\n### Configuration via Command Line\n\nA list of all available command line arguments and their respective defaults can be displayed by passing the `--help`/`-h` flag:\n\n```\n./guestbook --help\nUsage of ./guestbook:\n      --db-host string            PostgreSQL server address (default \"localhost\")\n      --db-max-idle-conns int     PostgreSQL max idle connections (default 25)\n      --db-max-idle-time string   PostgreSQL max idle time (default \"15m\")\n      --db-max-open-conns int     PostgreSQL max open connections (default 25)\n      --db-name string            PostgreSQL database (default \"guestbook\")\n      --db-password string        PostgreSQL password (default \"password\")\n      --db-port int               PostgreSQL port (default 5432)\n      --db-user string            PostgreSQL user (default \"guestbook\")\n  -h, --help                      Prints this overview\n      --port int                  Webserver port (default 8080)\n      --redis-host string         Redis server address (default \"localhost\")\n      --redis-port int            Redis port (default 6379)\n      --redis-password string     Redis password (default \"\")\n```\n\n### Configuration via Environment Variables\n\nInstead of passing runtime configuration via the command line, environment variables can be used instead. \n\n| Parameter Name       | Description                                                                                                |\n|----------------------|------------------------------------------------------------------------------------------------------------|\n| `GUESTBOOK_DB_HOST`           | PostgreSQL server address                                                            |\n| `GUESTBOOK_DB_MAX_IDLE_CONNS`  | PostgreSQL max idle connections                                                            |\n| `GUESTBOOK_DB_MAX_IDLE_TIME`   | PostgreSQL max idle time                                                              |\n| `GUESTBOOK_DB_MAX_OPEN_CONNS`  | PostgreSQL max open connections                                                             |\n| `GUESTBOOK_DB_NAME`           | PostgreSQL database                                                               |\n| `GUESTBOOK_DB_PASSWORD`        | PostgreSQL password                                                                 |\n| `GUESTBOOK_DB_PORT`            | PostgreSQL port                                                                          |\n| `GUESTBOOK_DB_USER`            | PostgreSQL user                                                                    |\n| `GUESTBOOK_PORT`              | Webserver port                                                                             |\n| `GUESTBOOK_REDIS_HOST`         | Redis server address                                                               |\n| `GUESTBOOK_REDIS_PORT`        | Redis port                                                                                |\n| 'GUESTBOOK_REDIS_PASSWORD'    | Redis password |\n\n## Deployment\n\nBuilding the whole application into a single Go binary makes it easily deployable in a variety of ways. For some deployments, e.g. (Docker) Compose, resources are provided within this repository.\n\n### Running the Go Binary\n\nAs mentioned in [Running the Application](https://github.com/mocdaniel/guestbook-demo#running-the-application) the application can be run on most OSes by executing the binary either manually:\n\n```\n./guestbook --db-host postgres.example.com --redis-host redis.example.com --db-user daniel --db-password supersecure\n```\n\nThis will run the application in the foreground and log to stdout/stderr. In case you want to run it in the background,\nyou might want to look into creating a **systemd service file**.\n\n### Running the Docker image standalone\n\nThis repository provides a [Dockerfile](Dockerfile), following best practices where possible. It builds the application \nsimilar to the steps described in [Building the Application](https://github.com/mocdaniel/guestbook-demo#building-the-application), \nusing very slim and secure [images provided by Chainguard](https://www.chainguard.dev/chainguard-images).\n\nFor deploying via Docker, you first have to build the image:\n\n```\ndocker build -t someuser/somename:someversion .\n```\n\nThen you can go on and run the application via Docker, either in the foreground or background (by providing the `-d` flag).\nCLI parameters can be provided as **environment variables** or **cmd**, following the image specification:\n\n```\n# configure using environment variables\ndocker run -d -p 8080:8080 --name guestbook-demo \\\n-e GUESTBOOK_DB_HOST=postgres.example.com \\\n-e GUESTBOOK_REDIS_HOST=redis.example.com \\\nsomeuser/somename:someversion\n\n# configure using CLI parameters\ndocker run -d -p 8080:8080 --name guestbook-demo someuser/somename:someversion \\\n--db-host=postgres.example.com \\\n--redis-host=redis.example.com\n```\n\nIn case you need/want to delete the running container again, issue \n\n```\ndocker stop guestbook-demo\ndocker rm guestbook-demo\n```\n\n### Running the Docker Compose Stack\n\nIn addition to the Dockerfile, this repository provides a [compose.yml](compose.yml) file which defines a working \nenvironment for the guestbook-demo including **PostgreSQL** and **Redis** out of the box.\n\nTo deploy the whole stack either in fore- or background (again, provide the flag `-d`), just run the following command from the repository's root directory:\n\n```\ndocker compose up -d \n```\n\nThis will build the application's Docker image as defined in the [Dockerfile](Dockerfile) and spin up three containers for the application, PostgreSQL, and Redis. If you need/want to delete the stack again, issue\n\n```\ndocker compose down\n```\n\nfrom the repository's root directory.\n\n## Contributing\n\nAs mentioned above, this is a demo repository and **not meant for real-world/production use**. \nTherefore, I plan on developing additional features on an as-needed basis and **won't accept Pull Requests introducing new features**. \nHowever, if you find lacking information, documentation or bugs to fix, feel free to open a Pull Request. \n\nPlease see [CONTRIBUTING.md](CONTRIBUTING.md) for additional information on setting up your local developer environment etc.\n\n## License\n\nThis project is licensed under the **MIT License**. A copy of the License text can be found within this repository at [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmocdaniel%2Fguestbook-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmocdaniel%2Fguestbook-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmocdaniel%2Fguestbook-demo/lists"}