Skip to content

Commit

Permalink
rough in nginx
Browse files Browse the repository at this point in the history
  • Loading branch information
rubys committed Aug 7, 2023
1 parent 5f41f7c commit 773daa9
Show file tree
Hide file tree
Showing 8 changed files with 2,221 additions and 3 deletions.
28 changes: 28 additions & 0 deletions gdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const defaults = {
legacyPeerDeps: false,
link: true,
litefs: false,
nginxRoot: '',
port: 0,
swap: '',
windows: false,
Expand Down Expand Up @@ -175,6 +176,7 @@ export class GDF {
if (this.litefs) packages.push('ca-certificates', 'fuse3')
if (this.remix && this.sqlite3) packages.push('sqlite3')
if (this.prisma) packages.push('openssl')
if (this.options.nginxRoot) packages.push('nginx')

return packages.sort()
}
Expand Down Expand Up @@ -351,6 +353,21 @@ export class GDF {
return this.#packager
}

// install modules needed to run
installModules() {
const modules = []

if (this.options.nginxRoot && !this.#pj.dependencies?.foreman) {
modules.push('foreman')
}

if (modules.length === 0) return
const add = this.packager === 'npm' ? 'install' : 'add'
for (const module of modules) {
execSync(`${this.packager} ${add} ${module}`, { stdio: 'inherit' })
}
}

// install all dependencies in package.json
get packagerInstall() {
let install = `${this.packager} install`
Expand Down Expand Up @@ -492,6 +509,10 @@ export class GDF {
return this.runtime.split('/')[0].replaceAll('.', '').toLowerCase()
}

get foreman() {
if (this.options.nginxRoot) return true
}

// command to start the web server
get startCommand() {
if (this.options.cmd) return JSON.stringify(this.options.cmd)
Expand Down Expand Up @@ -601,6 +622,9 @@ export class GDF {
this._appdir = appdir
this.#pj = JSON.parse(fs.readFileSync(path.join(appdir, 'package.json'), 'utf-8'))

// install modules needed to run
this.installModules()

if (options.force) this.#answer = 'a'

// read instructions
Expand Down Expand Up @@ -631,6 +655,10 @@ export class GDF {
templates['litefs.yml.ejs'] = `${this.configDir}litefs.yml`
}

if (this.options.nginxRoot) {
this.options.nginxRoot = path.join('/app', this.options.nginxRoot)
}

for (const [template, filename] of Object.entries(templates)) {
const dest = await this.#writeTemplateFile(template, filename)

Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ const options = yargs((hideBin(process.argv)))
describe: 'use COPY --link whenever possible',
type: 'boolean'
})
.option('nginx-root', {
describe: 'Root directory containing static files to be served by nginx',
type: 'string'
})
.option('port', {
describe: 'expose port',
type: 'integer'
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 40 additions & 1 deletion templates/Dockerfile.ejs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax = docker/dockerfile:1

<% if (packager == "bun") { -%>
<% if (packager === "bun") { -%>
# Adjust BUN_VERSION as desired
ARG BUN_VERSION=<%= bunVersion %>
FROM oven/bun:${BUN_VERSION} as base
Expand Down Expand Up @@ -175,10 +175,49 @@ ENTRYPOINT <%- entrypoint %>
# Deploy arguments
<%- emitArgs(options.args.deploy) %>
<% } -%>
<% if (options.nginxRoot) { -%>
# configure nginx
RUN sed -i 's/access_log\s.*;/access_log stdout;/' /etc/nginx/nginx.conf && \
sed -i 's/error_log\s.*;/error_log stderr info;/' /etc/nginx/nginx.conf
COPY <<-"EOF" /etc/nginx/sites-available/default
server {
listen <%= port %> default_server;
listen [::]:<%= port %> default_server;
access_log stdout;
root <%= options.nginxRoot %>;
location / {
try_files $uri @backend;
}
location @backend {
proxy_pass http://localhost:<%= port + 1 %>;
proxy_set_header Host $http_host;
}
}
EOF
<% } -%>
<% if (foreman) { -%>
# Build a Procfile for production use
COPY <<-"EOF" /app/Procfile.prod
<% if (options.nginxRoot) { -%>
nginx: /usr/sbin/nginx -g "daemon off;"
<% } -%>
app: PORT=<%= port+1 %> <%- startCommand.join(" ") %>
EOF
<% } -%>
# Start the server by default, this can be overwritten at runtime
EXPOSE <%= port %>
<% if (Object.keys(deployEnv).length > 0) { -%>
<%- emitEnv(deployEnv) %>
<% } -%>
<% if (foreman) { -%>
CMD [ "<%= packager === "bun" ? 'bunx' : 'npx' %>", "foreman", "start", "--procfile", "Procfile.prod" ]
<% } else { -%>
CMD <%- JSON.stringify(startCommand, null, 1).replaceAll(/\n\s*/g, " ") %>
<% } -%>
6 changes: 6 additions & 0 deletions test/base/nginx/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/.git
/node_modules
.dockerignore
.env
Dockerfile
fly.toml
73 changes: 73 additions & 0 deletions test/base/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# syntax = docker/dockerfile:1

# Adjust NODE_VERSION as desired
ARG NODE_VERSION=xxx
FROM node:${NODE_VERSION}-slim as base

LABEL fly_launch_runtime="Node.js"

# Node.js app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"


# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build node modules
RUN apt-get update -qq && \
apt-get install -y build-essential pkg-config python-is-python3

# Install node modules
COPY --link package-lock.json package.json ./
RUN npm ci

# Copy application code
COPY --link . .


# Final stage for app image
FROM base

# Install packages needed for deployment
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y nginx && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Copy built application
COPY --from=build /app /app

# configure nginx
RUN sed -i 's/access_log\s.*;/access_log stdout;/' /etc/nginx/nginx.conf && \
sed -i 's/error_log\s.*;/error_log stderr info;/' /etc/nginx/nginx.conf

COPY <<-"EOF" /etc/nginx/sites-available/default
server {
listen 3000 default_server;
listen [::]:3000 default_server;
access_log stdout;

root /app/public;

location / {
try_files $uri @backend;
}

location @backend {
proxy_pass http://localhost:3001;
proxy_set_header Host $http_host;
}
}
EOF

# Build a Procfile for production use
COPY <<-"EOF" /app/Procfile.prod
nginx: /usr/sbin/nginx -g "daemon off;"
app: PORT=3001 npm run start
EOF

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD [ "npx", "foreman", "start", "--procfile", "Procfile.prod" ]
Loading

0 comments on commit 773daa9

Please sign in to comment.