chore(): docker-compose
This commit is contained in:
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM golang:1.24 as build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy module files and download dependencies
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Copy the rest of the application source and build
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o /invoiceapi cmd/invoiceapi/main.go
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
FROM alpine:3
|
||||
# the test program:
|
||||
COPY --from=build /invoiceapi /invoiceapi
|
||||
# the tls certificates:
|
||||
# NB: this pulls directly from the upstream image, which already has ca-certificates:
|
||||
|
||||
CMD [ "/invoiceapi" ]
|
||||
|
||||
38
README.md
38
README.md
@@ -2,28 +2,24 @@ docker run --rm -p 3030:3000 gotenberg/gotenberg:8
|
||||
|
||||
## Configuration
|
||||
|
||||
This application is configured using a `config.json` file in the root of the project. You can use the `config.json.example` file as a starting point.
|
||||
This application can be configured using a `config.json` file in the root of the project, or by using environment variables. Values set in environment variables will override the values from the `config.json` file.
|
||||
|
||||
```json
|
||||
{
|
||||
"email": {
|
||||
"smtp": {
|
||||
"host": "smtp.example.com",
|
||||
"port": 587,
|
||||
"username": "user",
|
||||
"password": "password"
|
||||
},
|
||||
"from": "from@example.com"
|
||||
},
|
||||
"pdf": {
|
||||
"hostname": "http://localhost:3030"
|
||||
},
|
||||
"gitea": {
|
||||
"url": "https://gitea.example.com",
|
||||
"token": "your-gitea-token"
|
||||
}
|
||||
}
|
||||
```
|
||||
You can use the `config.example.json` file as a starting point for your `config.json`.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
The following environment variables can be used for configuration:
|
||||
|
||||
| Variable | Description |
|
||||
| --------------------- | --------------------------------------------- |
|
||||
| `PDF_HOSTNAME` | The hostname of the PDF generator (Gotenberg) |
|
||||
| `GITEA_URL` | The URL of your Gitea instance |
|
||||
| `GITEA_TOKEN` | Your Gitea API token |
|
||||
| `EMAIL_FROM` | The "From" address for sending emails |
|
||||
| `EMAIL_SMTP_HOST` | The SMTP server host |
|
||||
| `EMAIL_SMTP_PORT` | The SMTP server port |
|
||||
| `EMAIL_SMTP_USER` | The username for SMTP authentication |
|
||||
| `EMAIL_SMTP_PASSWORD` | The password for SMTP authentication |
|
||||
|
||||
## API Endpoints
|
||||
|
||||
|
||||
22
docker-compose.yml
Normal file
22
docker-compose.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
services:
|
||||
invoiceapi:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "8080:8080"
|
||||
depends_on:
|
||||
- gotenberg
|
||||
environment:
|
||||
- PDF_HOSTNAME=http://gotenberg:3000
|
||||
volumes:
|
||||
- ./config.json:/config.json
|
||||
develop:
|
||||
watch:
|
||||
- action: rebuild
|
||||
path: .
|
||||
ignore:
|
||||
- .git
|
||||
gotenberg:
|
||||
image: gotenberg/gotenberg:8
|
||||
restart: unless-stopped
|
||||
1
go.mod
1
go.mod
@@ -4,6 +4,7 @@ go 1.24.5
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.21.0
|
||||
github.com/caarlos0/env/v10 v10.0.0
|
||||
github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.8
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
||||
|
||||
2
go.sum
2
go.sum
@@ -2,6 +2,8 @@ code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4=
|
||||
code.gitea.io/sdk/gitea v0.21.0/go.mod h1:tnBjVhuKJCn8ibdyyhvUyxrR1Ca2KHEoTWoukNhXQPA=
|
||||
github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
|
||||
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
|
||||
github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA=
|
||||
github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9aGxzeN7G18=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
||||
|
||||
@@ -22,7 +22,7 @@ func New(log *slog.Logger, invoice invoicer, mail mailer) *Service {
|
||||
}
|
||||
|
||||
type invoicer interface {
|
||||
Generate(creditor, deptor model.Entity, mindur time.Duration, rate float64, repos []invoice.Repo) (document io.ReadCloser, report report.Report, err error)
|
||||
Generate(creditor, deptor model.Entity, mindur time.Duration, rate float64, repos []invoice.Repo) (document io.ReadCloser, report *report.Report, err error)
|
||||
}
|
||||
|
||||
type mailer interface {
|
||||
|
||||
@@ -5,37 +5,43 @@ import (
|
||||
"os"
|
||||
|
||||
"git.schreifuchs.ch/lou-taylor/accounting/internal/email"
|
||||
"github.com/caarlos0/env/v10"
|
||||
)
|
||||
|
||||
// PDF holds the configuration for the PDF generator.
|
||||
type PDF struct {
|
||||
Hostname string `json:"hostname"`
|
||||
Hostname string `json:"hostname" env:"HOSTNAME"`
|
||||
}
|
||||
|
||||
// Gitea holds the configuration for the Gitea client.
|
||||
type Gitea struct {
|
||||
URL string `json:"url"`
|
||||
Token string `json:"token"`
|
||||
URL string `json:"url" env:"URL"`
|
||||
Token string `json:"token" env:"TOKEN"`
|
||||
}
|
||||
|
||||
// Config holds the configuration for the entire application.
|
||||
type Config struct {
|
||||
Email email.Config `json:"email"`
|
||||
PDF PDF `json:"pdf"`
|
||||
Gitea Gitea `json:"gitea"`
|
||||
Email email.Config `json:"email" envPrefix:"EMAIL_"`
|
||||
PDF PDF `json:"pdf" envPrefix:"PDF_"`
|
||||
Gitea Gitea `json:"gitea" envPrefix:"GITEA_"`
|
||||
}
|
||||
|
||||
// Load loads the configuration from a JSON file.
|
||||
// Load loads the configuration from a JSON file and environment variables.
|
||||
func Load(path string) (*Config, error) {
|
||||
cfg := &Config{}
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
if err == nil {
|
||||
defer file.Close()
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
cfg := &Config{}
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(cfg); err != nil {
|
||||
if err := env.Parse(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -8,15 +8,15 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
SMTP SMTPConfig
|
||||
From string
|
||||
SMTP SMTPConfig `envPrefix:"SMTP_"`
|
||||
From string `env:"FROM"`
|
||||
}
|
||||
|
||||
type SMTPConfig struct {
|
||||
Host string
|
||||
Port string
|
||||
User string
|
||||
Password string
|
||||
Host string `env:"HOST"`
|
||||
Port string `env:"PORT"`
|
||||
User string `env:"USER"`
|
||||
Password string `env:"PASSWORD"`
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
|
||||
22
main.go
22
main.go
@@ -1,22 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.schreifuchs.ch/lou-taylor/accounting/internal/api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// var cfg invoice.Config
|
||||
// file, err := os.Open("config.json")
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// defer file.Close()
|
||||
// decoder := json.NewDecoder(file)
|
||||
// err = decoder.Decode(&cfg)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// invoice.Generate(cfg)
|
||||
api.Start(":8080")
|
||||
}
|
||||
Reference in New Issue
Block a user