Dockerizing Vue in Flask using uWSGI and nginx

huangapple go评论105阅读模式
英文:

Dockerizing Vue in Flask using uwsgi and nginx

问题

I'd like to containerize a client-server project I've been working on.
The project structure is as follows:

  1. ├── client
  2. ├── dist
  3. ├── node_modules
  4. ├── public
  5. └── src
  6. ├── nginx
  7. └── server
  8. ├── __pycache__
  9. ├── env
  10. ├── static
  11. └── templates

The client is a Vue.js app, and the server is Flask.
I know I should build the Vue app using npm run build and somehow copy the dist folder content into the server's static and templates directories.
In addition, I'd like to put the server behind uWSGI and Nginx for production.
I've followed this tutorial:

https://pythonise.com/series/learning-flask/building-a-flask-app-with-docker-compose

but it doesn't address how to serve the static Vue files (after they've been built).
I did like the approach of using docker-compose (as the tutorial suggested), so I've followed it, and now I have a docker-compose.yml in the root directory and 2 Dockerfiles (for client and server).

The docker-compose.yml content is:

  1. version: "3.7"
  2. services:
  3. flask:
  4. build: ./server
  5. container_name: flask
  6. restart: always
  7. expose:
  8. - 8080
  9. nginx:
  10. build: ./client
  11. container_name: nginx
  12. restart: always
  13. ports:
  14. - "80:80"

The server Dockerfile:

  1. # Use the Python 3.7.2 image
  2. FROM python:3.7.2-stretch
  3. # Set the working directory to /app
  4. WORKDIR /app
  5. # Copy the current directory contents into the container at /app
  6. ADD . /app
  7. # Install the dependencies
  8. RUN pip install -r requirements.txt
  9. # Run the command to start uWSGI
  10. CMD ["uwsgi", "app.ini"]

app.ini content:

  1. [uwsgi]
  2. wsgi-file = app.py
  3. callable = app
  4. socket = :8080
  5. processes = 4
  6. threads = 2
  7. master = true
  8. chmod-socket = 660
  9. vacuum = true
  10. die-on-term = true

client Dockerfile:

  1. # build stage
  2. FROM node:lts-alpine as build-stage
  3. WORKDIR /app
  4. COPY package*.json ./
  5. RUN npm install
  6. COPY . .
  7. RUN npm run build
  8. # production stage
  9. FROM nginx:stable-alpine as production-stage
  10. COPY --from=build-stage /app/dist /usr/share/nginx/html
  11. EXPOSE 80
  12. CMD ["nginx", "-g", "daemon off;"]

I thought maybe using a shared volume between containers is a possible solution, but I wasn't sure exactly if that's the way to go.

Any help will be greatly appreciated.

英文:

I'd like to containerise a client-server project I've been working on.
The project structure is as follows:

  1. ├── client
  2. │   ├── dist
  3. │   ├── node_modules
  4. │   ├── public
  5. │   └── src
  6. ├── nginx
  7. └── server
  8. ├── __pycache__
  9. ├── env
  10. ├── static
  11. └── templates

The client is a VueJs app and the server is Flask.
I know I should build the Vue app using npm run build and "somehow" copy the dist folder content into the server static and templates directories.
In addition I'd like to put the server behind uwsgi and Nginx for production.
I've followed this tutorial:

https://pythonise.com/series/learning-flask/building-a-flask-app-with-docker-compose

but it doesn't address how to serve the static Vue files (after they've been built).
I did like the approach of using docker-compose (as the tutorial suggested) so I've followed it and now I have a docker-compose.yml in the root directory and 2 Dockerfile (for client and server)

The docker-compose.yml content is:

  1. version: "3.7"
  2. services:
  3. flask:
  4. build: ./server
  5. container_name: flask
  6. restart: always
  7. expose:
  8. - 8080
  9. nginx:
  10. build: ./client
  11. container_name: nginx
  12. restart: always
  13. ports:
  14. - "80:80"

The server Dockerfile:

  1. # Use the Python3.7.2 image
  2. FROM python:3.7.2-stretch
  3. # Set the working directory to /app
  4. WORKDIR /app
  5. # Copy the current directory contents into the container at /app
  6. ADD . /app
  7. # Install the dependencies
  8. RUN pip install -r requirements.txt
  9. # run the command to start uWSGI
  10. CMD ["uwsgi", "app.ini"]

app.ini content:

  1. uwsgi]
  2. wsgi-file = app.py
  3. callable = app
  4. socket = :8080
  5. processes = 4
  6. threads = 2
  7. master = true
  8. chmod-socket = 660
  9. vacuum = true
  10. die-on-term = true

client Dockerfile:

  1. FROM node:lts-alpine as build-stage
  2. WORKDIR /app
  3. COPY package*.json ./
  4. RUN npm install
  5. COPY . .
  6. RUN npm run build
  7. # production stage
  8. FROM nginx:stable-alpine as production-stage
  9. COPY --from=build-stage /app/dist /usr/share/nginx/html
  10. EXPOSE 80
  11. CMD ["nginx", "-g", "daemon off;"]

I thought maybe using shared volume between containers is a possible solution, but wasn't sure exactly if that's the way to go.

Any help will be greatly appreciated.

答案1

得分: 2

由于您正在使用Vue.js,我会假设您正在开发一个单页面应用程序,其中服务器(Flask)是一个API服务器。

要使用Nginx提供Vue.js应用程序,您需要更改nginx.conf,而不是将代理传递给Flask,而是提供静态文件,这些文件位于/usr/share/nginx/html

  1. server {
  2. listen 80;
  3. location / {
  4. root /usr/share/nginx/html;
  5. try_files $uri $uri/ /index.html;
  6. }
  7. }

为了让Vue.js应用程序能够访问API服务器,您可以将一些带有前缀路径(如/api)的请求代理传递给Flask:

  1. server {
  2. ...
  3. location /api/ {
  4. include uwsgi_params;
  5. uwsgi_pass flask:8080;
  6. }
  7. }
英文:

Since you are using Vue.js I would assume that you are developing a single page application which the server (Flask) is an API server.

To serve Vue.js application using Nginx, you have to change nginx.conf instead of proxy pass to Flask, serve the static files which is /usr/share/nginx/html:

  1. server {
  2. listen 80;
  3. location / {
  4. root /usr/share/nginx/html;
  5. try_files $uri $uri/ /index.html;
  6. }
  7. }

To make Vue.js application can access API server you can proxy pass for some prefixed path such as /api to Flask:

  1. server {
  2. ...
  3. location /api/ {
  4. include uwsgi_params;
  5. uwsgi_pass flask:8080;
  6. }
  7. }

huangapple
  • 本文由 发表于 2020年1月7日 01:21:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/59616348.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定