feat: configure dedicated server proxy
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
e787359c54
commit
a86a0cb539
8 changed files with 91 additions and 91 deletions
16
.github/workflows/deploy-rancher.yml
vendored
16
.github/workflows/deploy-rancher.yml
vendored
|
|
@ -43,9 +43,7 @@ jobs:
|
|||
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
JWT_SECRET: ${{ secrets.GO_GUESS_JWT_SECRET }}
|
||||
GO_GUESS_HOST: ${{ vars.GO_GUESS_HOST }}
|
||||
GO_GUESS_FRONTEND_URL: ${{ vars.GO_GUESS_FRONTEND_URL }}
|
||||
GO_GUESS_TLS_SECRET: ${{ vars.GO_GUESS_TLS_SECRET }}
|
||||
RANCHER_NAMESPACE: ${{ vars.RANCHER_NAMESPACE }}
|
||||
|
||||
steps:
|
||||
|
|
@ -82,10 +80,6 @@ jobs:
|
|||
echo "GO_GUESS_JWT_SECRET must contain at least 32 characters" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$TARGET_ENVIRONMENT" = "production" ] && [ -z "$GO_GUESS_HOST" ]; then
|
||||
echo "GO_GUESS_HOST is required for production" >&2
|
||||
exit 1
|
||||
fi
|
||||
namespace="${RANCHER_NAMESPACE:-go-guess-$TARGET_ENVIRONMENT}"
|
||||
if [ -n "$PUBLISHED_SHA" ]; then
|
||||
image_tag="$PUBLISHED_SHA"
|
||||
|
|
@ -94,7 +88,7 @@ jobs:
|
|||
fi
|
||||
frontend_url="$GO_GUESS_FRONTEND_URL"
|
||||
if [ "$TARGET_ENVIRONMENT" = "production" ] && [ -z "$frontend_url" ]; then
|
||||
frontend_url="https://$GO_GUESS_HOST"
|
||||
frontend_url="https://goguess.urpi.be"
|
||||
fi
|
||||
{
|
||||
echo "DEPLOY_NAMESPACE=$namespace"
|
||||
|
|
@ -130,14 +124,6 @@ jobs:
|
|||
if [ -n "$RESOLVED_FRONTEND_URL" ]; then
|
||||
set -- "$@" --set-string "app.frontendURL=$RESOLVED_FRONTEND_URL"
|
||||
fi
|
||||
if [ "$TARGET_ENVIRONMENT" = "production" ]; then
|
||||
set -- "$@" --set-string "ingress.hosts[0].host=$GO_GUESS_HOST"
|
||||
if [ -n "$GO_GUESS_TLS_SECRET" ]; then
|
||||
set -- "$@" \
|
||||
--set-string "ingress.tls[0].secretName=$GO_GUESS_TLS_SECRET" \
|
||||
--set-string "ingress.tls[0].hosts[0]=$GO_GUESS_HOST"
|
||||
fi
|
||||
fi
|
||||
helm upgrade --install go-guess deploy/helm/go-guess \
|
||||
--namespace "$DEPLOY_NAMESPACE" \
|
||||
--values "$values_file" \
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,3 +6,4 @@ frontend/dist/
|
|||
frontend/coverage/
|
||||
bdd/node_modules/
|
||||
bdd/reports/
|
||||
deploy/local.yaml
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -128,11 +128,11 @@ make helm-deploy-production
|
|||
|
||||
Development uses demo fixtures, ephemeral database and message-broker storage,
|
||||
and NodePort `30080`. Production uses production fixtures, persistent volumes,
|
||||
an Nginx ingress, generated secrets that are preserved across upgrades, and
|
||||
larger resource limits. Before production deployment, replace
|
||||
`go-guess.example.com` in `values-production.yaml` or override
|
||||
`app.frontendURL` and `ingress.hosts[0].host`. Configure a TLS entry under
|
||||
`ingress.tls` when the Rancher cluster does not provide TLS separately.
|
||||
generated secrets that are preserved across upgrades, and larger resource
|
||||
limits. It exposes the application at NodePort `31374` for the dedicated-server
|
||||
Nginx proxy while PostgreSQL and RabbitMQ remain cluster-internal. The public
|
||||
URL is `https://goguess.urpi.be`; one.com DNS, Nginx, Certbot, firewall, and
|
||||
verification instructions are in `deploy/nginx/README.md`.
|
||||
|
||||
To use external managed services, disable the bundled StatefulSets and provide
|
||||
full connection URLs:
|
||||
|
|
@ -157,8 +157,8 @@ workflow succeeds. Create GitHub environments named `development` and
|
|||
- Secrets `REGISTRY_USERNAME`, `REGISTRY_PASSWORD`, and
|
||||
`GO_GUESS_JWT_SECRET`.
|
||||
- Variable `RANCHER_NAMESPACE` for the target namespace.
|
||||
- Production variable `GO_GUESS_HOST`, plus optional
|
||||
`GO_GUESS_FRONTEND_URL` and `GO_GUESS_TLS_SECRET`.
|
||||
- Optional variable `GO_GUESS_FRONTEND_URL` when overriding an environment's
|
||||
configured public URL.
|
||||
|
||||
Because the configured image registry uses HTTP, every Rancher cluster node must
|
||||
trust `batty1039.startdedicated.net:5000` as an insecure registry. Use HTTPS for
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ Go Guess has been installed in namespace {{ .Release.Namespace }}.
|
|||
{{- if .Values.ingress.enabled }}
|
||||
Open {{ .Values.app.frontendURL }}
|
||||
{{- else if eq .Values.service.type "NodePort" }}
|
||||
Open a cluster node on port {{ .Values.service.nodePort }}.
|
||||
The application is exposed on cluster node port {{ .Values.service.nodePort }}.
|
||||
Open {{ .Values.app.frontendURL }} through the external reverse proxy.
|
||||
{{- else }}
|
||||
Run:
|
||||
kubectl -n {{ .Release.Namespace }} port-forward service/{{ include "go-guess.fullname" . }} 8080:{{ .Values.service.port }}
|
||||
|
|
|
|||
|
|
@ -4,23 +4,14 @@ image:
|
|||
|
||||
app:
|
||||
environment: production
|
||||
frontendURL: https://go-guess.example.com
|
||||
frontendURL: https://goguess.urpi.be
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
type: NodePort
|
||||
nodePort: 31374
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 10m
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
hosts:
|
||||
- host: go-guess.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls: []
|
||||
enabled: false
|
||||
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
# Generated by Rancher
|
||||
# name: kubeconfig-ldfvp
|
||||
# createdTimestamp: 2026-09-20T09:13:04Z
|
||||
# ttl: 2592000
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
clusters:
|
||||
- name: "rancher"
|
||||
cluster:
|
||||
server: "https://rancher.urpi.be"
|
||||
certificate-authority-data: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ2VENDQ\
|
||||
VdPZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQkdNUnd3R2dZRFZRUUtFeE5rZVc1aGJXbGoKY\
|
||||
kdsemRHVnVaWEl0YjNKbk1TWXdKQVlEVlFRRERCMWtlVzVoYldsamJHbHpkR1Z1WlhJdFkyRkFNV\
|
||||
GM0T1RnNQpNVGczTURBZUZ3MHlOakE1TWpBd056RXhNVEJhRncwek5qQTVNVGN3TnpFeE1UQmFNR\
|
||||
Vl4SERBYUJnTlZCQW9UCkUyUjVibUZ0YVdOc2FYTjBaVzVsY2kxdmNtY3hKakFrQmdOVkJBTU1IV\
|
||||
1I1Ym1GdGFXTnNhWE4wWlc1bGNpMWoKWVVBeE56ZzVPRGt4T0Rjd01Ga3dFd1lIS29aSXpqMENBU\
|
||||
VlJS29aSXpqMERBUWNEUWdBRXNIVEFSdUJJcjNZQQo0NlVzRmM5N1lkRHd1eGtnNHNSU21ML3ZCS\
|
||||
Th3dWh5Z2M4Wm1jVUI4VWhWbUZvdEd4UnFqR3dWNG1GYXlxdGdQCmNnQVZmdkJ4bUtOQ01FQXdEZ\
|
||||
1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWUQKVlIwT0JCWUVGT\
|
||||
kNyVndRcjFXeWFpdnJMS1BLZ0hmbUVjRUFyTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFERAorU\
|
||||
2lMaXdOODFNU2FEOWEzaStUNkJGOHVjdXNKQm5xM2pJdHV4WGpFMlFJZ1Z5L3FNaEtRSFRIa3pzV\
|
||||
jIwWThBCll5SWdTWWZ1czZkaFdwNEI5TFl2eEVzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t"
|
||||
- name: "local"
|
||||
cluster:
|
||||
server: "https://rancher.urpi.be/k8s/clusters/local"
|
||||
certificate-authority-data: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ2VENDQ\
|
||||
VdPZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQkdNUnd3R2dZRFZRUUtFeE5rZVc1aGJXbGoKY\
|
||||
kdsemRHVnVaWEl0YjNKbk1TWXdKQVlEVlFRRERCMWtlVzVoYldsamJHbHpkR1Z1WlhJdFkyRkFNV\
|
||||
GM0T1RnNQpNVGczTURBZUZ3MHlOakE1TWpBd056RXhNVEJhRncwek5qQTVNVGN3TnpFeE1UQmFNR\
|
||||
Vl4SERBYUJnTlZCQW9UCkUyUjVibUZ0YVdOc2FYTjBaVzVsY2kxdmNtY3hKakFrQmdOVkJBTU1IV\
|
||||
1I1Ym1GdGFXTnNhWE4wWlc1bGNpMWoKWVVBeE56ZzVPRGt4T0Rjd01Ga3dFd1lIS29aSXpqMENBU\
|
||||
VlJS29aSXpqMERBUWNEUWdBRXNIVEFSdUJJcjNZQQo0NlVzRmM5N1lkRHd1eGtnNHNSU21ML3ZCS\
|
||||
Th3dWh5Z2M4Wm1jVUI4VWhWbUZvdEd4UnFqR3dWNG1GYXlxdGdQCmNnQVZmdkJ4bUtOQ01FQXdEZ\
|
||||
1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWUQKVlIwT0JCWUVGT\
|
||||
kNyVndRcjFXeWFpdnJMS1BLZ0hmbUVjRUFyTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFERAorU\
|
||||
2lMaXdOODFNU2FEOWEzaStUNkJGOHVjdXNKQm5xM2pJdHV4WGpFMlFJZ1Z5L3FNaEtRSFRIa3pzV\
|
||||
jIwWThBCll5SWdTWWZ1czZkaFdwNEI5TFl2eEVzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t"
|
||||
|
||||
users:
|
||||
- name: "rancher"
|
||||
user:
|
||||
token: "ext/token-9fzp2:d729wqhv4gbjhd9qjghs74f7h6wqcmml9c79stw8bw5nj2w9p752nw"
|
||||
|
||||
|
||||
contexts:
|
||||
- name: "rancher"
|
||||
context:
|
||||
user: "rancher"
|
||||
cluster: "rancher"
|
||||
- name: "local"
|
||||
context:
|
||||
user: "rancher"
|
||||
cluster: "local"
|
||||
|
||||
current-context: "local"
|
||||
55
deploy/nginx/README.md
Normal file
55
deploy/nginx/README.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Dedicated-server reverse proxy
|
||||
|
||||
Production exposes only the Go Guess application through Kubernetes NodePort
|
||||
`31374`. PostgreSQL and RabbitMQ remain available only through their
|
||||
cluster-internal services.
|
||||
|
||||
## DNS
|
||||
|
||||
In one.com, create an `A` record for `goguess.urpi.be` pointing to the dedicated
|
||||
server's public IPv4 address. Add an `AAAA` record only when the server and its
|
||||
firewall are configured for public IPv6. Wait for:
|
||||
|
||||
```bash
|
||||
dig +short goguess.urpi.be
|
||||
```
|
||||
|
||||
to return the dedicated server address before requesting a certificate.
|
||||
|
||||
## Nginx and Certbot
|
||||
|
||||
The included virtual host assumes Nginx runs on the Kubernetes node and can
|
||||
reach the NodePort at `127.0.0.1:31374`.
|
||||
|
||||
```bash
|
||||
sudo install -m 0644 deploy/nginx/goguess.urpi.be.conf \
|
||||
/etc/nginx/sites-available/goguess.urpi.be.conf
|
||||
sudo ln -s /etc/nginx/sites-available/goguess.urpi.be.conf \
|
||||
/etc/nginx/sites-enabled/goguess.urpi.be.conf
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
sudo certbot --nginx -d goguess.urpi.be
|
||||
sudo certbot renew --dry-run
|
||||
```
|
||||
|
||||
Certbot adds the HTTPS listener, certificate paths, and HTTP-to-HTTPS redirect
|
||||
to this virtual host. Allow inbound TCP ports `80` and `443`. Do not expose
|
||||
NodePort `31374`, PostgreSQL `5432`, RabbitMQ `5672`, or RabbitMQ management
|
||||
ports to the public internet. If Nginx is not on a Kubernetes node, replace
|
||||
`127.0.0.1` in `proxy_pass` with a private cluster-node address and allow
|
||||
`31374` only from the Nginx server.
|
||||
|
||||
## Deploy and verify
|
||||
|
||||
Deploy the production profile:
|
||||
|
||||
```bash
|
||||
make helm-deploy-production
|
||||
kubectl -n go-guess-production get pods
|
||||
kubectl -n go-guess-production get service go-guess
|
||||
curl --fail http://127.0.0.1:31374/api/health
|
||||
curl --fail https://goguess.urpi.be/api/health
|
||||
```
|
||||
|
||||
The `go-guess` service should show `80:31374/TCP`. The PostgreSQL and RabbitMQ
|
||||
services should remain `ClusterIP` services without NodePorts.
|
||||
21
deploy/nginx/goguess.urpi.be.conf
Normal file
21
deploy/nginx/goguess.urpi.be.conf
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name goguess.urpi.be;
|
||||
|
||||
client_max_body_size 10m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:31374;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue