nvoi 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +19 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +151 -0
- data/Makefile +26 -0
- data/Rakefile +16 -0
- data/doc/config-schema.yaml +357 -0
- data/examples/apex-wildcard/deploy.yml +68 -0
- data/examples/golang/.gitignore +19 -0
- data/examples/golang/Dockerfile +43 -0
- data/examples/golang/README.md +59 -0
- data/examples/golang/deploy.enc +0 -0
- data/examples/golang/deploy.yml +54 -0
- data/examples/golang/go.mod +39 -0
- data/examples/golang/go.sum +96 -0
- data/examples/golang/main.go +177 -0
- data/examples/golang/models/user.go +17 -0
- data/examples/golang-postgres-multi/.gitignore +18 -0
- data/examples/golang-postgres-multi/Dockerfile +39 -0
- data/examples/golang-postgres-multi/README.md +211 -0
- data/examples/golang-postgres-multi/deploy.yml +67 -0
- data/examples/golang-postgres-multi/go.mod +45 -0
- data/examples/golang-postgres-multi/go.sum +108 -0
- data/examples/golang-postgres-multi/main.go +197 -0
- data/examples/golang-postgres-multi/models/user.go +17 -0
- data/examples/postgres-multi/.env.production.example +11 -0
- data/examples/postgres-multi/README.md +112 -0
- data/examples/postgres-multi/deploy.yml +74 -0
- data/examples/postgres-single/.env.production.example +11 -0
- data/examples/postgres-single/.gitignore +15 -0
- data/examples/postgres-single/Dockerfile +35 -0
- data/examples/postgres-single/README.md +76 -0
- data/examples/postgres-single/deploy.yml +56 -0
- data/examples/postgres-single/go.mod +45 -0
- data/examples/postgres-single/go.sum +108 -0
- data/examples/postgres-single/main.go +184 -0
- data/examples/rails-single/.dockerignore +51 -0
- data/examples/rails-single/.env.production.example +11 -0
- data/examples/rails-single/.github/dependabot.yml +12 -0
- data/examples/rails-single/.github/workflows/ci.yml +39 -0
- data/examples/rails-single/.gitignore +20 -0
- data/examples/rails-single/.node-version +1 -0
- data/examples/rails-single/.rubocop.yml +8 -0
- data/examples/rails-single/.ruby-version +1 -0
- data/examples/rails-single/Dockerfile +86 -0
- data/examples/rails-single/Gemfile +56 -0
- data/examples/rails-single/Gemfile.lock +350 -0
- data/examples/rails-single/Procfile.dev +3 -0
- data/examples/rails-single/README.md +17 -0
- data/examples/rails-single/Rakefile +6 -0
- data/examples/rails-single/app/assets/builds/.keep +0 -0
- data/examples/rails-single/app/assets/images/.keep +0 -0
- data/examples/rails-single/app/assets/stylesheets/application.tailwind.css +1 -0
- data/examples/rails-single/app/controllers/application_controller.rb +4 -0
- data/examples/rails-single/app/controllers/concerns/.keep +0 -0
- data/examples/rails-single/app/controllers/users_controller.rb +19 -0
- data/examples/rails-single/app/helpers/application_helper.rb +2 -0
- data/examples/rails-single/app/javascript/application.js +3 -0
- data/examples/rails-single/app/javascript/controllers/application.js +9 -0
- data/examples/rails-single/app/javascript/controllers/hello_controller.js +7 -0
- data/examples/rails-single/app/javascript/controllers/index.js +8 -0
- data/examples/rails-single/app/jobs/application_job.rb +7 -0
- data/examples/rails-single/app/mailers/application_mailer.rb +4 -0
- data/examples/rails-single/app/models/application_record.rb +3 -0
- data/examples/rails-single/app/models/concerns/.keep +0 -0
- data/examples/rails-single/app/models/user.rb +2 -0
- data/examples/rails-single/app/views/layouts/application.html.erb +28 -0
- data/examples/rails-single/app/views/layouts/mailer.html.erb +13 -0
- data/examples/rails-single/app/views/layouts/mailer.text.erb +1 -0
- data/examples/rails-single/app/views/pwa/manifest.json.erb +22 -0
- data/examples/rails-single/app/views/pwa/service-worker.js +26 -0
- data/examples/rails-single/app/views/users/index.html.erb +38 -0
- data/examples/rails-single/bin/brakeman +7 -0
- data/examples/rails-single/bin/bundle +109 -0
- data/examples/rails-single/bin/dev +11 -0
- data/examples/rails-single/bin/docker-entrypoint +14 -0
- data/examples/rails-single/bin/jobs +6 -0
- data/examples/rails-single/bin/kamal +27 -0
- data/examples/rails-single/bin/rails +4 -0
- data/examples/rails-single/bin/rake +4 -0
- data/examples/rails-single/bin/rubocop +8 -0
- data/examples/rails-single/bin/setup +37 -0
- data/examples/rails-single/bin/thrust +5 -0
- data/examples/rails-single/bun.lock +224 -0
- data/examples/rails-single/config/application.rb +42 -0
- data/examples/rails-single/config/boot.rb +4 -0
- data/examples/rails-single/config/cable.yml +17 -0
- data/examples/rails-single/config/cache.yml +16 -0
- data/examples/rails-single/config/credentials.yml.enc +1 -0
- data/examples/rails-single/config/database.yml +100 -0
- data/examples/rails-single/config/environment.rb +5 -0
- data/examples/rails-single/config/environments/development.rb +69 -0
- data/examples/rails-single/config/environments/production.rb +87 -0
- data/examples/rails-single/config/environments/test.rb +50 -0
- data/examples/rails-single/config/initializers/assets.rb +7 -0
- data/examples/rails-single/config/initializers/content_security_policy.rb +25 -0
- data/examples/rails-single/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/rails-single/config/initializers/inflections.rb +16 -0
- data/examples/rails-single/config/locales/en.yml +31 -0
- data/examples/rails-single/config/puma.rb +41 -0
- data/examples/rails-single/config/queue.yml +18 -0
- data/examples/rails-single/config/recurring.yml +15 -0
- data/examples/rails-single/config/routes.rb +4 -0
- data/examples/rails-single/config.ru +6 -0
- data/examples/rails-single/db/cable_schema.rb +11 -0
- data/examples/rails-single/db/cache_schema.rb +12 -0
- data/examples/rails-single/db/migrate/20251123095526_create_users.rb +10 -0
- data/examples/rails-single/db/queue_schema.rb +129 -0
- data/examples/rails-single/db/seeds.rb +9 -0
- data/examples/rails-single/deploy.yml +57 -0
- data/examples/rails-single/lib/tasks/.keep +0 -0
- data/examples/rails-single/log/.keep +0 -0
- data/examples/rails-single/package.json +17 -0
- data/examples/rails-single/public/400.html +114 -0
- data/examples/rails-single/public/404.html +114 -0
- data/examples/rails-single/public/406-unsupported-browser.html +114 -0
- data/examples/rails-single/public/422.html +114 -0
- data/examples/rails-single/public/500.html +114 -0
- data/examples/rails-single/public/icon.png +0 -0
- data/examples/rails-single/public/icon.svg +3 -0
- data/examples/rails-single/public/robots.txt +1 -0
- data/examples/rails-single/script/.keep +0 -0
- data/examples/rails-single/vendor/.keep +0 -0
- data/examples/rails-single/yarn.lock +188 -0
- data/exe/nvoi +6 -0
- data/lib/nvoi/cli.rb +190 -0
- data/lib/nvoi/cloudflare/client.rb +287 -0
- data/lib/nvoi/config/config.rb +248 -0
- data/lib/nvoi/config/env_resolver.rb +63 -0
- data/lib/nvoi/config/loader.rb +102 -0
- data/lib/nvoi/config/naming.rb +196 -0
- data/lib/nvoi/config/ssh_keys.rb +82 -0
- data/lib/nvoi/config/types.rb +274 -0
- data/lib/nvoi/constants.rb +59 -0
- data/lib/nvoi/credentials/crypto.rb +88 -0
- data/lib/nvoi/credentials/editor.rb +272 -0
- data/lib/nvoi/credentials/manager.rb +173 -0
- data/lib/nvoi/deployer/cleaner.rb +36 -0
- data/lib/nvoi/deployer/image_builder.rb +23 -0
- data/lib/nvoi/deployer/infrastructure.rb +126 -0
- data/lib/nvoi/deployer/orchestrator.rb +146 -0
- data/lib/nvoi/deployer/retry.rb +67 -0
- data/lib/nvoi/deployer/service_deployer.rb +311 -0
- data/lib/nvoi/deployer/tunnel_manager.rb +57 -0
- data/lib/nvoi/deployer/types.rb +8 -0
- data/lib/nvoi/errors.rb +67 -0
- data/lib/nvoi/k8s/renderer.rb +44 -0
- data/lib/nvoi/k8s/templates.rb +29 -0
- data/lib/nvoi/logger.rb +72 -0
- data/lib/nvoi/providers/aws.rb +403 -0
- data/lib/nvoi/providers/base.rb +111 -0
- data/lib/nvoi/providers/hetzner.rb +288 -0
- data/lib/nvoi/providers/hetzner_client.rb +170 -0
- data/lib/nvoi/remote/docker_manager.rb +203 -0
- data/lib/nvoi/remote/ssh_executor.rb +72 -0
- data/lib/nvoi/remote/volume_manager.rb +103 -0
- data/lib/nvoi/service/delete.rb +234 -0
- data/lib/nvoi/service/deploy.rb +80 -0
- data/lib/nvoi/service/exec.rb +144 -0
- data/lib/nvoi/service/provider.rb +36 -0
- data/lib/nvoi/steps/application_deployer.rb +26 -0
- data/lib/nvoi/steps/database_provisioner.rb +60 -0
- data/lib/nvoi/steps/k3s_cluster_setup.rb +105 -0
- data/lib/nvoi/steps/k3s_provisioner.rb +351 -0
- data/lib/nvoi/steps/server_provisioner.rb +43 -0
- data/lib/nvoi/steps/services_provisioner.rb +29 -0
- data/lib/nvoi/steps/tunnel_configurator.rb +66 -0
- data/lib/nvoi/steps/volume_provisioner.rb +154 -0
- data/lib/nvoi/version.rb +5 -0
- data/lib/nvoi.rb +79 -0
- data/templates/app-deployment.yaml.erb +102 -0
- data/templates/app-ingress.yaml.erb +20 -0
- data/templates/app-secret.yaml.erb +10 -0
- data/templates/app-service.yaml.erb +12 -0
- data/templates/db-statefulset.yaml.erb +76 -0
- data/templates/service-deployment.yaml.erb +91 -0
- data/templates/worker-deployment.yaml.erb +50 -0
- metadata +361 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# PostgreSQL Multi-Instance Example
|
|
2
|
+
|
|
3
|
+
Production setup with app on master server and PostgreSQL on dedicated worker server.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────┐
|
|
9
|
+
│ Master Server (cx32) │
|
|
10
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
11
|
+
│ K3s Server Mode │
|
|
12
|
+
│ │
|
|
13
|
+
│ ┌──────────────────────────────┐ │
|
|
14
|
+
│ │ App Pod │ │
|
|
15
|
+
│ │ - Port 3000 │ │
|
|
16
|
+
│ │ - Connects to: │ │
|
|
17
|
+
│ │ postgres-service:5432 │ │
|
|
18
|
+
│ └──────────────────────────────┘ │
|
|
19
|
+
│ │
|
|
20
|
+
│ Private IP: 10.0.0.1 │
|
|
21
|
+
└─────────────────────────────────────┘
|
|
22
|
+
│
|
|
23
|
+
│ K3s Cluster Network (WireGuard)
|
|
24
|
+
│
|
|
25
|
+
┌─────────────────────────────────────┐
|
|
26
|
+
│ Worker Server (cx42) │
|
|
27
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
28
|
+
│ K3s Agent Mode │
|
|
29
|
+
│ │
|
|
30
|
+
│ ┌──────────────────────────────┐ │
|
|
31
|
+
│ │ PostgreSQL StatefulSet │ │
|
|
32
|
+
│ │ - Service: postgres-service │ │
|
|
33
|
+
│ │ - Port: 5432 │ │
|
|
34
|
+
│ │ - Volume: /var/lib/postgres │ │
|
|
35
|
+
│ └──────────────────────────────┘ │
|
|
36
|
+
│ │
|
|
37
|
+
│ Private IP: 10.0.0.2 │
|
|
38
|
+
│ Volume: /opt/postgres_data │
|
|
39
|
+
└─────────────────────────────────────┘
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Cost
|
|
43
|
+
|
|
44
|
+
- **Master**: 1x cx32 (~€10/month)
|
|
45
|
+
- **Worker**: 1x cx42 (~€15/month)
|
|
46
|
+
- **Total**: ~€25/month
|
|
47
|
+
|
|
48
|
+
## Benefits
|
|
49
|
+
|
|
50
|
+
1. **Resource Isolation**: Database gets dedicated server resources
|
|
51
|
+
2. **Better Performance**: App and DB don't compete for CPU/memory
|
|
52
|
+
3. **Scalability**: Can add more workers for distributed workloads
|
|
53
|
+
4. **High Availability**: Foundation for future HA setups
|
|
54
|
+
|
|
55
|
+
## Setup
|
|
56
|
+
|
|
57
|
+
1. **Copy environment file**:
|
|
58
|
+
```bash
|
|
59
|
+
cp .env.production.example .env.production
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. **Edit `.env.production`** with your credentials:
|
|
63
|
+
```bash
|
|
64
|
+
CLOUDFLARE_API_TOKEN=your_token
|
|
65
|
+
CLOUDFLARE_ACCOUNT_ID=your_account_id
|
|
66
|
+
HETZNER_API_TOKEN=your_token
|
|
67
|
+
DB_PASSWORD=your_secure_password
|
|
68
|
+
SECRET_KEY_BASE=$(openssl rand -hex 64)
|
|
69
|
+
JWT_SECRET=$(openssl rand -hex 32)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
3. **Deploy**:
|
|
73
|
+
```bash
|
|
74
|
+
nvoi-cli deploy --config examples/postgres-multi/deploy.yml
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Verification
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# SSH to master
|
|
81
|
+
ssh root@<master-ip>
|
|
82
|
+
|
|
83
|
+
# Check PostgreSQL pod (should be on worker node)
|
|
84
|
+
kubectl get pods -o wide | grep postgres
|
|
85
|
+
|
|
86
|
+
# SSH to worker node
|
|
87
|
+
ssh root@<worker-ip>
|
|
88
|
+
|
|
89
|
+
# Check volume on worker
|
|
90
|
+
ls -la /opt/postgres_data/
|
|
91
|
+
|
|
92
|
+
# From master: Test service DNS
|
|
93
|
+
kubectl run -it --rm debug --image=postgres:16-alpine --restart=Never -- \
|
|
94
|
+
psql postgresql://appuser:$DB_PASSWORD@postgres-service:5432/app_production -c '\dt'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## How It Works
|
|
98
|
+
|
|
99
|
+
1. **Master Server**: Runs K3s in server mode, hosts the app
|
|
100
|
+
2. **Worker Server**: Joins K3s cluster as agent, runs PostgreSQL
|
|
101
|
+
3. **K3s Networking**: Private network (10.0.0.0/16) between nodes
|
|
102
|
+
4. **Service DNS**: App connects via `postgres-service:5432`
|
|
103
|
+
5. **Volume**: PostgreSQL data persists on worker node filesystem
|
|
104
|
+
|
|
105
|
+
## Features
|
|
106
|
+
|
|
107
|
+
- ✅ PostgreSQL 16 Alpine on dedicated server
|
|
108
|
+
- ✅ Persistent data storage on worker
|
|
109
|
+
- ✅ K3s service discovery
|
|
110
|
+
- ✅ Private cluster networking
|
|
111
|
+
- ✅ Resource isolation
|
|
112
|
+
- ✅ Production-ready setup
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
application:
|
|
2
|
+
name: example-postgres-multinode
|
|
3
|
+
environment: production
|
|
4
|
+
|
|
5
|
+
# Provider configuration
|
|
6
|
+
domain_provider:
|
|
7
|
+
cloudflare:
|
|
8
|
+
api_token: $CLOUDFLARE_API_TOKEN
|
|
9
|
+
account_id: $CLOUDFLARE_ACCOUNT_ID
|
|
10
|
+
|
|
11
|
+
compute_provider:
|
|
12
|
+
hetzner:
|
|
13
|
+
api_token: $HETZNER_API_TOKEN
|
|
14
|
+
server_type: cx22 # Default for all servers
|
|
15
|
+
server_location: nbg1
|
|
16
|
+
|
|
17
|
+
# Multi-instance server configuration: 4 servers total
|
|
18
|
+
servers:
|
|
19
|
+
master:
|
|
20
|
+
master: true
|
|
21
|
+
type: cx22 # Control plane only, no workloads
|
|
22
|
+
location: nbg1
|
|
23
|
+
|
|
24
|
+
workers:
|
|
25
|
+
type: cx32 # App servers
|
|
26
|
+
count: 2
|
|
27
|
+
location: nbg1
|
|
28
|
+
|
|
29
|
+
database:
|
|
30
|
+
type: cx42 # Dedicated database server
|
|
31
|
+
location: nbg1
|
|
32
|
+
|
|
33
|
+
# Container retention
|
|
34
|
+
keep_count: 2
|
|
35
|
+
|
|
36
|
+
# Application secrets
|
|
37
|
+
secrets:
|
|
38
|
+
SECRET_KEY_BASE: $SECRET_KEY_BASE
|
|
39
|
+
JWT_SECRET: $JWT_SECRET
|
|
40
|
+
|
|
41
|
+
# Application service (runs on workers with 2 replicas)
|
|
42
|
+
app:
|
|
43
|
+
web:
|
|
44
|
+
servers: [workers]
|
|
45
|
+
domain: rb.run
|
|
46
|
+
subdomain: postgres-multi
|
|
47
|
+
port: 3000
|
|
48
|
+
healthcheck:
|
|
49
|
+
type: http
|
|
50
|
+
path: /health
|
|
51
|
+
port: 3000
|
|
52
|
+
interval: 10s
|
|
53
|
+
timeout: 5s
|
|
54
|
+
retries: 3
|
|
55
|
+
env:
|
|
56
|
+
# PostgreSQL connection via K3s service DNS
|
|
57
|
+
DATABASE_URL: postgresql://appuser:$DB_PASSWORD@db-example-postgres-multinode:5432/app_production
|
|
58
|
+
RAILS_ENV: production
|
|
59
|
+
|
|
60
|
+
# PostgreSQL database (runs on dedicated database server)
|
|
61
|
+
database:
|
|
62
|
+
servers: [database]
|
|
63
|
+
adapter: postgres
|
|
64
|
+
image: postgres:16-alpine
|
|
65
|
+
volume: postgres_data
|
|
66
|
+
secrets:
|
|
67
|
+
POSTGRES_DB: app_production
|
|
68
|
+
POSTGRES_USER: appuser
|
|
69
|
+
POSTGRES_PASSWORD: $DB_PASSWORD
|
|
70
|
+
|
|
71
|
+
# Environment variables
|
|
72
|
+
env:
|
|
73
|
+
APP_NAME: postgres-multi-demo
|
|
74
|
+
LOG_LEVEL: info
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Provider credentials (required)
|
|
2
|
+
CLOUDFLARE_API_TOKEN=your_cloudflare_token_here
|
|
3
|
+
CLOUDFLARE_ACCOUNT_ID=your_cloudflare_account_id_here
|
|
4
|
+
HETZNER_API_TOKEN=your_hetzner_token_here
|
|
5
|
+
|
|
6
|
+
# Database password
|
|
7
|
+
DB_PASSWORD=your_secure_db_password_here
|
|
8
|
+
|
|
9
|
+
# Application secrets
|
|
10
|
+
SECRET_KEY_BASE=generate_with_openssl_rand_hex_64
|
|
11
|
+
JWT_SECRET=generate_with_openssl_rand_hex_32
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Multi-stage build for optimized image size
|
|
2
|
+
|
|
3
|
+
# Stage 1: Build
|
|
4
|
+
FROM golang:1.23-alpine AS builder
|
|
5
|
+
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
|
|
8
|
+
# Copy dependency files
|
|
9
|
+
COPY go.mod go.sum ./
|
|
10
|
+
|
|
11
|
+
# Download dependencies
|
|
12
|
+
RUN go mod download
|
|
13
|
+
|
|
14
|
+
# Copy source code
|
|
15
|
+
COPY . .
|
|
16
|
+
|
|
17
|
+
# Build the application
|
|
18
|
+
RUN CGO_ENABLED=0 GOOS=linux go build -o app .
|
|
19
|
+
|
|
20
|
+
# Stage 2: Runtime
|
|
21
|
+
FROM alpine:latest
|
|
22
|
+
|
|
23
|
+
# Install runtime dependencies
|
|
24
|
+
RUN apk --no-cache add ca-certificates
|
|
25
|
+
|
|
26
|
+
WORKDIR /app
|
|
27
|
+
|
|
28
|
+
# Copy binary from builder
|
|
29
|
+
COPY --from=builder /app/app .
|
|
30
|
+
|
|
31
|
+
# Expose port
|
|
32
|
+
EXPOSE 3000
|
|
33
|
+
|
|
34
|
+
# Run the application
|
|
35
|
+
CMD ["./app"]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# PostgreSQL Single Instance Example
|
|
2
|
+
|
|
3
|
+
Simple deployment with app and PostgreSQL database on one server.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────┐
|
|
9
|
+
│ Server (cx32) │
|
|
10
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
11
|
+
│ │
|
|
12
|
+
│ ┌──────────────────────────────┐ │
|
|
13
|
+
│ │ App Container │ │
|
|
14
|
+
│ │ - Port 3000 │ │
|
|
15
|
+
│ │ - Connects to localhost:5432 │ │
|
|
16
|
+
│ └──────────────────────────────┘ │
|
|
17
|
+
│ │
|
|
18
|
+
│ ┌──────────────────────────────┐ │
|
|
19
|
+
│ │ PostgreSQL Container │ │
|
|
20
|
+
│ │ - Port 5432 │ │
|
|
21
|
+
│ │ - Volume: postgres_data │ │
|
|
22
|
+
│ └──────────────────────────────┘ │
|
|
23
|
+
│ │
|
|
24
|
+
└─────────────────────────────────────┘
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Cost
|
|
28
|
+
|
|
29
|
+
- **Server**: 1x cx32 (~€10/month)
|
|
30
|
+
- **Total**: ~€10/month
|
|
31
|
+
|
|
32
|
+
## Setup
|
|
33
|
+
|
|
34
|
+
1. **Copy environment file**:
|
|
35
|
+
```bash
|
|
36
|
+
cp .env.production.example .env.production
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
2. **Edit `.env.production`** with your credentials:
|
|
40
|
+
```bash
|
|
41
|
+
CLOUDFLARE_API_TOKEN=your_token
|
|
42
|
+
CLOUDFLARE_ACCOUNT_ID=your_account_id
|
|
43
|
+
HETZNER_API_TOKEN=your_token
|
|
44
|
+
DB_PASSWORD=your_secure_password
|
|
45
|
+
SECRET_KEY_BASE=$(openssl rand -hex 64)
|
|
46
|
+
JWT_SECRET=$(openssl rand -hex 32)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. **Deploy**:
|
|
50
|
+
```bash
|
|
51
|
+
nvoi-cli deploy --config examples/postgres-single/deploy.yml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Verification
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# SSH to server
|
|
58
|
+
ssh root@<server-ip>
|
|
59
|
+
|
|
60
|
+
# Check PostgreSQL pod
|
|
61
|
+
kubectl get pods | grep postgres
|
|
62
|
+
|
|
63
|
+
# Check volume
|
|
64
|
+
ls -la /opt/postgres_data/
|
|
65
|
+
|
|
66
|
+
# Test connection
|
|
67
|
+
kubectl exec -it postgres-0 -- psql -U appuser -d app_production -c '\dt'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
- ✅ PostgreSQL 16 Alpine
|
|
73
|
+
- ✅ Persistent data storage
|
|
74
|
+
- ✅ Health checks
|
|
75
|
+
- ✅ Automatic backups (via volume)
|
|
76
|
+
- ✅ Simple single-server setup
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
application:
|
|
2
|
+
name: example-postgres
|
|
3
|
+
environment: production
|
|
4
|
+
|
|
5
|
+
# Provider configuration
|
|
6
|
+
domain_provider:
|
|
7
|
+
cloudflare:
|
|
8
|
+
api_token: $CLOUDFLARE_API_TOKEN
|
|
9
|
+
account_id: $CLOUDFLARE_ACCOUNT_ID
|
|
10
|
+
|
|
11
|
+
compute_provider:
|
|
12
|
+
hetzner:
|
|
13
|
+
api_token: $HETZNER_API_TOKEN
|
|
14
|
+
server_type: cx22
|
|
15
|
+
server_location: fsn1
|
|
16
|
+
|
|
17
|
+
# Server configuration (single server, master: true is implicit)
|
|
18
|
+
servers:
|
|
19
|
+
master:
|
|
20
|
+
type: cx22
|
|
21
|
+
location: fsn1
|
|
22
|
+
|
|
23
|
+
# Container retention
|
|
24
|
+
keep_count: 2
|
|
25
|
+
|
|
26
|
+
# Application service
|
|
27
|
+
app:
|
|
28
|
+
web:
|
|
29
|
+
servers: [master]
|
|
30
|
+
domain: rb.run
|
|
31
|
+
subdomain: go-pg
|
|
32
|
+
port: 3000
|
|
33
|
+
healthcheck:
|
|
34
|
+
type: http
|
|
35
|
+
path: /health
|
|
36
|
+
port: 3000
|
|
37
|
+
interval: 10s
|
|
38
|
+
timeout: 5s
|
|
39
|
+
retries: 3
|
|
40
|
+
|
|
41
|
+
# PostgreSQL database (runs on same server)
|
|
42
|
+
database:
|
|
43
|
+
servers: [master]
|
|
44
|
+
adapter: postgres
|
|
45
|
+
image: postgres:16-alpine
|
|
46
|
+
volume: postgres_data
|
|
47
|
+
secrets:
|
|
48
|
+
POSTGRES_DB: app_production
|
|
49
|
+
POSTGRES_USER: appuser
|
|
50
|
+
POSTGRES_PASSWORD: $DB_PASSWORD
|
|
51
|
+
|
|
52
|
+
# Environment variables (DATABASE_URL auto-injected from database config)
|
|
53
|
+
env:
|
|
54
|
+
APP_NAME: go-postgres-demo
|
|
55
|
+
LOG_LEVEL: info
|
|
56
|
+
GIN_MODE: release
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module github.com/nvoi/example-postgres
|
|
2
|
+
|
|
3
|
+
go 1.23
|
|
4
|
+
|
|
5
|
+
toolchain go1.24.4
|
|
6
|
+
|
|
7
|
+
require (
|
|
8
|
+
github.com/gin-gonic/gin v1.9.1
|
|
9
|
+
gorm.io/driver/postgres v1.5.4
|
|
10
|
+
gorm.io/gorm v1.25.5
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
require (
|
|
14
|
+
github.com/bytedance/sonic v1.9.1 // indirect
|
|
15
|
+
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
|
16
|
+
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
|
17
|
+
github.com/gin-contrib/sse v0.1.0 // indirect
|
|
18
|
+
github.com/go-playground/locales v0.14.1 // indirect
|
|
19
|
+
github.com/go-playground/universal-translator v0.18.1 // indirect
|
|
20
|
+
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
|
21
|
+
github.com/goccy/go-json v0.10.2 // indirect
|
|
22
|
+
github.com/jackc/pgpassfile v1.0.0 // indirect
|
|
23
|
+
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
|
24
|
+
github.com/jackc/pgx/v5 v5.4.3 // indirect
|
|
25
|
+
github.com/jinzhu/inflection v1.0.0 // indirect
|
|
26
|
+
github.com/jinzhu/now v1.1.5 // indirect
|
|
27
|
+
github.com/json-iterator/go v1.1.12 // indirect
|
|
28
|
+
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
|
29
|
+
github.com/kr/text v0.2.0 // indirect
|
|
30
|
+
github.com/leodido/go-urn v1.2.4 // indirect
|
|
31
|
+
github.com/mattn/go-isatty v0.0.19 // indirect
|
|
32
|
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
|
33
|
+
github.com/modern-go/reflect2 v1.0.2 // indirect
|
|
34
|
+
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
|
35
|
+
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
|
36
|
+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
|
37
|
+
github.com/ugorji/go/codec v1.2.11 // indirect
|
|
38
|
+
golang.org/x/arch v0.3.0 // indirect
|
|
39
|
+
golang.org/x/crypto v0.14.0 // indirect
|
|
40
|
+
golang.org/x/net v0.10.0 // indirect
|
|
41
|
+
golang.org/x/sys v0.26.0 // indirect
|
|
42
|
+
golang.org/x/text v0.13.0 // indirect
|
|
43
|
+
google.golang.org/protobuf v1.30.0 // indirect
|
|
44
|
+
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
45
|
+
)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
|
2
|
+
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
|
3
|
+
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
|
4
|
+
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
|
5
|
+
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
|
6
|
+
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
|
7
|
+
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
8
|
+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
9
|
+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
10
|
+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
11
|
+
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
|
12
|
+
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
|
13
|
+
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
|
14
|
+
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
|
15
|
+
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
|
16
|
+
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
|
17
|
+
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
|
18
|
+
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
|
19
|
+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
|
20
|
+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
|
21
|
+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
|
22
|
+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
|
23
|
+
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
|
24
|
+
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
|
25
|
+
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
|
26
|
+
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
|
27
|
+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
28
|
+
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
29
|
+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
30
|
+
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
|
31
|
+
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
|
32
|
+
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
|
33
|
+
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
|
34
|
+
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
|
35
|
+
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
|
|
36
|
+
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
|
37
|
+
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
|
38
|
+
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
|
39
|
+
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
|
40
|
+
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
|
41
|
+
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
|
42
|
+
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
|
43
|
+
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
|
44
|
+
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
|
45
|
+
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
|
46
|
+
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
|
47
|
+
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
|
48
|
+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|
49
|
+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|
50
|
+
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
|
51
|
+
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
|
52
|
+
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
|
53
|
+
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
54
|
+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
55
|
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
|
56
|
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
57
|
+
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
|
58
|
+
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
|
59
|
+
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
|
60
|
+
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
|
61
|
+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
62
|
+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
63
|
+
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
|
64
|
+
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
|
65
|
+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
66
|
+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
|
67
|
+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
68
|
+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
69
|
+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
70
|
+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
71
|
+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
72
|
+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
73
|
+
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
74
|
+
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
|
75
|
+
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
|
76
|
+
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
|
77
|
+
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
|
78
|
+
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
|
79
|
+
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
|
80
|
+
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
|
81
|
+
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
|
82
|
+
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
|
83
|
+
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
|
84
|
+
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
|
85
|
+
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
|
86
|
+
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|
87
|
+
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
88
|
+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
89
|
+
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
|
90
|
+
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
91
|
+
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
|
92
|
+
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|
93
|
+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
94
|
+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
95
|
+
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
96
|
+
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
|
97
|
+
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
98
|
+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
99
|
+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
|
100
|
+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
101
|
+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
102
|
+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
103
|
+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
104
|
+
gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo=
|
|
105
|
+
gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0=
|
|
106
|
+
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
|
107
|
+
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
|
108
|
+
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|