| 1 | import { |
| 2 | bucket, |
| 3 | defineRailway, |
| 4 | github, |
| 5 | image, |
| 6 | postgres, |
| 7 | preserve, |
| 8 | project, |
| 9 | service, |
| 10 | volume, |
| 11 | } from "railway/iac"; |
| 12 | |
| 13 | export default defineRailway(() |
| 14 | const ghost = |
| 15 | |
| 16 | const postgresDatabase = |
| 17 | region: "asia-southeast1-eqsg3a", |
| 18 | }); |
| 19 | postgresDatabase.networking = |
| 20 | const postgresVolumeUO8m = |
| 21 | alerts: { usage: { |
| 22 | allowOnlineResize: true, |
| 23 | region: "asia-southeast1-eqsg3a", |
| 24 | sizeMB: 5000, |
| 25 | }); |
| 26 | const ghostBucket = |
| 27 | const web = |
| 28 | source: ghost, |
| 29 | build: { |
| 30 | buildEnvironment: "V3", |
| 31 | builder: "DOCKERFILE", |
| 32 | dockerfilePath: "/apps/web/Dockerfile", |
| 33 | watchPatterns: ["/apps/web/**"], |
| 34 | }, |
| 35 | replicas: { "asia-southeast1-eqsg3a": |
| 36 | deploy: { sleepApplication: true |
| 37 | domains: ["web.ghost.procrastinator.fyi"], |
| 38 | env: { |
| 39 | NEXT_PUBLIC_API_URL: preserve(), |
| 40 | NEXT_PUBLIC_DOCS_URL: preserve(), |
| 41 | NEXT_PUBLIC_SITE_URL: preserve(), |
| 42 | NEXT_PUBLIC_SSH_CLONE_HOST: preserve(), |
| 43 | NEXT_PUBLIC_GITHUB_CLIENT_ID: preserve(), |
| 44 | OTEL_EXPORTER_OTLP_ENDPOINT: preserve(), |
| 45 | }, |
| 46 | }); |
| 47 | const docs = |
| 48 | source: ghost, |
| 49 | build: { |
| 50 | buildEnvironment: "V3", |
| 51 | builder: "DOCKERFILE", |
| 52 | dockerfilePath: "/apps/docs/Dockerfile", |
| 53 | watchPatterns: ["/apps/docs/**"], |
| 54 | }, |
| 55 | replicas: { "asia-southeast1-eqsg3a": |
| 56 | deploy: { sleepApplication: true |
| 57 | domains: ["docs.ghost.procrastinator.fyi"], |
| 58 | env: { |
| 59 | NEXT_PUBLIC_DOCS_URL: preserve(), |
| 60 | NEXT_PUBLIC_WEB_APP_URL: preserve(), |
| 61 | }, |
| 62 | }); |
| 63 | const api = |
| 64 | source: ghost, |
| 65 | build: { |
| 66 | buildEnvironment: "V3", |
| 67 | builder: "DOCKERFILE", |
| 68 | dockerfilePath: "apps/api/Dockerfile", |
| 69 | watchPatterns: ["/apps/api/**"], |
| 70 | }, |
| 71 | healthcheck: "/api", |
| 72 | healthcheckTimeout: 60, |
| 73 | preDeploy: "node packages/db/dist/migrate.js", |
| 74 | replicas: { "asia-southeast1-eqsg3a": |
| 75 | deploy: { restartPolicyMaxRetries: 5 |
| 76 | domains: ["api.ghost.procrastinator.fyi"], |
| 77 | networking: { tcpProxies: { |
| 78 | env: { |
| 79 | AUTH_COOKIE_DOMAIN: preserve(), |
| 80 | AUTH_TRUSTED_ORIGINS: preserve(), |
| 81 | BETTER_AUTH_SECRET: preserve(), |
| 82 | COMMIT_SIGNING_KEY: preserve(), |
| 83 | BETTER_AUTH_URL: preserve(), |
| 84 | DATABASE_URL: preserve(), |
| 85 | EMAIL_PROXY: preserve(), |
| 86 | EMAIL_PROXY_SECRET: preserve(), |
| 87 | EMAIL_SENDER: preserve(), |
| 88 | EMAIL_VERIFICATION_ENABLED: preserve(), |
| 89 | GIT_SSH_HOST_KEY: preserve(), |
| 90 | GIT_SSH_PORT: preserve(), |
| 91 | PORT: preserve(), |
| 92 | S3_ACCESS_KEY_ID: preserve(), |
| 93 | S3_BUCKET: preserve(), |
| 94 | S3_ENDPOINT: preserve(), |
| 95 | S3_SECRET_ACCESS_KEY: preserve(), |
| 96 | WEBHOOK_ALLOW_PRIVATE_NETWORKS: preserve(), |
| 97 | WEBHOOK_SECRET_KEY: preserve(), |
| 98 | WEB_APP_URL: preserve(), |
| 99 | ZOEKT_URL: preserve(), |
| 100 | ZOEKT_URL_BASE: preserve(), |
| 101 | }, |
| 102 | }); |
| 103 | const delivery = |
| 104 | source: ghost, |
| 105 | build: { |
| 106 | buildEnvironment: "V3", |
| 107 | builder: "DOCKERFILE", |
| 108 | dockerfilePath: "/apps/delivery/Dockerfile", |
| 109 | watchPatterns: ["/apps/delivery/**"], |
| 110 | }, |
| 111 | replicas: { "asia-southeast1-eqsg3a": |
| 112 | env: { |
| 113 | DATABASE_URL: preserve(), |
| 114 | EMAIL_PROXY: preserve(), |
| 115 | EMAIL_PROXY_SECRET: preserve(), |
| 116 | WEBHOOK_ALLOW_PRIVATE_NETWORKS: preserve(), |
| 117 | WEBHOOK_SECRET_KEY: preserve(), |
| 118 | }, |
| 119 | }); |
| 120 | const zoekt = |
| 121 | source: ghost, |
| 122 | build: { |
| 123 | buildEnvironment: "V3", |
| 124 | builder: "DOCKERFILE", |
| 125 | dockerfilePath: "/apps/zoekt/Dockerfile", |
| 126 | watchPatterns: ["/apps/zoekt/**"], |
| 127 | }, |
| 128 | healthcheck: "/healthz", |
| 129 | replicas: { "asia-southeast1-eqsg3a": |
| 130 | env: { |
| 131 | S3_ACCESS_KEY_ID: preserve(), |
| 132 | S3_BUCKET: preserve(), |
| 133 | S3_ENDPOINT: preserve(), |
| 134 | S3_SECRET_ACCESS_KEY: preserve(), |
| 135 | }, |
| 136 | }); |
| 137 | const otelLgtm = |
| 138 | source: image("grafana/otel-lgtm |
| 139 | replicas: { "asia-southeast1-eqsg3a": |
| 140 | deploy: { sleepApplication: true |
| 141 | env: { |
| 142 | GF_SECURITY_ADMIN_PASSWORD: preserve(), |
| 143 | GF_SECURITY_ADMIN_USER: preserve(), |
| 144 | }, |
| 145 | }); |
| 146 | |
| 147 | return project("Ghost |
| 148 | resources: [ |
| 149 | web, |
| 150 | docs, |
| 151 | api, |
| 152 | postgresDatabase, |
| 153 | delivery, |
| 154 | zoekt, |
| 155 | otelLgtm, |
| 156 | postgresVolumeUO8m, |
| 157 | ghostBucket, |
| 158 | ], |
| 159 | }); |
| 160 | }); |