# README
Go Compose Template
An architecture template for an app using Golang. The server uses the Chi router to handle requests. Postgres is used for the database. SQLC generates type-safe queries to the database. Docker Compose allows for a simple deployment and the ability to scale later by developing with containers in mind.
Running This Project
This walkthrough is designed for Linux systems. Windows systems can follow the general thread but may need to substitute some commands.
- First, create the file
secrets/postgres-password.secret
and add a password to it. This password is used by the database and app containers to improve security, but the secret file itself is not tracked. - Run
make -B build
(or, run each ofmake sqlc
,make app
,make docker
separately, see below). This will download all Go dependencies and docker containers required to run the project. - Run
make run
to start the project with Docker Compose.- On the first run, the database container will create a new database. This may not finish before the app container complains. If the app container is killed during the first
make run
, simply wait for the database to finish (a log message will inform you that the "database system is ready to accept connections") before stopping the process and callingmake run
again. If the app container still does not start up, try altering the healthcheck incompose.yaml
or removing it entirely.
- On the first run, the database container will create a new database. This may not finish before the app container complains. If the app container is killed during the first
- Once the containers have started up, the app container should log to stdout with the message "ready to serve".
- With a new terminal, run
curl 127.0.0.1:8080/newAuthor/author
. The app container should logmsg="new author request" authorName=author
. - In the new terminal, run
curl 127.0.0.1:8080/allAuthors
. You should receive a response1: author
.
Thanks to the persistent volume, restarting the Docker Compose session should retain the data (i.e. curling the allAuthors
end point should return the authors made previously).
Check our the Go code under internal/app
to see how the app logic works, including the log statements seen in this example. See the SQLC schemas and queries under sqlc/
for information on the database schema. Finally, compose.yaml
shows how these containers are built, managed, and communicate.
Make
This template provides a Makefile to help set up and manage the various systems. Use make -B <target>
to force the command to be run if make
refuses to build something.
make sqlc
generates SQLC for use in the Go project. Schemas and queries are written in the respective files undersqlc
. Generated code is placed underinternal/app/database
. Note that theschema.sql
file is used to generate the database in Postgres.make app
builds the application logic (a Go project underinternal/app
) and places the executable inbuild
. This can be changed to use Docker to build the application as well if need be, and is essential if the host operating system is not Linux based.make docker
builds the app container (specified by the Dockerfile underbuild
, copying in the compiled Go project) and creates the database container. If the database container has not been built before, the filesqlc/schema.sql
that is copied in will create a new set of tables. Note that the database is stored in a persistent volume managed by Docker (volumedatabase-data
) and hence restarting the container will ensure the database persists. Sincesqlc/schema.sql
is run on every start up, adding the relevantDROP TABLE
statements to the start of the schema will allow for a fresh database with each container restart, and is useful for testing and development. A similar result can be achieved by removing the volume withdocker volume rm <volume name>
make -i dockerClean
allows for the explicit removal of the docker containers and volumes --- BEWARE! This will drop your database and containers!
make build
runs the above commands in order, preparing the application to be run.make run
first runsmake build
thendocker compose up
to start the application --- this effectively replacesgo run .
in your debugging step.
Secrets
The secrets
directory allows for secrets (passwords, API keys, and so on) to be placed within the project without fear of being tracked with git due to the .gitignore
. To compile this project the file postgres-password.secret
must be present in this directory.
Logging and Debugging
This template uses slog
to log events in the application. By default the log level is set to INFO
and logs are written in JSON format to a file that is mounted to the host file-system at ./logs/log
.
An environment variable DEBUG
is checked when the container starts up, and can be set in the compose.yaml
. If this variable is set, logging is instead set to level DEBUG
and logs are written as text directly to stdout
.
TODO:
- Add SSL to the Postgres database.
- Prevent outside requests to Postgres database --- look into Docker Compose networking.