add deploy docs
This commit is contained in:
		
							parent
							
								
									f5174a124c
								
							
						
					
					
						commit
						e2cf7bc33b
					
				
							
								
								
									
										90
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								README.md
									
									
									
									
									
								
							| @ -16,6 +16,96 @@ go build -mod=vendor . | |||||||
| ./goserv run --listen :3000 --serve-path ./overrides | ./goserv run --listen :3000 --serve-path ./overrides | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## Eamples and Config Templates | ||||||
|  | 
 | ||||||
|  | The example files are located in `./examples` | ||||||
|  | 
 | ||||||
|  | - Caddyfile (web server config) | ||||||
|  | - .env (environment variables) | ||||||
|  | - build.sh | ||||||
|  | 
 | ||||||
|  | ## Dependencies | ||||||
|  | 
 | ||||||
|  | This setup can be run on a VPS, such as Digital Ocean, OVH, or Scaleway | ||||||
|  | for \$5/month with minimal dependencies: | ||||||
|  | 
 | ||||||
|  | -   VPS | ||||||
|  | -   Caddy | ||||||
|  | -   PostgreSQL | ||||||
|  | -   Serviceman | ||||||
|  | 
 | ||||||
|  | **Mac**, **Linux**: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | curl -fsS https://webinstall.dev | bash | ||||||
|  | export PATH="$HOME:/.local/bin:$PATH" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | webi caddy serviceman postgres | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### VPS Setup | ||||||
|  | 
 | ||||||
