add docker-compose.yml

This commit is contained in:
dhax 2021-09-08 23:49:50 +02:00
parent f7b222b7f3
commit 32abb2ac26
5 changed files with 117 additions and 58 deletions

View file

@ -1,19 +1,26 @@
FROM golang:alpine AS builder FROM golang AS builder
WORKDIR /src
# Download dependencies
COPY go.mod go.sum /
RUN go mod download
# Add source code # Add source code
ADD ./ /go/src/github.com/dhax/go-base/ COPY . .
RUN CGO_ENABLED=0 go build -o main .
RUN cd /go/src/github.com/dhax/go-base && \
go build && \
mv ./go-base /usr/bin/go-base
# Multi-Stage production build # Multi-Stage production build
FROM alpine FROM alpine AS production
RUN apk --no-cache add ca-certificates
RUN apk add --update ca-certificates
WORKDIR /app
# Retrieve the binary from the previous stage # Retrieve the binary from the previous stage
COPY --from=builder /usr/bin/go-base /usr/local/bin/go-base COPY --from=builder /src/main .
# Copy static template files
COPY templates templates
# Copy frontend
COPY public public
# Expose port
EXPOSE 3000
# Set the binary as the entrypoint of the container # Set the binary as the entrypoint of the container
CMD ["go-base", "serve"] CMD ["./main", "serve"]

View file

