Skip to content

Commit a4e3d30

Browse files
committed
Add Dockerfile and generate static redirects for nginx
1 parent 3a8f333 commit a4e3d30

6 files changed

Lines changed: 137 additions & 50 deletions

File tree

.dockerignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
**/.dockerignore
2+
**/.env
3+
**/.git
4+
**/.gitignore
5+
**/.project
6+
**/.settings
7+
**/.toolstarget
8+
**/.vs
9+
**/.vscode
10+
**/.idea
11+
**/*.*proj.user
12+
**/*.dbmdl
13+
**/*.jfm
14+
**/azds.yaml
15+
**/bin
16+
**/node_modules
17+
**/npm-debug.log
18+
**/obj
19+
**/secrets.dev.yaml
20+
**/values.dev.yaml
21+
22+
**/.devcontainer
23+
**/.fleet
24+
**/.husky
25+
**/.run
26+
**/.space
27+
**/dist
28+
docker-compose*.yml
29+
Dockerfile*
30+
LICENSE
31+
LICENSE-CODE
32+
README.md
33+
redirect.conf

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM node:22-alpine AS builder
2+
EXPOSE 80
3+
4+
WORKDIR /app
5+
COPY package.json package-lock.json ./
6+
RUN npm install --no-cache
7+
COPY . .
8+
RUN ./build.sh
9+
10+
11+
FROM nginx:stable-alpine AS final
12+
13+
COPY deployment/nginx.conf /etc/nginx/nginx.conf
14+
COPY deployment/default.conf /etc/nginx/conf.d/default.conf
15+
COPY --from=builder --chown=nginx:nginx /app/root/redirect.conf /etc/nginx/extra/redirect.conf
16+
17+
RUN rm -rf /usr/share/nginx/html/*
18+
COPY --from=builder --chown=nginx:nginx /app/root/ /usr/share/nginx/html/
19+
RUN rm -rf /usr/share/nginx/html/redirect.conf
20+
21+
RUN mkdir -p /var/cache/nginx
22+
23+
RUN chown -R nginx:nginx /var/cache/nginx
24+
RUN touch /var/run/nginx.pid && \
25+
chown -R nginx:nginx /var/run/nginx.pid
26+
27+
USER nginx
28+
29+
WORKDIR /usr/share/nginx/html

deployment/default.conf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
server {
2+
listen 80;
3+
listen [::]:80;
4+
server_name localhost;
5+
location / {
6+
root /usr/share/nginx/html;
7+
index index.html index.htm;
8+
}
9+
include /etc/nginx/extra/*.conf;
10+
11+
error_page 404 /404.html;
12+
location = /404.html {
13+
root /usr/share/nginx/html;
14+
}
15+
16+
error_page 500 502 503 504 /50x.html;
17+
location = /50x.html {
18+
root /usr/share/nginx/html;
19+
}
20+
}

deployment/nginx.conf

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
user nginx;
2+
worker_processes auto;
3+
4+
error_log /var/log/nginx/error.log notice;
5+
pid /var/run/nginx.pid;
6+
7+
8+
events {
9+
worker_connections 1024;
10+
}
11+
12+
13+
http {
14+
include /etc/nginx/mime.types;
15+
default_type application/octet-stream;
16+
17+
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
18+
'$status $body_bytes_sent "$http_referer" '
19+
'"$http_user_agent" "$http_x_forwarded_for"';
20+
21+
access_log /var/log/nginx/access.log main;
22+
23+
sendfile on;
24+
#tcp_nopush on;
25+
26+
keepalive_timeout 65;
27+
28+
gzip on;
29+
30+
include /etc/nginx/conf.d/*.conf;
31+
}

src/plugins/static-redirects.ts

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,21 @@ import type { AstroConfig, AstroIntegrationLogger } from "astro";
33
import path from "node:path";
44
import fs from "node:fs/promises";
55

6-
let configJson = { routes: [] };
6+
function createNginxRule(redirectFrom: string, redirectTo: string) {
7+
if (redirectFrom.endsWith("/")) {
8+
redirectFrom = redirectFrom.slice(0, -1);
9+
}
10+
11+
return (
12+
"rewrite ^" +
13+
redirectFrom +
14+
"(/?)$ $scheme://$http_host" +
15+
redirectTo +
16+
"/ permanent;\n"
17+
);
18+
}
19+
20+
let nginxRedirectRules = "";
721

822
export async function configurePlugin(hookOptions: any) {
923
const buildOutput: string = hookOptions.buildOutput;
@@ -12,61 +26,27 @@ export async function configurePlugin(hookOptions: any) {
1226

1327
if (buildOutput !== "static") {
1428
logger.warn(
15-
`Skip generating static redirects file: not compatible with '${buildOutput}' builds, only 'static' is supported.`,
29+
`Skip generating static redirects: not compatible with '${buildOutput}' builds, only 'static' is supported.`,
1630
);
1731
return;
1832
}
1933

2034
// Find redirects
2135
const redirects = config.redirects;
2236
if (!Object.keys(redirects).length) {
23-
logger.warn("Skip generating static redirects file: no redirects found.");
37+
logger.warn("Skip generating static redirects: no redirects found.");
2438
return;
2539
}
2640

27-
// Load existing staticwebapp.config.json
28-
const configSourcePath = path.join(
29-
url.fileURLToPath(config.srcDir),
30-
"staticwebapp.config.json",
31-
);
32-
33-
try {
34-
configJson = JSON.parse(
35-
await fs.readFile(configSourcePath, {
36-
encoding: "utf-8",
37-
}),
38-
);
39-
40-
if (!configJson.routes) {
41-
configJson.routes = [];
42-
}
43-
} catch {
44-
logger.debug(
45-
`Skip load existing config file: '${configSourcePath}' not found.`,
46-
);
47-
}
48-
4941
// Add redirects
5042
logger.info("Generating static redirects file...");
5143
Object.keys(redirects).forEach((from) => {
5244
const redirect = redirects[from];
5345

5446
if (typeof redirect === "string") {
55-
// @ts-ignore
56-
configJson.routes.push({
57-
route: from,
58-
methods: ["GET"],
59-
redirect: redirect,
60-
statusCode: 301,
61-
});
47+
nginxRedirectRules += createNginxRule(from, redirect);
6248
} else {
63-
// @ts-ignore
64-
configJson.routes.push({
65-
route: from,
66-
methods: ["GET"],
67-
redirect: redirect.destination,
68-
statusCode: redirect.status,
69-
});
49+
nginxRedirectRules += createNginxRule(from, redirect.destination);
7050
}
7151
});
7252
}
@@ -75,25 +55,20 @@ export async function writeToOutput(hookOptions: any) {
7555
const outDir: string = hookOptions.dir;
7656
const logger: AstroIntegrationLogger = hookOptions.logger;
7757

78-
if (!configJson || !configJson.routes.length) {
58+
if (!nginxRedirectRules || !nginxRedirectRules.length) {
7959
logger.warn(
8060
`Skip generating static redirects file: no redirects were generated.`,
8161
);
8262
return;
8363
}
8464

85-
// Write staticwebapp.config.json
65+
// Write redirect.conf
8666
const configDestinationPath = path.join(
8767
url.fileURLToPath(outDir),
88-
"staticwebapp.config.json",
89-
);
90-
await fs.writeFile(
91-
configDestinationPath,
92-
JSON.stringify(configJson, null, 2),
93-
);
94-
logger.info(
95-
`Generated static redirects file: ${configDestinationPath} (${configJson.routes.length} redirects)`,
68+
"redirect.conf",
9669
);
70+
await fs.writeFile(configDestinationPath, nginxRedirectRules);
71+
logger.info(`Generated static redirects file: ${configDestinationPath}`);
9772
}
9873

9974
export default function staticRedirects() {

src/staticwebapp.config.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)