|  | You should have a domain pointing to a VPS and create a user account named `app` | ||||||
|  | (because that's a common convention). This script will create an `app` user, | ||||||
|  | copying the `authorized_keys` from the root account. | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | my_vps='example.com' | ||||||
|  | ssh root@"$my_vps" 'curl -sS https://webinstall.dev/ssh-adduser | bash' | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can then login as a normal user. | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | ssh app@"$my_vps" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | It is now safe to disable the root account. | ||||||
|  | 
 | ||||||
|  | ### Caddy (Automatic HTTPS Server) | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | curl -fsS https://webinstall.dev/caddy | bash | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can start Caddy as a system service under the app user like this: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | sudo setcap 'cap_net_bind_service=+ep' "$(readlink $(command -v caddy))" | ||||||
|  | 
 | ||||||
|  | sudo env PATH="$PATH" \ | ||||||
|  |     serviceman add --name caddy --username app \ | ||||||
|  |     caddy run --config ./Caddyfile | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | See the Cheat Sheet at https://webinstall.dev/caddy | ||||||
|  | and https://webinstall.dev/serviceman | ||||||
|  | 
 | ||||||
|  | ### PostgreSQL (Database) | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | curl -fsS https://webinstall.dev/postgres | bash | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can start Postgres as a system service under the app user like this: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | sudo env PATH="$PATH" \ | ||||||
|  |     serviceman add --name postgres --username app -- \ | ||||||
|  |     postgres -D /home/app/.local/share/postgres/var -p 5432 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Username and password are set to 'postgres' by default: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | psql 'postgres://postgres:postgres@localhost:5432/postgres' | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | See the Cheat Sheets at https://webinstall.dev/postgres | ||||||
|  | and https://webinstall.dev/serviceman | ||||||
|  | 
 | ||||||
| ## License | ## License | ||||||
| 
 | 
 | ||||||
| Copyright 2020. All rights reserved. | Copyright 2020. All rights reserved. | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								examples/Caddyfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/Caddyfile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | # redirect www to bare domain | ||||||
|  | www.example.com { | ||||||
|  |     redir https://example.com{uri} permanent | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | example.com { | ||||||
|  |     # log to stdout, which is captured by journalctl | ||||||
|  |     log { | ||||||
|  |         output stdout | ||||||
|  |         format console | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     # turn on standard streaming compression | ||||||
|  |     encode gzip zstd | ||||||
|  | 
 | ||||||
|  |     # reverse proxy /api to :3000 | ||||||
|  |     reverse_proxy /api/* localhost:3000 | ||||||
|  | 
 | ||||||
|  |     # serve static files from public folder, but not /api | ||||||
|  |     @notApi { | ||||||
|  |         file { | ||||||
|  |             try_files {path} {path}/ {path}/index.html | ||||||
|  |         } | ||||||
|  |         not path /api/* | ||||||
|  |     } | ||||||
|  |     route { | ||||||
|  |       rewrite @notApi {http.matchers.file.relative} | ||||||
|  |     } | ||||||
|  |     root * /srv/example.com/public/ | ||||||
|  |     file_server | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								examples/build.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								examples/build.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | set -e | ||||||
|  | set -u | ||||||
|  | 
 | ||||||
|  | export GOFLAGS="-mod=vendor" | ||||||
|  | go mod tidy | ||||||
|  | go mod vendor | ||||||
|  | go generate -mod=vendor ./... | ||||||
|  | go build -mod=vendor . | ||||||
|  | 
 | ||||||
							
								
								
									
										2
									
								
								examples/dotenv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								examples/dotenv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | PORT="3000" | ||||||
|  | #LISTEN=":3000" | ||||||
							
								
								
									
										24
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								main.go
									
									
									
									
									
								
							| @ -38,6 +38,8 @@ func ver() { | |||||||
| 	fmt.Printf("%s v%s %s (%s)\n", name, version, commit[:7], date) | 	fmt.Printf("%s v%s %s (%s)\n", name, version, commit[:7], date) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var defaultAddr = ":3000" | ||||||
|  | 
 | ||||||
| type runOptions struct { | type runOptions struct { | ||||||
| 	listen     string | 	listen     string | ||||||
| 	trustProxy bool | 	trustProxy bool | ||||||
| @ -53,16 +55,15 @@ var dbURL string | |||||||
| func init() { | func init() { | ||||||
| 	runOpts = runOptions{} | 	runOpts = runOptions{} | ||||||
| 	runFlags = flag.NewFlagSet("run", flag.ExitOnError) | 	runFlags = flag.NewFlagSet("run", flag.ExitOnError) | ||||||
| 	runFlags.StringVar(&runOpts.listen, "listen", ":3000", "the address and port on which to listen") | 	runFlags.StringVar( | ||||||
|  | 		&runOpts.listen, "listen", "", | ||||||
|  | 		"the address and port on which to listen (default \""+defaultAddr+"\")") | ||||||
| 	runFlags.BoolVar(&runOpts.trustProxy, "trust-proxy", false, "trust X-Forwarded-For header") | 	runFlags.BoolVar(&runOpts.trustProxy, "trust-proxy", false, "trust X-Forwarded-For header") | ||||||
| 	runFlags.BoolVar(&runOpts.compress, "compress", true, "enable compression for text,html,js,css,etc") | 	runFlags.BoolVar(&runOpts.compress, "compress", true, "enable compression for text,html,js,css,etc") | ||||||
| 	runFlags.StringVar(&runOpts.static, "serve-path", "", "path to serve, falls back to built-in web app") | 	runFlags.StringVar(&runOpts.static, "serve-path", "", "path to serve, falls back to built-in web app") | ||||||
| 	runFlags.StringVar( | 	runFlags.StringVar( | ||||||
| 		&dbURL, | 		&dbURL, "db-url", "postgres://postgres:postgres@localhost:5432/postgres", | ||||||
| 		"db-url", | 		"database (postgres) connection url") | ||||||
| 		"postgres://postgres:postgres@localhost:5432/postgres", |  | ||||||
| 		"database (postgres) connection url", |  | ||||||
| 	) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| @ -94,6 +95,17 @@ func main() { | |||||||
| 		initFlags.Parse(args[2:]) | 		initFlags.Parse(args[2:]) | ||||||
| 	case "run": | 	case "run": | ||||||
| 		runFlags.Parse(args[2:]) | 		runFlags.Parse(args[2:]) | ||||||
|  | 		if "" == runOpts.listen { | ||||||
|  | 			listen := os.Getenv("LISTEN") | ||||||
|  | 			port := os.Getenv("PORT") | ||||||
|  | 			if len(listen) > 0 { | ||||||
|  | 				runOpts.listen = listen | ||||||
|  | 			} else if len(port) > 0 { | ||||||
|  | 				runOpts.listen = "127.0.0.1:" + port | ||||||
|  | 			} else { | ||||||
|  | 				runOpts.listen = defaultAddr | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		serve() | 		serve() | ||||||
| 	default: | 	default: | ||||||
| 		usage() | 		usage() | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user