Skip to content

Commit 75635ee

Browse files
committed
Make the reverse_proxy configurable
1 parent 8c16f87 commit 75635ee

File tree

14 files changed

+149
-59
lines changed

14 files changed

+149
-59
lines changed

src/blocks/create_domain.ts renamed to src/blocks/create_caddy_domain.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,18 @@ import { block } from './block.js'
44

55
type Config = {
66
domain: string
7-
ports_var: string
87
caddyfile_path: string
8+
caddyfile_content: string
99
}
1010

11-
const reverse_proxy = (x: Config) =>
12-
`${x.domain} {
13-
reverse_proxy {{ ${x.ports_var} | map('regex_replace', '^', '127.0.0.1:') | join(' ') }} {
14-
lb_policy client_ip_hash
15-
}
16-
}`
17-
18-
export function create_domain(config: Config): Block {
19-
return block(`Configure domain: ${config.domain}`, {}, [
11+
export function create_caddy_domain(config: Config): Block {
12+
return block(`Configure Caddy domain: ${config.domain}`, {}, [
2013
builtin.lineinfile(
2114
`Ensure ${config.domain} is in /etc/hosts`,
2215
{ path: '/etc/hosts', line: `127.0.0.1 ${config.domain}`, state: 'present' },
2316
{ become: true },
2417
),
25-
builtin.copy(`Create Caddyfile for ${config.domain}`, { dest: config.caddyfile_path, content: reverse_proxy(config) }, { register: 'caddyfile' }),
18+
builtin.copy(`Create Caddyfile for ${config.domain}`, { dest: config.caddyfile_path, content: config.caddyfile_content }, { register: 'caddyfile' }),
2619
builtin.command(`Reload caddy`, { cmd: `sudo systemctl reload caddy` }, { become: true, when: 'caddyfile.changed' }),
2720
]).get()
2821
}

src/blocks/create_directory.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { builtin } from '../ansible/tasks/index.js'
22

3-
export function create_directory(path: string) {
4-
return builtin.file(
5-
`Create directory ${path}`,
6-
{ path, state: 'directory', owner: '{{ansible_user}}', group: '{{ansible_user}}', mode: '0755' },
7-
{ become: true },
8-
)
3+
type Config = {
4+
owner?: string
5+
group?: string
6+
mode?: string
7+
}
8+
9+
export function create_directory(path: string, config: Config = {}) {
10+
config.owner ||= '{{ansible_user}}'
11+
config.group ||= '{{ansible_user}}'
12+
config.mode ||= '0755'
13+
return builtin.file(`Create directory ${path}`, { path, state: 'directory', ...config }, { become: true })
914
}

src/blocks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export * as assert from './assert.js'
22
export * from './build_repo.js'
33
export * from './create_directory.js'
4-
export * from './create_domain.js'
4+
export * from './create_caddy_domain.js'
55
export * from './create_service.js'
66
export * from './delete_directory.js'
77
export * from './delete_docker_image.js'

src/blocks/install_caddy.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import { block } from './block.js'
12
import { Block } from '../ansible/types.js'
23
import { builtin } from '../ansible/tasks/index.js'
3-
import { block } from './block.js'
44

5-
export function install_caddy(caddyfiles_pattern: string): Block {
5+
type Config = {
6+
caddyfile_content: string
7+
}
8+
9+
export function install_caddy(config: Config): Block {
610
return block(`Install Caddy`, {}, [
711
builtin.apt(
812
`Install Caddy's dependencies`,
@@ -26,14 +30,7 @@ export function install_caddy(caddyfiles_pattern: string): Block {
2630
),
2731
builtin.apt(`Update apt cache`, { update_cache: true }, { become: true }),
2832
builtin.apt(`Install Caddy`, { name: 'caddy', state: 'present' }, { become: true }),
29-
builtin.copy(
30-
`Configure Caddy`,
31-
{
32-
dest: '/etc/caddy/Caddyfile',
33-
content: `import ${caddyfiles_pattern}\n`,
34-
},
35-
{ become: true },
36-
),
33+
builtin.copy(`Configure Caddy`, { dest: '/etc/caddy/Caddyfile', content: config.caddyfile_content }, { become: true }),
3734
builtin.command(`Reload Caddy config`, { cmd: `sudo systemctl start caddy` }, { become: true }),
3835
]).get()
3936
}

src/files.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import fs from 'fs'
2+
import path from 'path'
3+
import { fileURLToPath } from 'url'
4+
5+
type FileData = {
6+
server_caddyfile: {
7+
log_path: string
8+
service_caddyfiles_pattern: string
9+
}
10+
service_caddyfile: {
11+
domain: string
12+
local_urls: string
13+
}
14+
}
15+
16+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
17+
const files_dir = path.join(__dirname, 'files')
18+
19+
export function get_file<Name extends keyof FileData>(name: Name, data: FileData[Name]) {
20+
let content = fs.readFileSync(path.join(files_dir, name), 'utf-8')
21+
for (const [key, value] of Object.entries(data)) {
22+
content = content.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value)
23+
}
24+
return content
25+
}

src/files/server_caddyfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
log {
3+
format json
4+
output file {{log_path}} {
5+
roll_size 10mb
6+
roll_keep 10
7+
}
8+
}
9+
}
10+
11+
import {{service_caddyfiles_pattern}}

src/files/service_caddyfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{{domain}} {
2+
reverse_proxy {{local_urls}} {
3+
lb_policy client_ip_hash
4+
}
5+
}

src/reverse_proxy/caddy.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import path from 'path'
2+
import { get_file } from '../files.js'
3+
import * as blocks from '../blocks/index.js'
4+
import { CaddyConfig, ReverseProxy, ReverseProxyConfig, Server } from '../types.js'
5+
6+
const default_config: Required<CaddyConfig> = {
7+
get_server_caddyfile: (server) =>
8+
get_file('server_caddyfile', {
9+
log_path: `${server.logs_dir}/caddy.log`,
10+
service_caddyfiles_pattern: `${server.services_dir}/*/Caddyfile`,
11+
}),
12+
get_service_caddyfile: (server, config) => get_file('service_caddyfile', config),
13+
}
14+
15+
export function caddy(config: CaddyConfig = {}): ReverseProxy {
16+
const normalized_config = { ...default_config, ...config }
17+
return {
18+
get_log_path: (server) => `${server.logs_dir}/caddy.log`,
19+
get_server_tasks: (server) => get_server_tasks(normalized_config, server),
20+
get_service_tasks: (server, reverse_proxy_config) => get_service_tasks(normalized_config, server, reverse_proxy_config),
21+
}
22+
}
23+
24+
function get_server_tasks(config: Required<CaddyConfig>, server: Server) {
25+
return [blocks.install_caddy({ caddyfile_content: config.get_server_caddyfile(server) })]
26+
}
27+
28+
function get_service_tasks(config: Required<CaddyConfig>, server: Server, reverse_proxy_config: ReverseProxyConfig) {
29+
return [
30+
blocks.create_caddy_domain({
31+
domain: reverse_proxy_config.domain,
32+
caddyfile_path: path.join(server.get_service_dir(reverse_proxy_config.service_name), 'Caddyfile'),
33+
caddyfile_content: config.get_service_caddyfile(server, reverse_proxy_config),
34+
}),
35+
]
36+
}

src/reverse_proxy/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './caddy.js'

src/server.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'path'
33
import { Host } from './ansible/types.js'
44
import * as blocks from './blocks/index.js'
55
import { Server, ServerConfig } from './types.js'
6+
import { caddy } from './reverse_proxy/index.js'
67

78
export function server(config: ServerConfig): Server {
89
const user = os.userInfo().username
@@ -14,16 +15,20 @@ export function server(config: ServerConfig): Server {
1415
const hosty_dir = config.hosty_dir || '/srv/hosty'
1516
const backups_dir = path.join(hosty_dir, 'backups')
1617
const services_dir = path.join(hosty_dir, 'services')
18+
const logs_dir = path.join(hosty_dir, 'logs')
19+
1720
return {
1821
connection,
1922
hosty_dir,
2023
backups_dir,
2124
services_dir,
25+
logs_dir,
2226
name: config.name,
2327
ssh_key: config.ssh_key || { path: '~/.ssh/id_rsa', passphrase: '' },
2428
git_config: config.git_config || {},
2529
docker_network: config.docker_network || 'hosty',
2630
docker_prefix: config.docker_prefix || '',
31+
reverse_proxy: config.reverse_proxy || caddy(),
2732
get_service_dir: (name) => path.join(services_dir, name),
2833
get_backups_dir: (name) => path.join(backups_dir, name),
2934
}
@@ -58,6 +63,7 @@ export function get_setup_tasks(server: Server) {
5863
blocks.generate_ssh_key(server.ssh_key),
5964
blocks.install_nixpacks(),
6065
blocks.create_directory(server.hosty_dir),
61-
blocks.install_caddy(`${server.services_dir}/*/Caddyfile`),
66+
blocks.create_directory(server.logs_dir, { mode: '0777' }),
67+
...server.reverse_proxy.get_server_tasks(server),
6268
]
6369
}

0 commit comments

Comments
 (0)