chore: add Docker deployment behind Caddy
Build the static Next.js export in a reproducible container and expose it through the existing Caddy network and upstream service name.
This commit is contained in:
15
.dockerignore
Normal file
15
.dockerignore
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
Dockerfile*
|
||||||
|
compose*.yaml
|
||||||
|
compose*.yml
|
||||||
23
DEPLOYMENT.md
Normal file
23
DEPLOYMENT.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Deployment
|
||||||
|
|
||||||
|
This project builds the Next.js static export in a Node container and serves the
|
||||||
|
generated files from Nginx on port 80. The container joins the existing
|
||||||
|
`caddy_proxy` Docker network under the `static-site` service name expected by
|
||||||
|
Caddy.
|
||||||
|
|
||||||
|
## Deploy or update
|
||||||
|
|
||||||
|
From the project directory on the server, run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose up --build -d
|
||||||
|
```
|
||||||
|
|
||||||
|
The external `caddy_proxy` network must already exist and Caddy must be attached
|
||||||
|
to it. No host port is published because Caddy is the public entry point and
|
||||||
|
terminates TLS for `amiirkhl.ir` and `www.amiirkhl.ir`.
|
||||||
|
|
||||||
|
If the previous `static-site` container was created from a different Compose
|
||||||
|
project directory, remove that old stack once before the first deployment to
|
||||||
|
avoid a Docker container-name conflict. Updates from this project then use only
|
||||||
|
the command above.
|
||||||
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
FROM node:22-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM nginx:alpine AS runtime
|
||||||
|
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
COPY --from=builder /app/out/ /usr/share/nginx/html/
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1/ || exit 1
|
||||||
|
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
15
compose.yaml
Normal file
15
compose.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
services:
|
||||||
|
static-site:
|
||||||
|
image: amiirkhl-portfolio:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: static-site
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- caddy_proxy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
caddy_proxy:
|
||||||
|
external: true
|
||||||
|
name: caddy_proxy
|
||||||
41
nginx.conf
Normal file
41
nginx.conf
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
charset utf-8;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_types
|
||||||
|
application/javascript
|
||||||
|
application/json
|
||||||
|
application/xml
|
||||||
|
image/svg+xml
|
||||||
|
text/css
|
||||||
|
text/plain;
|
||||||
|
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
|
||||||
|
location ^~ /_next/static/ {
|
||||||
|
try_files $uri =404;
|
||||||
|
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri.html $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
location = /404.html {
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user