~yerinalexey/gobin

6013cb5e58902241b8fa8b797c4cbd6ad988434f — Alexey Yerin 5 months ago bc245cd
Use configuration file instead of environment
6 files changed, 73 insertions(+), 52 deletions(-)

M README.md
A config.example.toml
M config/config.go
M go.mod
M go.sum
M main.go
M README.md => README.md +12 -29
@@ 11,33 11,9 @@ Simple self-hosted service for sharing text snippets
Two basic requirements are Go compiler (unless you grab built binaries)
and PostgreSQL database running.

## Database
Set `DATABASE_URI` environment variable to `postgresql://`-URI:

```sh
export DATABASE_URI=posgtresql://USER:PASSWORD@localhost/DB
```

- `USER` is your username (`postrges` is default)
- `PASSWORD` is your strong and complicated password
- `DB` is your database name (make sure to run `create database` before running)

## Configuration
Configuration is done via environment variables:

- `PORT` - change port on which application is running (default: 4000)
- `BASE_URL` - base URL for permalinks, no trailing slash (default: `http://localhost:4000`)
- `TEMPLATE_ROOT` - where templates are located (default: `./templates`)
- `STATIC_ROOT` - where static files are located (default: `./static`)

Example:
```sh
export BASE_URL=https://somesite.dev
export PORT=80 # Note: you might need to run gobin as root

export TEMPLATE_ROOT=/usr/share/gobin/templates
export STATIC_ROOT=/usr/share/gobin/static
```
Copy `config.example.toml` to `config.toml` (or whatever you want) and
edit to your liking. All fields are required.

## Building
```sh


@@ 49,9 25,11 @@ go build

## Migrations
```sh
./gobin-migrate up
DATABASE_URI=postgres://.. ./gobin-migrate up
```

`DATABASE_URI` is the same as `dbUri` in `config.toml`.

If something goes wrong, you can apply migrations manually by running
`up.sql` files in subdirectories of `./migrations`.



@@ 60,5 38,10 @@ If something goes wrong, you can apply migrations manually by running
./gobin
```

It's also a good idea to run `gobin` binary as a system service. Make
sure to provide all environment variables.
or

```sh
./gobin -config /etc/whatever.toml    # if you have a config file in different place
```

It's also a good idea to run `gobin` binary as a system service.

A config.example.toml => config.example.toml +22 -0
@@ 0,0 1,22 @@
# Configuration for gobin

# Postgres database URI to connect to
#
# Format as follows: postgres://<USER>[:PASSWORD]@<HOST>[:PORT]/<DB>
dbUri = "postgres://postgres:qqqq@localhost/gobin"

# On which port the application runs
#
# If you port is <1024, you need to run gobin as root because such ports
# are priviliged
port = 4000

# Directories for static assets and templates, relative to where you're
# launching gobin from
templateRoot = "./templates"
staticRoot = "./static"

# Base URL for permalinks
#
# FIXME: This setting will be gone at some point
baseUrl = "http://localhost"

M config/config.go => config/config.go +25 -22
@@ 5,7 5,8 @@ package config
import (
	"os"
	"errors"
	"strconv"

	"github.com/naoina/toml"
)

type Config struct {


@@ 18,37 19,39 @@ type Config struct {
	BaseUrl string
}

func New() (*Config, error) {
	db_uri := os.Getenv("DATABASE_URI")
	if db_uri == "" {
		return nil, errors.New("DATABASE_URI is not set")
func New(configFile string) (*Config, error) {
	f, err := os.Open(configFile)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	cfg := Config{}

	var port int = 4000
	if err = toml.NewDecoder(f).Decode(&cfg); err != nil {
		return nil, err
	}

	if v := os.Getenv("PORT"); v != "" {
		var err error
		port, err = strconv.Atoi(v)
	// Checks to make sure config is not messed up
	if cfg.DbUri == "" {
		return nil, errors.New("DbUri is not set")
	}

		if err != nil {
			return nil, errors.New("PORT is not an integer")
		}
	if cfg.Port == 0 {
		return nil, errors.New("Port can't be 0")
	}

	base_url := os.Getenv("BASE_URL")
	if base_url == "" {
		base_url = "http://localhost:4000"
	if cfg.BaseUrl == "" {
		return nil, errors.New("BaseUri should be set")
	}

	template_root := os.Getenv("TEMPLATE_ROOT")
	if template_root == "" {
		template_root = "./templates"
	if cfg.TemplateRoot == "" {
		return nil, errors.New("TemplateRoot should be set")
	}

	static_root := os.Getenv("STATIC_ROOT")
	if static_root == "" {
		static_root = "./static"
	if cfg.StaticRoot == "" {
		return nil, errors.New("StaticRoot should be set")
	}

	return &Config{db_uri, port, template_root, static_root, base_url}, nil
	return &cfg, nil
}

M go.mod => go.mod +3 -0
@@ 5,7 5,10 @@ go 1.15
require (
	github.com/gorilla/mux v1.8.0
	github.com/jackc/pgx/v4 v4.10.0
	github.com/kylelemons/godebug v1.1.0 // indirect
	github.com/lib/pq v1.4.0 // indirect
	github.com/naoina/go-stringutil v0.1.0 // indirect
	github.com/naoina/toml v0.1.1
	github.com/pkg/errors v0.9.1 // indirect
	github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea // indirect
	gopkg.in/yaml.v2 v2.2.3 // indirect

M go.sum => go.sum +6 -0
@@ 75,6 75,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=


@@ 90,6 92,10 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8=
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

M main.go => main.go +5 -1
@@ 23,6 23,7 @@ import (
	"net/http"
	"path"
	"strconv"
	"flag"

	"git.sr.ht/~yerinalexey/gobin/config"
	"git.sr.ht/~yerinalexey/gobin/paste"


@@ 32,7 33,10 @@ import (
)

func main() {
	config, err := config.New()
	configFile := flag.String("config", "config.toml", "path to configuration file")
	flag.Parse()

	config, err := config.New(*configFile)

	if err != nil {
		log.Fatalln("Invalid configuration:", err)