Fake Instagram
A social media platform clone extended into a full DevOps environment.
Fake Instagram started as a university project and evolved into a full-stack social media application with user registration and authentication, profiles, posts, image uploads, likes, comments and a personalized feed.
The frontend is built with Angular and Angular Material, while the backend is an Express.js REST API. MongoDB Atlas is used as the database and Cloudinary handles uploaded media, keeping large image files outside of the application database.
The application is fully containerized with Docker and Docker Compose, allowing the frontend, backend and supporting services to be started as a consistent local development environment.
The project was later extended (within another course) beyond the application itself into a small DevOps environment. Nginx acts as a reverse proxy, routing requests to the different containers through separate paths while exposing the system through a single domain.
Jenkins was introduced as a local CI/CD server for automating application workflows. Terraform was used to define infrastructure configuration, while iptables provided additional control over network traffic between the services.
The infrastructure was also extended with Zabbix for system and service monitoring and Graylog for centralized log collection and analysis. This turned the project from a simple university web application into an environment where deployment, observability and infrastructure management could be explored alongside application development.
Links
$ cat challenges.md
Designing the full-stack architecture
The application had to connect an Angular frontend, Express.js API, MongoDB Atlas and Cloudinary into a coherent system. Keeping responsibilities separated between the client, API, database and media storage was an important part of the implementation.
Handling media outside the application
Social applications can quickly generate large amounts of media data. I used Cloudinary for image storage and delivery instead of keeping uploaded files directly in the application or database, reducing the amount of binary data handled by the backend.
Routing multiple containers through one domain
Once the application was split into multiple containers, I needed a way to expose the services without assigning a separate public endpoint to each one. Nginx was introduced as a reverse proxy to route different URL paths to the appropriate container.
Building a repeatable development environment
Docker Compose was used to define the application's services and their relationships. This made the environment reproducible and provided a foundation for experimenting with additional infrastructure and DevOps tooling.
Introducing CI/CD into a local environment
I extended the project with Jenkins to experiment with automated build and deployment workflows. Running Jenkins locally made it possible to explore CI/CD concepts without depending on an external hosted pipeline.
Adding observability
As the number of services increased, understanding what was happening across the system became more difficult. Zabbix was introduced for monitoring while Graylog provided centralized log collection, making it easier to inspect service health and diagnose problems.
Managing infrastructure and network traffic
The project was extended with Terraform for infrastructure configuration and iptables for controlling network traffic. This provided hands-on experience with infrastructure as code and the networking boundaries between application services.
Full-stack e-commerce platform for sports gear with Stripe checkout.