Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Dockerize option to nuxt project #581

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

hamidne
Copy link

@hamidne hamidne commented Aug 1, 2020

This PR adds Dockerfile and docker-compose.yml as devOps option 🐳

@hamidne hamidne changed the title Add Dockerize option to nuxt project feat: Add Dockerize option to nuxt project Aug 1, 2020
@@ -0,0 +1,25 @@
# Dockerfile
FROM node:14-alpine
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alpine version is a very small version. I have been using this config for a long time and it can install packages well, the only problem is that it does not have git by default, which is when we use a package that instead of npm from use git, to solve this problem, I install git manually.
I have also seen some users have problems because the output size of the container with the image node itself is large.

Copy link
Author

@hamidne hamidne Aug 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And in this case, if you know something better, I'll be happy for you to share so we can replace it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok using alpine by default,. Maybe we can add a comment like # FROM node:14 to quickly switch? :)

Using single stage, ends up with final image with full dependencies in intermediate layers (including all devDependencies like webpack). (read more)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alpine > *

also, at geospoc we use nginx to serve as it provides nice brotli support out-of-the-box,

this is a huge change on how deployment of nuxt apps work..

PS. this is the Dockerfile we use at GeoSpoc

# Create the container from the alpine linux image
FROM alpine:latest as stage0

# Add nodejs
RUN apk add --update --no-cache nodejs nodejs-npm

# Set the directory we want to run the next commands for
WORKDIR /frontend

# Copy package.json & package-lock.json
COPY package.json package.json
COPY package-lock.json package-lock.json

# Install the dependencies, can be commented out if you're running the same node version
RUN npm ci

# Copy our source code into the container
COPY . .

# run webpack and the build the project
RUN NODE_ENV=production npm run build

# copy the built app to our served directory
FROM nginx:alpine

# Copy frontend data to dir that'll host the static files
COPY --from=stage0 /frontend/dist /var/www/html

# Copy the respective nginx configuration files
COPY docker/app/nginx/nginx.conf /etc/nginx/nginx.conf

# Copy the wildcard certificates from certs to /etc/ssl
COPY docker/app/nginx/certs/* /etc/ssl/

# build-base will add gcc
RUN apk add --update --no-cache git bash curl make build-base pcre-dev zlib-dev \
    && mkdir ~/brotli && command="nginx -v" && nginxv=$( ${command} 2>&1 ) && nginxlocal=$(echo $nginxv | grep -o '[0-9.]*$') \
    && cd ~/brotli && curl -L "https://nginx.org/download/nginx-$(echo $nginxlocal).tar.gz" -o nginx.tar.gz && tar zxvf nginx.tar.gz && rm nginx.tar.gz \
    && git clone https://github.com/google/ngx_brotli.git && cd ngx_brotli && git submodule update --init \
    && cd ~/brotli/nginx-$(echo $nginxlocal) && ./configure --with-compat --add-dynamic-module=../ngx_brotli && make modules \
    && cp -r ./objs/*.so /usr/lib/nginx/modules/ \
    && rm -rf ~/brotli/ \
    && sed -i '1iload_module modules/ngx_http_brotli_filter_module.so; load_module modules/ngx_http_brotli_static_module.so;' /etc/nginx/nginx.conf

# Expose ports.
EXPOSE 80
EXPOSE 443

# start nginx and keep the process from backgrounding and the container from quitting
CMD ["nginx"]

staged builds for life!

packages/cna-template/template/_docker-compose.yml Outdated Show resolved Hide resolved
packages/create-nuxt-app/lib/prompts.js Outdated Show resolved Hide resolved
@hamidne hamidne requested a review from pi0 August 22, 2020 16:04
@@ -112,5 +112,15 @@ module.exports = [
{ name: 'Semantic Pull Requests', value: 'semantic-pull-requests' }
],
default: []
},
{
name: 'devOps',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to somehow enable it only for server target since for full static doesn't makes sense having this option

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The selection of this feature is optional and also due to the code structure, it is not possible to enable this feature based on the condition.

Copy link
Contributor

@scscgit scscgit Aug 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There most certainly are use-cases for deploying full static sites as Dockerized, which except for using nginx itself include also scenarios like using a reverse proxy to expose private services inside a k8s cluster (and possibly whitelisting/blacklisting their endpoints) when the site consumes their API, or to go around CORS issues if the APIs cannot be accessed directly (though in some cases https://axios.nuxtjs.org/options/#proxy may be used for this, but it can't be used if we "already" use nginx anyway)

This seems to be officially suggested by Nuxt at https://nuxtjs.org/docs/2.x/deployment/nginx-proxy

However, note that nginx has some major issues when using it as a reverse proxy for other services; for example it doesn't support search of /etc/resolv.conf even if you apply a workaround https://serverfault.com/a/373306 to load the resolver IP, which is vital if you need for the domains to be cached temporarily rather than having the IP be resolved only at startup. There may be even a need for hacks like https://serverfault.com/a/909100 if you need to reload the file itself.

Copy link
Member

@pi0 pi0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR pending because we should prefer multistage images.There might be many different approaches to build a docker image for nuxt apps. It would be probably better if we focus on documentation explaining how to deploy projects via docker and some common practices IMO

@hamidne
Copy link
Author

hamidne commented Oct 10, 2020

Of course, making a CI/CD for each project is time consuming and different for each project, and therefore requires a Docker image with a different structure, but in small projects having a code sample can be very helpful.
You should also spend more time on related documentation and introduce different Docker image structures so that people can create their own Docker image as needed.

@scscgit
Copy link
Contributor

scscgit commented Apr 10, 2022

2 years is a pretty long time, is there any plan to introduce a first iteration of the Docker image variant yet? I'd like to eventually integrate new improvements or workarounds, but it's difficult to open PRs if nothing has been merged yet. Can we get any information about what is currently being worked on? It would be great if we had a documentation for various use-cases, or even better, if the Dockerfile was self-documented with available next steps after providing users with multiple generation options. For example, dev mode or build vs. generate may differ (and so does SSR), and we need workarounds like envsubst if we want to pass environment variables to nginx. Kubernetes tools could be also added in the following iterations, and so could tools like podman to become more inclusive.

  • It's non-trivial to create a multi-platform baseline that new projects can easily reuse, and there are plenty of additional DX improvements available, for example adding common docker use-cases as npm scripts, e.g. stop & rm to clean the containers (npm i -D cash-true and adding "docker:clean": "echo Cleaning up Docker containers && (docker stop image-name || true) && (docker rm image-name || true)"), agreeing on optimal cache usage (--no-cache), parametrizing env using cross-env-shell with workarounds (e.g. cross-env-shell docker run --name project_name -v '\\\"$INIT_CWD:/usr/src/app\\\"'), referring to build image using $npm_package_version, using separate image name for dev mode, pipeline to push the image, etc.

The pros and cons of specific implementations (e.g. base docker images and their versions) could be listed somewhere as a source of truth to make it easier to suggest changes once the dependent technologies further evolve, so that users aren't stuck with ad-hoc decisions in their projects if they prefer zero-configuration.


Also related to Nuxt 3 docs:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants