Search code examples
dockerpassengerstartupnext.jsphusion

How to define startup file in phusion/passenger-nodejs docker container


I'm attempting to get a next.js app running in a docker container based on phusion/passenger-docker.

I have what I think is a complete setup based on passenger-docker documentation but I'm getting a 404 page from nginx.

A docker log dump shows that passenger or nginx, is looking for index.html

[error] 48#48: *1 "/home/app/nhe_app/index.html" is not found

My startup file is /home/app/nhe_app/server.js

Dockerfile final stage:

# Build production container from builder stage
FROM phusion/passenger-nodejs:1.0.8

# Set correct environment variables.
ENV HOME /root
ENV NODE_ENV=production

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

# Enable Nginx and Passenger
RUN rm -f /etc/service/nginx/down

WORKDIR /home/app/nhe_app
RUN rm /etc/nginx/sites-enabled/default

COPY --chown=app:app ./nhe_app.conf /etc/nginx/sites-enabled/nhe_app.conf
COPY --chown=app:app ./secret_key.conf /etc/nginx/main.d/secret_key.conf
COPY --chown=app:app ./gzip_max.conf /etc/nginx/conf.d/gzip_max.conf

COPY --chown=app:app --from=builder /app/server.js /app/.env /home/app/nhe_app/
COPY --chown=app:app --from=builder app/src /home/app/nhe_app/src
COPY --chown=app:app --from=builder app/node_modules /home/app/nhe_app/node_modules

# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

nginx configuration - nhe_app.conf:

server {
    listen 80;
    server_name glen-mac.local;
    root /home/app/nhe_app/server.js;

    passenger_enabled on;
    passenger_user app;
    passenger_startup_file server.js;
}

I expect that passenger will start nginx and run my app.

When I build and start the docker container it seems to expect index.html.

I'm building the docker container with docker image build -t nhe_app .

And running it with docker container run --name nhe_app -p 80:3000 nhe_app

Browsing to http://glen-mac.local/ shows nginx's formatted 404 page.

How can I configure passenger-docker to look for and execute my server.js rather than index.html?


Solution

  • There are several subtle problems in the OP question.

    Most notably, Passenger seems to require that the app root path, defined by root in the nginx configuration above, has a top level folder named public. This folder must not contain an index.html file and probably should be empty. This is shown in examples, but not spelled out as a hard requirement in the docs.

    Second major error is that Passenger bypasses the port specified in the app's server.js (3000 in this case) and replaces it with the port specified in the nginx configuration. So the docker run command changed from:

    docker container run --name nhe_app -p 80:3000 nhe_app

    to

    docker container run --name nhe_app -p 80:80 nhe_app.

    Otherwise, the best advice I can give is:

    1. Learn the Passenger basics through a local installation (without Docker). Get the Passenger demo app working.
    2. Get your app working in that local Passenger installation.
    3. Apply what you have learned to implementing your app in passenger-docker.