Our Personal Data Server from scratch! tranquil.farm
oauth atproto pds rust postgresql objectstorage fun

Container build should use all-in-one backend+frontend #39

merged opened by lewis.moe targeting main from fix/container-frontend-inside
Labels

None yet.

assignee
Participants 1
AT URI
at://did:plc:3fwecdnvtcscjnrx2p4n7alz/sh.tangled.repo.pull/3mgippndzu322
+110 -202
Diff #0
+6
Dockerfile
··· 1 FROM rust:1.92-alpine AS builder 2 RUN apk add --no-cache ca-certificates musl-dev pkgconfig openssl-dev openssl-libs-static 3 WORKDIR /app ··· 18 FROM alpine:3.23 19 RUN apk add --no-cache msmtp ca-certificates && ln -sf /usr/bin/msmtp /usr/sbin/sendmail 20 COPY --from=builder /tmp/tranquil-pds /usr/local/bin/tranquil-pds 21 COPY migrations /app/migrations 22 WORKDIR /app 23 ENV SERVER_HOST=0.0.0.0
··· 1 + FROM denoland/deno:alpine AS frontend 2 + WORKDIR /app 3 + COPY frontend/ ./ 4 + RUN deno task build 5 + 6 FROM rust:1.92-alpine AS builder 7 RUN apk add --no-cache ca-certificates musl-dev pkgconfig openssl-dev openssl-libs-static 8 WORKDIR /app ··· 23 FROM alpine:3.23 24 RUN apk add --no-cache msmtp ca-certificates && ln -sf /usr/bin/msmtp /usr/sbin/sendmail 25 COPY --from=builder /tmp/tranquil-pds /usr/local/bin/tranquil-pds 26 + COPY --from=frontend /app/dist /var/lib/tranquil-pds/frontend 27 COPY migrations /app/migrations 28 WORKDIR /app 29 ENV SERVER_HOST=0.0.0.0
+1 -21
docker-compose.prod.yaml
··· 27 reservations: 28 memory: 256M 29 30 - frontend: 31 - build: 32 - context: ./frontend 33 - dockerfile: Dockerfile 34 - image: tranquil-pds-frontend:latest 35 - restart: unless-stopped 36 - healthcheck: 37 - test: ["CMD", "wget", "-q", "--spider", "http://localhost:80/"] 38 - interval: 30s 39 - timeout: 10s 40 - retries: 3 41 - start_period: 5s 42 - deploy: 43 - resources: 44 - limits: 45 - memory: 128M 46 - reservations: 47 - memory: 32M 48 - 49 db: 50 image: postgres:18-alpine 51 restart: unless-stopped ··· 76 - "80:80" 77 - "443:443" 78 volumes: 79 - - ./nginx.frontend.conf:/etc/nginx/nginx.conf:ro 80 - ./certs:/etc/nginx/certs:ro 81 - acme_challenge:/var/www/acme:ro 82 depends_on: 83 - tranquil-pds 84 - - frontend 85 healthcheck: 86 test: ["CMD", "nginx", "-t"] 87 interval: 30s
··· 27 reservations: 28 memory: 256M 29 30 db: 31 image: postgres:18-alpine 32 restart: unless-stopped ··· 57 - "80:80" 58 - "443:443" 59 volumes: 60 + - ./nginx.conf:/etc/nginx/nginx.conf:ro 61 - ./certs:/etc/nginx/certs:ro 62 - acme_challenge:/var/www/acme:ro 63 depends_on: 64 - tranquil-pds 65 healthcheck: 66 test: ["CMD", "nginx", "-t"] 67 interval: 30s
+2 -2
docs/install-containers.md
··· 145 ## Create nginx configuration 146 147 ```bash 148 - cp /opt/tranquil-pds/nginx.frontend.conf /srv/tranquil-pds/config/nginx.conf 149 ``` 150 151 ## Clone and build images ··· 288 Copy the production compose and nginx configs: 289 ```sh 290 cp /opt/tranquil-pds/docker-compose.prod.yaml /srv/tranquil-pds/docker-compose.yml 291 - cp /opt/tranquil-pds/nginx.frontend.conf /srv/tranquil-pds/config/nginx.conf 292 ``` 293 294 Edit `/srv/tranquil-pds/docker-compose.yml` to adjust paths if needed:
··· 145 ## Create nginx configuration 146 147 ```bash 148 + cp /opt/tranquil-pds/nginx.conf /srv/tranquil-pds/config/nginx.conf 149 ``` 150 151 ## Clone and build images ··· 288 Copy the production compose and nginx configs: 289 ```sh 290 cp /opt/tranquil-pds/docker-compose.prod.yaml /srv/tranquil-pds/docker-compose.yml 291 + cp /opt/tranquil-pds/nginx.conf /srv/tranquil-pds/config/nginx.conf 292 ``` 293 294 Edit `/srv/tranquil-pds/docker-compose.yml` to adjust paths if needed:
+101
nginx.conf
···
··· 1 + worker_processes auto; 2 + error_log /var/log/nginx/error.log warn; 3 + pid /var/run/nginx.pid; 4 + 5 + events { 6 + worker_connections 4096; 7 + use epoll; 8 + multi_accept on; 9 + } 10 + 11 + http { 12 + include /etc/nginx/mime.types; 13 + default_type application/octet-stream; 14 + 15 + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 16 + '$status $body_bytes_sent "$http_referer" ' 17 + '"$http_user_agent" "$http_x_forwarded_for" ' 18 + 'rt=$request_time uct="$upstream_connect_time" ' 19 + 'uht="$upstream_header_time" urt="$upstream_response_time"'; 20 + 21 + access_log /var/log/nginx/access.log main; 22 + 23 + sendfile on; 24 + tcp_nopush on; 25 + tcp_nodelay on; 26 + keepalive_timeout 65; 27 + types_hash_max_size 2048; 28 + 29 + gzip on; 30 + gzip_vary on; 31 + gzip_proxied any; 32 + gzip_comp_level 6; 33 + gzip_types text/plain text/css text/xml application/json application/javascript 34 + application/xml application/xml+rss text/javascript application/activity+json; 35 + 36 + ssl_protocols TLSv1.2 TLSv1.3; 37 + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; 38 + ssl_prefer_server_ciphers off; 39 + ssl_session_cache shared:SSL:10m; 40 + ssl_session_timeout 1d; 41 + ssl_session_tickets off; 42 + ssl_stapling on; 43 + ssl_stapling_verify on; 44 + 45 + upstream pds { 46 + server tranquil-pds:3000; 47 + keepalive 32; 48 + } 49 + 50 + server { 51 + listen 80; 52 + listen [::]:80; 53 + server_name _; 54 + 55 + location /.well-known/acme-challenge/ { 56 + root /var/www/acme; 57 + } 58 + 59 + location / { 60 + return 301 https://$host$request_uri; 61 + } 62 + } 63 + 64 + server { 65 + listen 443 ssl; 66 + listen [::]:443 ssl; 67 + http2 on; 68 + server_name _; 69 + 70 + ssl_certificate /etc/nginx/certs/fullchain.pem; 71 + ssl_certificate_key /etc/nginx/certs/privkey.pem; 72 + 73 + client_max_body_size 10G; 74 + 75 + proxy_http_version 1.1; 76 + proxy_set_header Host $host; 77 + proxy_set_header X-Real-IP $remote_addr; 78 + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 79 + proxy_set_header X-Forwarded-Proto $scheme; 80 + 81 + location /xrpc/ { 82 + proxy_pass http://pds; 83 + proxy_set_header Upgrade $http_upgrade; 84 + proxy_set_header Connection "upgrade"; 85 + proxy_read_timeout 86400; 86 + proxy_send_timeout 86400; 87 + proxy_buffering off; 88 + proxy_request_buffering off; 89 + } 90 + 91 + location /oauth/ { 92 + proxy_pass http://pds; 93 + proxy_read_timeout 300; 94 + proxy_send_timeout 300; 95 + } 96 + 97 + location / { 98 + proxy_pass http://pds; 99 + } 100 + } 101 + }
-179
nginx.frontend.conf
··· 1 - worker_processes auto; 2 - error_log /var/log/nginx/error.log warn; 3 - pid /var/run/nginx.pid; 4 - 5 - events { 6 - worker_connections 4096; 7 - use epoll; 8 - multi_accept on; 9 - } 10 - 11 - http { 12 - include /etc/nginx/mime.types; 13 - default_type application/octet-stream; 14 - 15 - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 16 - '$status $body_bytes_sent "$http_referer" ' 17 - '"$http_user_agent" "$http_x_forwarded_for" ' 18 - 'rt=$request_time uct="$upstream_connect_time" ' 19 - 'uht="$upstream_header_time" urt="$upstream_response_time"'; 20 - 21 - access_log /var/log/nginx/access.log main; 22 - 23 - sendfile on; 24 - tcp_nopush on; 25 - tcp_nodelay on; 26 - keepalive_timeout 65; 27 - types_hash_max_size 2048; 28 - 29 - gzip on; 30 - gzip_vary on; 31 - gzip_proxied any; 32 - gzip_comp_level 6; 33 - gzip_types text/plain text/css text/xml application/json application/javascript 34 - application/xml application/xml+rss text/javascript application/activity+json; 35 - 36 - ssl_protocols TLSv1.2 TLSv1.3; 37 - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; 38 - ssl_prefer_server_ciphers off; 39 - ssl_session_cache shared:SSL:10m; 40 - ssl_session_timeout 1d; 41 - ssl_session_tickets off; 42 - ssl_stapling on; 43 - ssl_stapling_verify on; 44 - 45 - upstream backend { 46 - server tranquil-pds:3000; 47 - keepalive 32; 48 - } 49 - 50 - upstream frontend { 51 - server frontend:80; 52 - keepalive 16; 53 - } 54 - 55 - server { 56 - listen 80; 57 - listen [::]:80; 58 - server_name _; 59 - 60 - location /.well-known/acme-challenge/ { 61 - root /var/www/acme; 62 - } 63 - 64 - location / { 65 - return 301 https://$host$request_uri; 66 - } 67 - } 68 - 69 - server { 70 - listen 443 ssl; 71 - listen [::]:443 ssl; 72 - http2 on; 73 - server_name _; 74 - 75 - ssl_certificate /etc/nginx/certs/fullchain.pem; 76 - ssl_certificate_key /etc/nginx/certs/privkey.pem; 77 - 78 - client_max_body_size 10G; 79 - 80 - location /xrpc/ { 81 - proxy_pass http://backend; 82 - proxy_http_version 1.1; 83 - proxy_set_header Upgrade $http_upgrade; 84 - proxy_set_header Connection "upgrade"; 85 - proxy_set_header Host $host; 86 - proxy_set_header X-Real-IP $remote_addr; 87 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 88 - proxy_set_header X-Forwarded-Proto $scheme; 89 - proxy_read_timeout 86400; 90 - proxy_send_timeout 86400; 91 - proxy_buffering off; 92 - proxy_request_buffering off; 93 - } 94 - 95 - location = /oauth-client-metadata.json { 96 - proxy_pass http://frontend; 97 - proxy_http_version 1.1; 98 - proxy_set_header Host $host; 99 - proxy_set_header Accept-Encoding ""; 100 - sub_filter_once off; 101 - sub_filter_types application/json; 102 - sub_filter '__FRONTEND_HOSTNAME__' $host; 103 - } 104 - 105 - location /oauth/ { 106 - proxy_pass http://backend; 107 - proxy_http_version 1.1; 108 - proxy_set_header Host $host; 109 - proxy_set_header X-Real-IP $remote_addr; 110 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 111 - proxy_set_header X-Forwarded-Proto $scheme; 112 - proxy_read_timeout 300; 113 - proxy_send_timeout 300; 114 - } 115 - 116 - location /.well-known/ { 117 - proxy_pass http://backend; 118 - proxy_http_version 1.1; 119 - proxy_set_header Host $host; 120 - proxy_set_header X-Real-IP $remote_addr; 121 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 122 - proxy_set_header X-Forwarded-Proto $scheme; 123 - } 124 - 125 - location /webhook/ { 126 - proxy_pass http://backend; 127 - proxy_http_version 1.1; 128 - proxy_set_header Host $host; 129 - proxy_set_header X-Real-IP $remote_addr; 130 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 131 - proxy_set_header X-Forwarded-Proto $scheme; 132 - } 133 - 134 - location = /metrics { 135 - proxy_pass http://backend; 136 - proxy_http_version 1.1; 137 - proxy_set_header Host $host; 138 - proxy_set_header X-Real-IP $remote_addr; 139 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 140 - proxy_set_header X-Forwarded-Proto $scheme; 141 - } 142 - 143 - location = /health { 144 - proxy_pass http://backend; 145 - proxy_http_version 1.1; 146 - proxy_set_header Host $host; 147 - } 148 - 149 - location = /robots.txt { 150 - proxy_pass http://backend; 151 - proxy_http_version 1.1; 152 - proxy_set_header Host $host; 153 - } 154 - 155 - location = /logo { 156 - proxy_pass http://backend; 157 - proxy_http_version 1.1; 158 - proxy_set_header Host $host; 159 - } 160 - 161 - location ~ ^/u/[^/]+/did\.json$ { 162 - proxy_pass http://backend; 163 - proxy_http_version 1.1; 164 - proxy_set_header Host $host; 165 - proxy_set_header X-Real-IP $remote_addr; 166 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 167 - proxy_set_header X-Forwarded-Proto $scheme; 168 - } 169 - 170 - location / { 171 - proxy_pass http://frontend; 172 - proxy_http_version 1.1; 173 - proxy_set_header Host $host; 174 - proxy_set_header X-Real-IP $remote_addr; 175 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 176 - proxy_set_header X-Forwarded-Proto $scheme; 177 - } 178 - } 179 - }
···

History

1 round 0 comments
sign up or login to add to the discussion
lewis.moe submitted #0
1 commit
expand
fix: container build should use all-in-one backend+frontend
expand 0 comments
pull request successfully merged