Skip to content

Commit

Permalink
allow custom ports for webserver and le
Browse files Browse the repository at this point in the history
  • Loading branch information
tsmethurst committed Jul 24, 2021
1 parent 05e9af0 commit 318e377
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 26 deletions.
14 changes: 11 additions & 3 deletions GETTINGSTARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ docker run -d --network host --user postgres -e POSTGRES_PASSWORD=some_password
On your local machine (not your server), with Go installed, clone the GoToSocial repository, and build the binary with the provided build script:

```bash
./build/sh
./build.sh
```

If you need to build for a different architecture other than the one you're running the build on (eg., you're running on a Raspberry Pi but building on an amd64 machine), you can put set `GOOS` or `GOARCH` environment variables before running the build script, eg:

```bash
GOARCH=arm64 ./build.sh
```

### 6: Prepare VPS
Expand All @@ -52,7 +58,7 @@ Copy your binary from your local machine onto the VPS, using something like the
scp ./gotosocial [email protected]:/gotosocial/gotosocial
```

Replace `root` with whatever user you're actually running on your remote server.
Replace `root` with whatever user you're actually running on your remote server (you wouldn't run as root right? ;).

### 8: Copy Web Dir

Expand All @@ -75,11 +81,13 @@ cd /gotosocial
Then start the GoToSocial server with the following command (where `example.org` is the domain you set up in step 1, and `some_password` is the password you set for Postgres in step 4):

```bash
./gotosocial --host example.org --storage-serve-host example.org --letsencrypt-enabled=true server start
./gotosocial --host example.org --port 443 --storage-serve-host example.org --letsencrypt-enabled=true server start
```

The server should now start up and you should be able to access the splash page by navigating to your domain in the browser. Note that it might take up to a minute or so for your LetsEncrypt certificates to be created for the first time, so refresh a few times if necessary.

Note that for this example we're assuming that we're allowed to run on port 443 (standard https port), and that nothing else is running on this port.

### 10: Create and confirm your user

You can use the GoToSocial binary to also create, confirm, and promote your user account.
Expand Down
6 changes: 6 additions & 0 deletions cmd/gotosocial/generalflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,11 @@ func generalFlags(flagNames, envNames config.Flags, defaults config.Defaults) []
Value: defaults.Protocol,
EnvVars: []string{envNames.Protocol},
},
&cli.IntFlag{
Name: flagNames.Port,
Usage: "Port to use for GoToSocial. Change this to 443 if you're running the binary directly on the host machine.",
Value: defaults.Port,
EnvVars: []string{envNames.Port},
},
}
}
6 changes: 6 additions & 0 deletions cmd/gotosocial/letsencryptflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ func letsEncryptFlags(flagNames, envNames config.Flags, defaults config.Defaults
Value: defaults.LetsEncryptEnabled,
EnvVars: []string{envNames.LetsEncryptEnabled},
},
&cli.IntFlag{
Name: flagNames.LetsEncryptPort,
Usage: "Port to listen on for letsencrypt certificate challenges. Must not be the same as the GtS webserver/API port.",
Value: defaults.LetsEncryptPort,
EnvVars: []string{envNames.LetsEncryptPort},
},
&cli.StringFlag{
Name: flagNames.LetsEncryptCertDir,
Usage: "Directory to store acquired letsencrypt certificates.",
Expand Down
25 changes: 21 additions & 4 deletions example/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,22 @@ host: "localhost"
accountDomain: ""

# String. Protocol to use for the server. Only change to http for local testing!
# This should be the protocol part of the URI that your server is actually reachable on. So even if you're
# running GoToSocial behind a reverse proxy that handles SSL certificates for you, instead of using built-in
# letsencrypt, it should still be https.
# Options: ["http","https"]
# Default: "https"
protocol: "https"

# Int. Listen port for the GoToSocial webserver + API. If you're running behind a reverse proxy and/or in a docker,
# container, just set this to whatever you like (or leave the default), and make sure it's forwarded properly.
# If you are running with built-in letsencrypt enabled, and running GoToSocial directly on a host machine, you will
# probably want to set this to 443 (standard https port), unless you have other services already using that port.
# This *MUST NOT* be the same as the letsencrypt port specified below, unless letsencrypt is turned off.
# Examples: [443, 6666, 8080]
# Default: 8080
port: 8080

############################
##### DATABASE CONFIG ######
############################
Expand Down Expand Up @@ -256,16 +268,21 @@ statuses:
letsEncrypt:

# Bool. Whether or not letsencrypt should be enabled for the server.
# If true, the server will serve on port 443 (https) and obtain letsencrypt
# certificates automatically.
# If false, the server will serve on port 8080 (http), and the rest of the settings
# here will be ignored.
# If false, the rest of the settings here will be ignored.
# You should only change this if you want to serve GoToSocial behind a reverse proxy
# like Traefik, HAProxy, or Nginx.
# Options: [true, false]
# Default: true
enabled: true

# Int. Port to listen for letsencrypt certificate challenges on.
# If letsencrypt is enabled, this port must be reachable or you won't be able to obtain certs.
# If letsencrypt is disabled, this port will not be used.
# This *must not* be the same as the webserver/API port specified above.
# Examples: [80, 8000, 1312]
# Default: 80
port: 80

# String. Directory in which to store LetsEncrypt certificates.
# It is a good move to make this a sub-path within your storage directory, as it makes
# backup easier, but you might wish to move them elsewhere if they're also accessed by other services.
Expand Down
17 changes: 17 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type Config struct {
Host string `yaml:"host"`
AccountDomain string `yaml:"accountDomain"`
Protocol string `yaml:"protocol"`
Port int `yaml:"port"`
DBConfig *DBConfig `yaml:"db"`
TemplateConfig *TemplateConfig `yaml:"template"`
AccountsConfig *AccountsConfig `yaml:"accounts"`
Expand Down Expand Up @@ -150,6 +151,10 @@ func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error {
return errors.New("protocol was not set")
}

if c.Port == 0 || f.IsSet(fn.Port) {
c.Port = f.Int(fn.Port)
}

// db flags
if c.DBConfig.Type == "" || f.IsSet(fn.DbType) {
c.DBConfig.Type = f.String(fn.DbType)
Expand Down Expand Up @@ -262,6 +267,10 @@ func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error {
c.LetsEncryptConfig.Enabled = f.Bool(fn.LetsEncryptEnabled)
}

if c.LetsEncryptConfig.Port == 0 || f.IsSet(fn.LetsEncryptPort) {
c.LetsEncryptConfig.Port = f.Int(fn.LetsEncryptPort)
}

if c.LetsEncryptConfig.CertDir == "" || f.IsSet(fn.LetsEncryptCertDir) {
c.LetsEncryptConfig.CertDir = f.String(fn.LetsEncryptCertDir)
}
Expand Down Expand Up @@ -329,6 +338,7 @@ type Flags struct {
Host string
AccountDomain string
Protocol string
Port string

DbType string
DbAddress string
Expand Down Expand Up @@ -366,6 +376,7 @@ type Flags struct {
LetsEncryptEnabled string
LetsEncryptCertDir string
LetsEncryptEmailAddress string
LetsEncryptPort string

OIDCEnabled string
OIDCIdpName string
Expand All @@ -384,6 +395,7 @@ type Defaults struct {
Host string
AccountDomain string
Protocol string
Port int
SoftwareVersion string

DbType string
Expand Down Expand Up @@ -422,6 +434,7 @@ type Defaults struct {
LetsEncryptEnabled bool
LetsEncryptCertDir string
LetsEncryptEmailAddress string
LetsEncryptPort int

OIDCEnabled bool
OIDCIdpName string
Expand All @@ -442,6 +455,7 @@ func GetFlagNames() Flags {
Host: "host",
AccountDomain: "account-domain",
Protocol: "protocol",
Port: "port",

DbType: "db-type",
DbAddress: "db-address",
Expand Down Expand Up @@ -477,6 +491,7 @@ func GetFlagNames() Flags {
StatusesMaxMediaFiles: "statuses-max-media-files",

LetsEncryptEnabled: "letsencrypt-enabled",
LetsEncryptPort: "letsencrypt-port",
LetsEncryptCertDir: "letsencrypt-cert-dir",
LetsEncryptEmailAddress: "letsencrypt-email",

Expand All @@ -500,6 +515,7 @@ func GetEnvNames() Flags {
Host: "GTS_HOST",
AccountDomain: "GTS_ACCOUNT_DOMAIN",
Protocol: "GTS_PROTOCOL",
Port: "GTS_PORT",

DbType: "GTS_DB_TYPE",
DbAddress: "GTS_DB_ADDRESS",
Expand Down Expand Up @@ -535,6 +551,7 @@ func GetEnvNames() Flags {
StatusesMaxMediaFiles: "GTS_STATUSES_MAX_MEDIA_FILES",

LetsEncryptEnabled: "GTS_LETSENCRYPT_ENABLED",
LetsEncryptPort: "GTS_LETSENCRYPT_PORT",
LetsEncryptCertDir: "GTS_LETSENCRYPT_CERT_DIR",
LetsEncryptEmailAddress: "GTS_LETSENCRYPT_EMAIL",

Expand Down
7 changes: 7 additions & 0 deletions internal/config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ func TestDefault() *Config {
ApplicationName: defaults.ApplicationName,
Host: defaults.Host,
Protocol: defaults.Protocol,
Port: defaults.Port,
SoftwareVersion: defaults.SoftwareVersion,
DBConfig: &DBConfig{
Type: defaults.DbType,
Expand Down Expand Up @@ -51,6 +52,7 @@ func TestDefault() *Config {
},
LetsEncryptConfig: &LetsEncryptConfig{
Enabled: defaults.LetsEncryptEnabled,
Port: defaults.LetsEncryptPort,
CertDir: defaults.LetsEncryptCertDir,
EmailAddress: defaults.LetsEncryptEmailAddress,
},
Expand Down Expand Up @@ -115,6 +117,7 @@ func Default() *Config {
},
LetsEncryptConfig: &LetsEncryptConfig{
Enabled: defaults.LetsEncryptEnabled,
Port: defaults.LetsEncryptPort,
CertDir: defaults.LetsEncryptCertDir,
EmailAddress: defaults.LetsEncryptEmailAddress,
},
Expand All @@ -140,6 +143,7 @@ func GetDefaults() Defaults {
Host: "",
AccountDomain: "",
Protocol: "https",
Port: 8080,

DbType: "postgres",
DbAddress: "localhost",
Expand Down Expand Up @@ -175,6 +179,7 @@ func GetDefaults() Defaults {
StatusesMaxMediaFiles: 6,

LetsEncryptEnabled: true,
LetsEncryptPort: 80,
LetsEncryptCertDir: "/gotosocial/storage/certs",
LetsEncryptEmailAddress: "",

Expand All @@ -197,6 +202,7 @@ func GetTestDefaults() Defaults {
Host: "localhost:8080",
AccountDomain: "",
Protocol: "http",
Port: 8080,

DbType: "postgres",
DbAddress: "localhost",
Expand Down Expand Up @@ -230,6 +236,7 @@ func GetTestDefaults() Defaults {
StatusesMaxMediaFiles: 6,

LetsEncryptEnabled: false,
LetsEncryptPort: 0,
LetsEncryptCertDir: "",
LetsEncryptEmailAddress: "",

Expand Down
8 changes: 5 additions & 3 deletions internal/config/letsencrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package config
// LetsEncryptConfig wraps everything needed to manage letsencrypt certificates from within gotosocial.
type LetsEncryptConfig struct {
// Should letsencrypt certificate fetching be enabled?
Enabled bool
Enabled bool `yaml:"enabled"`
// What port should the server listen for letsencrypt challenges on?
Port int `yaml:"port"`
// Where should certificates be stored?
CertDir string
CertDir string `yaml:"certDir"`
// Email address to pass to letsencrypt for notifications about certificate expiry etc.
EmailAddress string
EmailAddress string `yaml:"emailAddress"`
}
22 changes: 6 additions & 16 deletions internal/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,24 @@ func (r *router) AttachStaticFS(relativePath string, fs http.FileSystem) {
r.engine.StaticFS(relativePath, fs)
}

// Start starts the router nicely.
//
// Different ports and handlers will be served depending on whether letsencrypt is enabled or not.
// If it is enabled, then port 80 will be used for handling LE requests, and port 443 will be used
// for serving actual requests.
//
// If letsencrypt is not being used, then port 8080 only will be used for serving requests.
// Start starts the router nicely. It will serve two handlers if letsencrypt is enabled, and only the web/API handler if letsencrypt is not enabled.
func (r *router) Start() {
if r.config.LetsEncryptConfig.Enabled {
// serve the http handler on port 80 for receiving letsencrypt requests and solving their devious riddles
// serve the http handler on the selected letsencrypt port, for receiving letsencrypt requests and solving their devious riddles
go func() {
if err := http.ListenAndServe(":http", r.certManager.HTTPHandler(http.HandlerFunc(httpsRedirect))); err != nil && err != http.ErrServerClosed {
if err := http.ListenAndServe(fmt.Sprintf(":%d", r.config.LetsEncryptConfig.Port), r.certManager.HTTPHandler(http.HandlerFunc(httpsRedirect))); err != nil && err != http.ErrServerClosed {
r.logger.Fatalf("listen: %s", err)
}
}()

// and serve the actual TLS handler on port 443
// and serve the actual TLS handler
go func() {
if err := r.srv.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
r.logger.Fatalf("listen: %s", err)
}
}()
} else {
// no tls required so just serve on port 8080
// no tls required
go func() {
if err := r.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
r.logger.Fatalf("listen: %s", err)
Expand Down Expand Up @@ -148,6 +142,7 @@ func New(cfg *config.Config, db db.DB, logger *logrus.Logger) (Router, error) {

// create the http server here, passing the gin engine as handler
s := &http.Server{
Addr: fmt.Sprintf(":%d", cfg.Port),
Handler: engine,
ReadTimeout: readTimeout,
WriteTimeout: writeTimeout,
Expand All @@ -167,12 +162,7 @@ func New(cfg *config.Config, db db.DB, logger *logrus.Logger) (Router, error) {
Cache: autocert.DirCache(cfg.LetsEncryptConfig.CertDir),
Email: cfg.LetsEncryptConfig.EmailAddress,
}
// and create an HTTPS server
s.Addr = ":https"
s.TLSConfig = m.TLSConfig()
} else {
// le is NOT enabled, so just serve bare requests on port 8080
s.Addr = ":8080"
}

return &router{
Expand Down

0 comments on commit 318e377

Please sign in to comment.