Backend + Frontend on a Single Container
If you're like me and you don't want things to be complicated, then you obviously want everything to run in the same container (I'm exagerating obviously)
In this example I'll be containerizing a Django application and a Nuxt.JS application into a single Docker Image. Currently my application only have a few users and it isn't worth the time to over-compilcate things, I want to code, push and let the image update everything together.
This will also simplify the development, versioning and deployment flow.
So let's get right into it.
Folder Structure
I'm using a simple folder structure with `backend/` and `frontend/` where the code resides, there's a bunch of other folders we can ignore (workflows, scripts, configs, docs, etc)
At the root level I have the `Dockerfile`
Dockerfile
The Dockerfile contains a frontend-build stage and a backend stage (the one that's deployed), the frontend-build stage uses node:lts and the backend uses some minimal image (here I chose opensuse/leap)
The Dockerfile:
FROM node:lts-bookworm as frontend-build
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY frontend/package*.json ./
COPY frontend/yarn.lock ./
RUN yarn install
# Bundle app source
COPY ./frontend .
RUN yarn generate
FROM opensuse/leap:15.5
RUN zypper --non-interactive si -d python311 python311-pip \
&& zypper --non-interactive in python311 \
&& python3.11 -m ensurepip
COPY backend/requirements.txt /requirements.txt
RUN python3.11 -m pip install -r /requirements.txt
WORKDIR /app
COPY backend .
EXPOSE 8000
COPY --from=frontend-build /usr/src/app/.output/public /app/staticfiles
RUN python3.11 manage.py collectstatic --noinput
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "accounting.wsgi"]
That's it.
When I push code from any of backend/ or frontend/, my CI/CD will build, bump version and deploy the latest docker image. I've been delaying an article on that kind of (basic) CI/CD (that meets most needs), but if enough interest don't hesitate leaving a comment
Also, SUBSCRIBE! Thank you
Member discussion