@ -1,6 +1,6 @@
# Go Restful API Boilerplate # Go Restful API Boilerplate
[![GoDoc Badge]][GoDoc] [![GoReportCard Badge]][GoReportCard] [![GoDoc Badge]][godoc] [![GoReportCard Badge]][goreportcard]
Easily extendible RESTful API boilerplate aiming to follow idiomatic go and best practice. Easily extendible RESTful API boilerplate aiming to follow idiomatic go and best practice.
@ -9,6 +9,7 @@ The goal of this boiler is to have a solid and structured foundation to build up
Any feedback and pull requests are welcome and highly appreciated. Feel free to open issues just for comments and discussions. Any feedback and pull requests are welcome and highly appreciated. Feel free to open issues just for comments and discussions.
## Features ## Features
The following feature set is a minimal selection of typical Web API requirements: The following feature set is a minimal selection of typical Web API requirements:
- Configuration using [viper](https://github.com/spf13/viper) - Configuration using [viper](https://github.com/spf13/viper)
@ -16,82 +17,91 @@ The following feature set is a minimal selection of typical Web API requirements
- PostgreSQL support including migrations using [go-pg](https://github.com/go-pg/pg) - PostgreSQL support including migrations using [go-pg](https://github.com/go-pg/pg)
- Structured logging with [Logrus](https://github.com/sirupsen/logrus) - Structured logging with [Logrus](https://github.com/sirupsen/logrus)
- Routing with [chi router](https://github.com/go-chi/chi) and middleware - Routing with [chi router](https://github.com/go-chi/chi) and middleware
- JWT Authentication using [jwt-go](https://github.com/dgrijalva/jwt-go) with example passwordless email authentication - JWT Authentication using [golang-jwt](https://github.com/golang-jwt/jwt/v4) with example passwordless email authentication
- Request data validation using [ozzo-validation](https://github.com/go-ozzo/ozzo-validation) - Request data validation using [ozzo-validation](https://github.com/go-ozzo/ozzo-validation)
- HTML emails with [gomail](https://github.com/go-gomail/gomail) - HTML emails with [gomail](https://github.com/go-gomail/gomail)
## Start Application ## Start Application
- Clone this repository - Clone this repository
- Create a postgres database and set environment variables for your database accordingly if not using same as default - Create a postgres database and set environment variables for your database accordingly if not using same as default
- Run the application to see available commands: ```go run main.go``` - Run the application to see available commands: `go run main.go`
- First initialize the database running all migrations found in ./database/migrate at once with command *migrate*: ```go run main.go migrate``` - First initialize the database running all migrations found in ./database/migrate at once with command _migrate_: `go run main.go migrate`
- Run the application with command *serve*: ```go run main.go serve``` - Run the application with command _serve_: `go run main.go serve`
Or just use the provided docker-compose file. After first start attach to the server container and run `./main migrate` to populate the database.
## API Routes ## API Routes
### Authentication ### Authentication
For passwordless login following routes are available: For passwordless login following routes are available:
Path | Method | Required JSON | Header | Description | Path | Method | Required JSON | Header | Description |
---|---|---|---|--- | ------------- | ------ | ------------- | ------------------------------------- | ----------------------------------------------------------------------- |
/auth/login | POST | email | | the email you want to login with (see below) | /auth/login | POST | email | | the email you want to login with (see below) |
/auth/token | POST | token | | the token you received via email (or printed to stdout if smtp not set) | /auth/token | POST | token | | the token you received via email (or printed to stdout if smtp not set) |
/auth/refresh | POST | | Authorization: "Bearer refresh_token" | refresh JWTs | /auth/refresh | POST | | Authorization: "Bearer refresh_token" | refresh JWTs |
/auth/logout | POST | | Authorizaiton: "Bearer refresh_token" | logout from this device | /auth/logout | POST | | Authorizaiton: "Bearer refresh_token" | logout from this device |
### Example API ### Example API
Besides /auth/* the API provides two main routes /api/* and /admin/*, as an example to separate application and administration context. The latter requires to be logged in as administrator by providing the respective JWT in Authorization Header.
Besides /auth/_ the API provides two main routes /api/_ and /admin/\*, as an example to separate application and administration context. The latter requires to be logged in as administrator by providing the respective JWT in Authorization Header.
Check [routes.md](routes.md) for a generated overview of the provided API routes. Check [routes.md](routes.md) for a generated overview of the provided API routes.
### Client API Access and CORS ### Client API Access and CORS
The server is configured to serve a Progressive Web App (PWA) client from *./public* folder (this repo only serves an example index.html, see below for a demo PWA client to put here). In this case enabling CORS is not required, because the client is served from the same host as the api.
If you want to access the api from a client that is serverd from a different host, including e.g. a development live reloading server with below demo client, you must enable CORS on the server first by setting environment variable *ENABLE_CORS=true* on the server to allow api connections from clients serverd by other hosts. The server is configured to serve a Progressive Web App (PWA) client from _./public_ folder (this repo only serves an example index.html, see below for a demo PWA client to put here). In this case enabling CORS is not required, because the client is served from the same host as the api.
If you want to access the api from a client that is serverd from a different host, including e.g. a development live reloading server with below demo client, you must enable CORS on the server first by setting environment variable _ENABLE_CORS=true_ on the server to allow api connections from clients serverd by other hosts.
#### Demo client application #### Demo client application
For demonstration of the login and account management features this API serves a demo [Vue.js](https://vuejs.org) PWA. The client's source code can be found [here](https://github.com/dhax/go-base-vue). Build and put it into the api's *./public* folder, or use the live development server (requires CORS enabled).
Outgoing emails containing the login token will be print to stdout if no valid email smtp settings are provided by environment variables (see table below). If *EMAIL_SMTP_HOST* is set but the host can not be reached the application will exit immediately at start. For demonstration of the login and account management features this API serves a demo [Vue.js](https://vuejs.org) PWA. The client's source code can be found [here](https://github.com/dhax/go-base-vue). Build and put it into the api's _./public_ folder, or use the live development server (requires CORS enabled).
Outgoing emails containing the login token will be print to stdout if no valid email smtp settings are provided by environment variables (see table below). If _EMAIL_SMTP_HOST_ is set but the host can not be reached the application will exit immediately at start.
Use one of the following bootstrapped users for login: Use one of the following bootstrapped users for login:
- admin@boot.io (has access to admin panel) - admin@boot.io (has access to admin panel)
- user@boot.io - user@boot.io
A deployed version can also be found on [Heroku](https://govue.herokuapp.com) A deployed version can also be found on [Heroku](https://govue.herokuapp.com)
### Environment Variables ### Environment Variables
By default viper will look at $HOME/.go-base.yaml for a config file. Setting your config as Environment Variables is recommended as by 12-Factor App. By default viper will look at $HOME/.go-base.yaml for a config file. Setting your config as Environment Variables is recommended as by 12-Factor App.
Name | Type | Default | Description | Name | Type | Default | Description |
---|---|---|--- | ----------------------- | ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
PORT | string | localhost:3000 | http address (accepts also port number only for heroku compability) | PORT | string | localhost:3000 | http address (accepts also port number only for heroku compability) |
LOG_LEVEL | string | debug | log level | LOG_LEVEL | string | debug | log level |
LOG_TEXTLOGGING | bool | false | defaults to json logging | LOG_TEXTLOGGING | bool | false | defaults to json logging |
DB_NETWORK | string | tcp | database 'tcp' or 'unix' connection | DB_NETWORK | string | tcp | database 'tcp' or 'unix' connection |
DB_ADDR | string | localhost:5432 | database tcp address or unix socket | DB_ADDR | string | localhost:5432 | database tcp address or unix socket |
DB_USER | string | postgres | database user name | DB_USER | string | postgres | database user name |
DB_PASSWORD | string | postgres | database user password | DB_PASSWORD | string | postgres | database user password |
DB_DATABASE | string | gobase | database shema name | DB_DATABASE | string | postgres | database shema name |
AUTH_LOGIN_URL | string | http://localhost:3000/login | client login url as sent in login token email | AUTH_LOGIN_URL | string | http://localhost:3000/login | client login url as sent in login token email |
AUTH_LOGIN_TOKEN_LENGTH | int | 8 | length of login token | AUTH_LOGIN_TOKEN_LENGTH | int | 8 | length of login token |
AUTH_LOGIN_TOKEN_EXPIRY | time.Duration | 11m | login token expiry | AUTH_LOGIN_TOKEN_EXPIRY | time.Duration | 11m | login token expiry |
AUTH_JWT_SECRET | string | random | jwt sign and verify key - value "random" creates random 32 char secret at startup (and automatically invalidates existing tokens on app restarts, so during dev you might want to set a fixed value here) | AUTH_JWT_SECRET | string | random | jwt sign and verify key - value "random" creates random 32 char secret at startup (and automatically invalidates existing tokens on app restarts, so during dev you might want to set a fixed value here) |
AUTH_JWT_EXPIRY | time.Duration | 15m | jwt access token expiry | AUTH_JWT_EXPIRY | time.Duration | 15m | jwt access token expiry |
AUTH_JWT_REFRESH_EXPIRY | time.Duration | 1h | jwt refresh token expiry | AUTH_JWT_REFRESH_EXPIRY | time.Duration | 1h | jwt refresh token expiry |
EMAIL_SMTP_HOST | string || email smtp host (if set and connection can't be established then app exits) | EMAIL_SMTP_HOST | string | | email smtp host (if set and connection can't be established then app exits) |
EMAIL_SMTP_PORT | int || email smtp port | EMAIL_SMTP_PORT | int | | email smtp port |
EMAIL_SMTP_USER | string || email smtp username | EMAIL_SMTP_USER | string | | email smtp username |
EMAIL_SMTP_PASSWORD | string || email smtp password | EMAIL_SMTP_PASSWORD | string | | email smtp password |
EMAIL_FROM_ADDRESS | string || from address used in sending emails | EMAIL_FROM_ADDRESS | string | | from address used in sending emails |
EMAIL_FROM_NAME | string || from name used in sending emails | EMAIL_FROM_NAME | string | | from name used in sending emails |
ENABLE_CORS | bool | false | enable CORS requests | ENABLE_CORS | bool | false | enable CORS requests |
### Testing ### Testing
Package auth/pwdless contains example api tests using a mocked database. Package auth/pwdless contains example api tests using a mocked database.
[GoDoc]: https://godoc.org/github.com/dhax/go-base [godoc]: https://godoc.org/github.com/dhax/go-base
[GoDoc Badge]: https://godoc.org/github.com/dhax/go-base?status.svg [godoc badge]: https://godoc.org/github.com/dhax/go-base?status.svg
[GoReportCard]: https://goreportcard.com/report/github.com/dhax/go-base [goreportcard]: https://goreportcard.com/report/github.com/dhax/go-base
[GoReportCard Badge]: https://goreportcard.com/badge/github.com/dhax/go-base [goreportcard badge]: https://goreportcard.com/badge/github.com/dhax/go-base

View file

@ -26,7 +26,7 @@ func init() {
RootCmd.AddCommand(serveCmd) RootCmd.AddCommand(serveCmd)
// Here you will define your flags and configuration settings. // Here you will define your flags and configuration settings.
viper.SetDefault("port", "localhost:3000") viper.SetDefault("port", "3000")
viper.SetDefault("log_level", "debug") viper.SetDefault("log_level", "debug")
viper.SetDefault("auth_login_url", "http://localhost:3000/login") viper.SetDefault("auth_login_url", "http://localhost:3000/login")

View file

@ -15,7 +15,7 @@ func DBConn() (*pg.DB, error) {
viper.SetDefault("db_addr", "localhost:5432") viper.SetDefault("db_addr", "localhost:5432")
viper.SetDefault("db_user", "postgres") viper.SetDefault("db_user", "postgres")
viper.SetDefault("db_password", "postgres") viper.SetDefault("db_password", "postgres")
viper.SetDefault("db_database", "gobase") viper.SetDefault("db_database", "postgres")
db := pg.Connect(&pg.Options{ db := pg.Connect(&pg.Options{
Network: viper.GetString("db_network"), Network: viper.GetString("db_network"),

42
docker-compose.yml Normal file
View file

@ -0,0 +1,42 @@
version: "3.8"
volumes:
postgres:
services:
server:
build:
context: .
depends_on:
- postgres
ports:
- 3000:3000
environment:
LOG_LEVEL: debug
LOG_TEXTLOGGING: "true"
#PORT: 3000
DB_ADDR: postgres:5432
#DB_USER: postgres
#DB_PASSWORD: postgres
#DB_DATABASE: postgres
#AUTH_JWT_EXPIRY: 1h
#AUTH_JWT_REFRESH_EXPIRY: 72h
#AUTH_JWT_SECRET: my secret
#SENDGRID_API_KEY: your-sendgrid-api-key
#EMAIL_FROM_ADDRESS: go-base
#EMAIL_FROM_NAME: Go Base
#EMAIL_SMTP_HOST:
#EMAIL_SMTP_PORT: 465
#EMAIL_SMTP_USER:
#EMAIL_SMTP_PASSWORD:
ENABLE_CORS: "true"
postgres:
image: postgres:13
restart: unless-stopped
ports:
- 5432:5432
volumes:
- postgres:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres