diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 4020bcb..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - parser: '@typescript-eslint/parser', - parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': 'warn', - }, -} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.gitignore b/.gitignore index 78523e4..92ecd67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,29 +1,38 @@ -# Logs -logs -*.log +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* -lerna-debug.log* -node_modules -dist -dist-ssr -*.local +# local env files +.env*.local -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? +# vercel +.vercel -# various stuff -blogPosts.json -public/blog/*.xml -public/blog/feed.json \ No newline at end of file +# typescript +*.tsbuildinfo +next-env.d.ts + +blogPosts.json \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..d8e9561 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/mainwebsite.iml b/.idea/mainwebsite.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/mainwebsite.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..47de522 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6a3b83c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "javascript.preferences.importModuleSpecifierEnding": "minimal" +} \ No newline at end of file diff --git a/README.md b/README.md index a022825..e4ea4ae 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,6 @@ My public face on the wild internet. -Hosted on Vercel. Made with React, Typescript, Markdown and Material UI. +Hosted on Vercel. Made with Next.js, Typescript, Markdown and Material UI. URL: https://srizan.dev diff --git a/index.html b/index.html deleted file mode 100644 index 0d0dd40..0000000 --- a/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Sr Izan's front page for the web:tm: - - - -
- - - diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..6ab1084 --- /dev/null +++ b/next.config.js @@ -0,0 +1,2 @@ +/** @type {import('next').NextConfig} */ +export const nextConfig = {} \ No newline at end of file diff --git a/package.json b/package.json index d72c6cb..92952a0 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,38 @@ { - "name": "mainwebsite", + "name": "njs-move", + "version": "0.1.0", "private": true, - "version": "0.0.0", "type": "module", "scripts": { - "dev": "node src/blogPostGenerator.js && vite", - "build": "node src/blogPostGenerator.js && tsc && vite build", - "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "dev": "node src/blogPostGenerator.js && next dev", + "build": "next build", + "start": "node src/blogPostGenerator.js;next start", + "lint": "next lint" }, "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@fortawesome/fontawesome-svg-core": "^6.4.0", - "@fortawesome/free-brands-svg-icons": "^6.4.0", - "@fortawesome/free-regular-svg-icons": "^6.4.0", - "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@fortawesome/react-fontawesome": "^0.2.0", - "@mui/icons-material": "^5.14.12", - "@mui/material": "^5.14.5", - "dayjs": "^1.11.9", + "@mui/material": "^5.14.18", + "dayjs": "^1.11.10", "feed": "^4.2.2", - "glob": "^10.3.3", + "glob": "^10.3.10", "gray-matter": "^4.0.3", - "marked": "^8.0.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-helmet": "^6.1.0", - "react-markdown": "^8.0.7", - "react-router-dom": "^6.15.0", + "marked": "^10.0.0", + "next": "^14.0.3", + "react": "^18", + "react-dom": "^18", + "react-icons": "^4.12.0", + "react-markdown": "^9.0.1", "react-syntax-highlighter": "^15.5.0", - "remark-gfm": "^3.0.1" + "remark-gfm": "^4.0.0" }, "devDependencies": { - "@types/js-yaml": "^4.0.5", - "@types/mdx": "^2.0.6", - "@types/node": "^20.5.1", - "@types/react": "^18.0.37", - "@types/react-dom": "^18.0.11", - "@types/react-helmet": "^6.1.9", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", "@types/react-syntax-highlighter": "^15.5.10", - "@typescript-eslint/eslint-plugin": "^5.59.0", - "@typescript-eslint/parser": "^5.59.0", - "@vitejs/plugin-react": "^4.0.0", - "eslint": "^8.38.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.3.4", - "typescript": "^5.0.2", - "vite": "^4.3.9" + "eslint": "^8", + "eslint-config-next": "14.0.2", + "typescript": "^5" } } diff --git a/public/blog/atom.xml b/public/blog/atom.xml new file mode 100644 index 0000000..7e58e3a --- /dev/null +++ b/public/blog/atom.xml @@ -0,0 +1,198 @@ + + + https://srizan.dev/blog + Sr Izan's Blog + 2023-11-17T18:19:59.603Z + https://github.com/jpmonette/feed + + Sr Izan + izan@srizan.dev + https://srizan.dev + + + + My little donowall place on the net + https://srizan.dev/pfp.png + https://srizan.dev/pfp.png + Copyleft 2023, Sr Izan + + <![CDATA[My tales of MongoDB migration]]> + https://srizan.dev/blog/2 + + 2023-11-11T23:00:00.000Z + + Introduction +

So, the last few months I've been migrating services from my good old Raspberry Pi into my new HP server and the last service I migrated was MongoDB.

+

I've been using MongoDB for a while now and I've been using it for a few things, like my discord bots, webhooks-ui and probably other projects I don't remember right now.

+

So, let's get started!

+

Testing the plan

+

My database instance is on Docker with a replica set of 1 node (itself) so Prisma works.

+

My idea is to add the HP server as a secondary replica and then promote it to be the primary one, but I don't know if that will work, so we need to test some stuff.

+

I first created 2 docker containers on my main Ryzen machine's WSL Ubuntu instance.

+

I created a docker-compose.yml file with the following content:

+
version: "3.8"
+services:
+  mongo1:
+    image: mongo:4.4.17-rc0-focal
+    container_name: mongo1
+    restart: always
+    ports:
+      - 27017:27017
+    volumes:
+      - ./mongo1:/data/db
+    command: mongod --replSet mongoset
+    networks:
+      - mongo
+  mongo2:
+    image: mongo:4.4.17-rc0-focal
+    container_name: mongo2
+    restart: always
+    ports:
+      - 27018:27017
+    volumes:
+      - ./mongo2:/data/db
+    command: mongod --replSet mongoset
+    networks:
+      - mongo
+networks:
+  mongo:
+
+

and ran it with docker compose up -d.

+

I went to connect with MongoDB Compass and it didn't work for some reason. I asked GPT and nothing. It looks like it accepted the connection but it won't connect, so I installed mongosh and tried to connect with that.

+
$ mongosh mongodb://localhost:27017
+
+

...and it worked! That didn't make any sense, but okay, we can work with it.

+

I then connected to the mongo1 instance and ran the following commands:

+
> rs.initiate()
+
+

and it worked, but only that same database connected. Before adding the second database to the replica, I went ahead and pinged it from the first container (just to check if the network configuration worked):

+
docker exec mongo1 sh -c "rm /bin/ping;apt update;apt install inetutils-ping -y;ping mongo2"
+
+

I removed /bin/ping because I tried to transfer the binary from WSL to the container but it still needed some libraries and I didn't want to bother, so I just installed the package.

+

It worked, so I went ahead and added the second database to the replica set:

+
> rs.add("mongo2")
+
+

After waiting for it, the second database connected and everything was working fine. Let's create a collection and some documents on the primary replica (mongo1):

+
> use test
+> db.createCollection("test")
+> db.test.insertOne({ name: "test" })
+
+

and then, let's check if it's on the second replica (mongo2):

+
$ mongosh mongodb://localhost:27017
+
+
> use test
+> db.getMongo().setReadPref("secondaryPreferred")
+> db.test.find()
+
+

and, yeah, that worked.

+

I don't really know if ORMs will read when connecting to the second replica, but for now it's fine as the main plan is on track.
So, to promote I connected to the primary replica (mongo1) and ran the following command:

+
> rs.stepDown()
+
+

And that worked! Woo! The second replica is now the primary one. We can now start drum rolls please:

+

The migration

+

This is it. We're doing it.

+

I went ahead and created a new docker-compose file on my server with the following content:

+
version: "3.8"
+services:
+    mongo:
+        image: mongo:4.4.17-rc0-focal
+        container_name: mongodb
+        restart: unless-stopped
+        ports:
+            - 27017:27017
+        volumes:
+            - ./mongo:/data/db
+        command: mongod --replSet rs0
+
+

After deploying the stack, I connected using mongosh to the primary db and ran the following command:

+
> rs.add("ip")
+
+

and after waiting for a while it looked like it worked. I then connected to the new database and ran the following command to check if the replica cloned fine:

+
> db.getMongo().setReadPref("secondaryPreferred")
+
+

and let's just let the results speak for themselves:

+
rs0 [direct: secondary] test> show dbs
+# author's note: some dbs are redacted for privacy reasons 
+admin         80.00 KiB
+api           80.00 KiB
+ava           40.00 KiB
+bask         168.00 KiB
+config       144.00 KiB
+local        348.00 KiB
+vinci        428.00 KiB
+rs0 [direct: secondary] test> use vinci
+switched to db vinci
+rs0 [direct: secondary] vinci> show tables
+afk
+birthdays
+chatgpt
+giveaways-enters
+giveaways-message
+padyama
+suggestions
+twitter
+warns
+youtube
+rs0 [direct: secondary] vinci> db.afk.find()
+[
+  {
+    _id: ObjectId("sadfsad fsadfsdf"),
+    id: 'redacted',
+    reason: 'redacted',
+    __v: 0
+  },
+  {
+    _id: ObjectId("asdfsadfadf"),
+    id: 'redacted',
+    reason: 'readacted',
+    __v: 0
+  }
+]
+rs0 [direct: secondary] vinci>
+
+

Nice. let's now try to write something to the database from Vinci:

That just worked and we can see it on the secondary replica:

+
rs0 [direct: secondary] vinci> db.afk.find({ id: '703974042700611634' })
+[
+  {
+    _id: ObjectId("6550eccc6154a8c9030fe76a"),
+    id: '703974042700611634',
+    reason: 'test',
+    __v: 0
+  }
+]
+
+

Let's now edit all .envs and change the database url to the new secondary one. For this I checked all dbs that I have and then go from top to bottom editing the secrets.

+

After that was done I needed to deploy all changes. I went ahead and created too many tabs on my terminal and ran the all deployment commands on each tab. At the same time.
I really hope that doesn't make my server run out of ram, because I'm really short on that.

+

After executing all the commands I rs.stepDown()'ed the primary Raspberry Pi replica and, as expected, the HP Server took over.

+

The last command of the day:

+
> rs.remove("ip")
+
+

...SIKE! I needed to check the logs of the containers to see if everything was working fine. The api and vinci to be exact.
This is because api runs Prisma and vinci runs the now defunct in my stack, mongoose.

+

Luckily enough, both were fine, so I was free. Yay!

+

Conclusion

+

Welp, that was a lot of work. I'm glad it's over. I got my HP server on July and it's now November and I just finished migrating.
Could I have done it in less time? Yes.
Was I lazy? Also yes.

+

So that answers all your questions.

+

I hope you enjoyed this my first blog post, and thankfully it was a big one.
This took 3 hours in total, but at the end of the day, it was worth it.

+

I'll see you in the next one!

+]]>
+ + Sr Izan + https://srizan.dev + +
+ + <![CDATA[Welcome to my new blog!]]> + https://srizan.dev/blog/1 + + 2023-08-19T22:00:00.000Z + + Hey! +

This is probably the last time I'm going to make a blog. I've made a few in the past, but I've never really stuck to them. I'm hoping that this time will be different.
This one was made entirely from scratch using React and Markdown, initially trying to use MDX, but it was a pain to set up, and it didn't end up working in the end.
I'm hoping to post about my projects, and maybe some other stuff too. I'm not sure yet, but I'll figure it out as I go along.
Anyways, thank you for reading. I hope you enjoyed my UX/UI for this one!

+

PD: I need some help for making the blog text look good and readable, so hit me up on my Discord if you have any ideas.

+]]>
+ + Sr Izan + https://srizan.dev + +
+
\ No newline at end of file diff --git a/public/blog/feed.json b/public/blog/feed.json new file mode 100644 index 0000000..d7c6a39 --- /dev/null +++ b/public/blog/feed.json @@ -0,0 +1,38 @@ +{ + "version": "https://jsonfeed.org/version/1", + "title": "Sr Izan's Blog", + "home_page_url": "https://srizan.dev/blog", + "feed_url": "https://srizan.dev/blog/feed.json", + "description": "My little donowall place on the net", + "icon": "https://srizan.dev/pfp.png", + "author": { + "name": "Sr Izan", + "url": "https://srizan.dev" + }, + "items": [ + { + "id": "https://srizan.dev/blog/2", + "content_html": "

Introduction

\n

So, the last few months I've been migrating services from my good old Raspberry Pi into my new HP server and the last service I migrated was MongoDB.

\n

I've been using MongoDB for a while now and I've been using it for a few things, like my discord bots, webhooks-ui and probably other projects I don't remember right now.

\n

So, let's get started!

\n

Testing the plan

\n

My database instance is on Docker with a replica set of 1 node (itself) so Prisma works.

\n

My idea is to add the HP server as a secondary replica and then promote it to be the primary one, but I don't know if that will work, so we need to test some stuff.

\n

I first created 2 docker containers on my main Ryzen machine's WSL Ubuntu instance.

\n

I created a docker-compose.yml file with the following content:

\n
version: "3.8"\nservices:\n  mongo1:\n    image: mongo:4.4.17-rc0-focal\n    container_name: mongo1\n    restart: always\n    ports:\n      - 27017:27017\n    volumes:\n      - ./mongo1:/data/db\n    command: mongod --replSet mongoset\n    networks:\n      - mongo\n  mongo2:\n    image: mongo:4.4.17-rc0-focal\n    container_name: mongo2\n    restart: always\n    ports:\n      - 27018:27017\n    volumes:\n      - ./mongo2:/data/db\n    command: mongod --replSet mongoset\n    networks:\n      - mongo\nnetworks:\n  mongo:\n
\n

and ran it with docker compose up -d.

\n

I went to connect with MongoDB Compass and it didn't work for some reason. I asked GPT and nothing. It looks like it accepted the connection but it won't connect, so I installed mongosh and tried to connect with that.

\n
$ mongosh mongodb://localhost:27017\n
\n

...and it worked! That didn't make any sense, but okay, we can work with it.

\n

I then connected to the mongo1 instance and ran the following commands:

\n
> rs.initiate()\n
\n

and it worked, but only that same database connected. Before adding the second database to the replica, I went ahead and pinged it from the first container (just to check if the network configuration worked):

\n
docker exec mongo1 sh -c "rm /bin/ping;apt update;apt install inetutils-ping -y;ping mongo2"\n
\n

I removed /bin/ping because I tried to transfer the binary from WSL to the container but it still needed some libraries and I didn't want to bother, so I just installed the package.

\n

It worked, so I went ahead and added the second database to the replica set:

\n
> rs.add("mongo2")\n
\n

After waiting for it, the second database connected and everything was working fine. Let's create a collection and some documents on the primary replica (mongo1):

\n
> use test\n> db.createCollection("test")\n> db.test.insertOne({ name: "test" })\n
\n

and then, let's check if it's on the second replica (mongo2):

\n
$ mongosh mongodb://localhost:27017\n
\n
> use test\n> db.getMongo().setReadPref("secondaryPreferred")\n> db.test.find()\n
\n

and, yeah, that worked.

\n

I don't really know if ORMs will read when connecting to the second replica, but for now it's fine as the main plan is on track.
So, to promote I connected to the primary replica (mongo1) and ran the following command:

\n
> rs.stepDown()\n
\n

And that worked! Woo! The second replica is now the primary one. We can now start drum rolls please:

\n

The migration

\n

This is it. We're doing it.

\n

I went ahead and created a new docker-compose file on my server with the following content:

\n
version: "3.8"\nservices:\n    mongo:\n        image: mongo:4.4.17-rc0-focal\n        container_name: mongodb\n        restart: unless-stopped\n        ports:\n            - 27017:27017\n        volumes:\n            - ./mongo:/data/db\n        command: mongod --replSet rs0\n
\n

After deploying the stack, I connected using mongosh to the primary db and ran the following command:

\n
> rs.add("ip")\n
\n

and after waiting for a while it looked like it worked. I then connected to the new database and ran the following command to check if the replica cloned fine:

\n
> db.getMongo().setReadPref("secondaryPreferred")\n
\n

and let's just let the results speak for themselves:

\n
rs0 [direct: secondary] test> show dbs\n# author's note: some dbs are redacted for privacy reasons \nadmin         80.00 KiB\napi           80.00 KiB\nava           40.00 KiB\nbask         168.00 KiB\nconfig       144.00 KiB\nlocal        348.00 KiB\nvinci        428.00 KiB\nrs0 [direct: secondary] test> use vinci\nswitched to db vinci\nrs0 [direct: secondary] vinci> show tables\nafk\nbirthdays\nchatgpt\ngiveaways-enters\ngiveaways-message\npadyama\nsuggestions\ntwitter\nwarns\nyoutube\nrs0 [direct: secondary] vinci> db.afk.find()\n[\n  {\n    _id: ObjectId("sadfsad fsadfsdf"),\n    id: 'redacted',\n    reason: 'redacted',\n    __v: 0\n  },\n  {\n    _id: ObjectId("asdfsadfadf"),\n    id: 'redacted',\n    reason: 'readacted',\n    __v: 0\n  }\n]\nrs0 [direct: secondary] vinci>\n
\n

Nice. let's now try to write something to the database from Vinci:
\"\"
That just worked and we can see it on the secondary replica:

\n
rs0 [direct: secondary] vinci> db.afk.find({ id: '703974042700611634' })\n[\n  {\n    _id: ObjectId("6550eccc6154a8c9030fe76a"),\n    id: '703974042700611634',\n    reason: 'test',\n    __v: 0\n  }\n]\n
\n

Let's now edit all .envs and change the database url to the new secondary one. For this I checked all dbs that I have and then go from top to bottom editing the secrets.

\n

After that was done I needed to deploy all changes. I went ahead and created too many tabs on my terminal and ran the all deployment commands on each tab. At the same time.
I really hope that doesn't make my server run out of ram, because I'm really short on that.

\n

After executing all the commands I rs.stepDown()'ed the primary Raspberry Pi replica and, as expected, the HP Server took over.

\n

The last command of the day:

\n
> rs.remove("ip")\n
\n

...SIKE! I needed to check the logs of the containers to see if everything was working fine. The api and vinci to be exact.
This is because api runs Prisma and vinci runs the now defunct in my stack, mongoose.

\n

Luckily enough, both were fine, so I was free. Yay!

\n

Conclusion

\n

Welp, that was a lot of work. I'm glad it's over. I got my HP server on July and it's now November and I just finished migrating.
Could I have done it in less time? Yes.
Was I lazy? Also yes.

\n

So that answers all your questions.

\n

I hope you enjoyed this my first blog post, and thankfully it was a big one.
This took 3 hours in total, but at the end of the day, it was worth it.

\n

I'll see you in the next one!

\n", + "url": "https://srizan.dev/blog/2", + "title": "My tales of MongoDB migration", + "summary": "Here I ramble about the last service migration I did, MongoDB, and all the difficulties that came with it.", + "date_modified": "2023-11-11T23:00:00.000Z", + "author": { + "name": "Sr Izan", + "url": "https://srizan.dev" + } + }, + { + "id": "https://srizan.dev/blog/1", + "content_html": "

Hey!

\n

This is probably the last time I'm going to make a blog. I've made a few in the past, but I've never really stuck to them. I'm hoping that this time will be different.
This one was made entirely from scratch using React and Markdown, initially trying to use MDX, but it was a pain to set up, and it didn't end up working in the end.
I'm hoping to post about my projects, and maybe some other stuff too. I'm not sure yet, but I'll figure it out as I go along.
Anyways, thank you for reading. I hope you enjoyed my UX/UI for this one!

\n

PD: I need some help for making the blog text look good and readable, so hit me up on my Discord if you have any ideas.

\n", + "url": "https://srizan.dev/blog/1", + "title": "Welcome to my new blog!", + "summary": "This post welcomes you to my new blog", + "date_modified": "2023-08-19T22:00:00.000Z", + "author": { + "name": "Sr Izan", + "url": "https://srizan.dev" + } + } + ] +} \ No newline at end of file diff --git a/public/blog/rss.xml b/public/blog/rss.xml new file mode 100644 index 0000000..e1c284a --- /dev/null +++ b/public/blog/rss.xml @@ -0,0 +1,191 @@ + + + + Sr Izan's Blog + https://srizan.dev/blog + My little donowall place on the net + Fri, 17 Nov 2023 18:19:59 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + en + + Sr Izan's Blog + https://srizan.dev/pfp.png + https://srizan.dev/blog + + Copyleft 2023, Sr Izan + + + <![CDATA[My tales of MongoDB migration]]> + https://srizan.dev/blog/2 + https://srizan.dev/blog/2 + Sat, 11 Nov 2023 23:00:00 GMT + + Introduction +

So, the last few months I've been migrating services from my good old Raspberry Pi into my new HP server and the last service I migrated was MongoDB.

+

I've been using MongoDB for a while now and I've been using it for a few things, like my discord bots, webhooks-ui and probably other projects I don't remember right now.

+

So, let's get started!

+

Testing the plan

+

My database instance is on Docker with a replica set of 1 node (itself) so Prisma works.

+

My idea is to add the HP server as a secondary replica and then promote it to be the primary one, but I don't know if that will work, so we need to test some stuff.

+

I first created 2 docker containers on my main Ryzen machine's WSL Ubuntu instance.

+

I created a docker-compose.yml file with the following content:

+
version: "3.8"
+services:
+  mongo1:
+    image: mongo:4.4.17-rc0-focal
+    container_name: mongo1
+    restart: always
+    ports:
+      - 27017:27017
+    volumes:
+      - ./mongo1:/data/db
+    command: mongod --replSet mongoset
+    networks:
+      - mongo
+  mongo2:
+    image: mongo:4.4.17-rc0-focal
+    container_name: mongo2
+    restart: always
+    ports:
+      - 27018:27017
+    volumes:
+      - ./mongo2:/data/db
+    command: mongod --replSet mongoset
+    networks:
+      - mongo
+networks:
+  mongo:
+
+

and ran it with docker compose up -d.

+

I went to connect with MongoDB Compass and it didn't work for some reason. I asked GPT and nothing. It looks like it accepted the connection but it won't connect, so I installed mongosh and tried to connect with that.

+
$ mongosh mongodb://localhost:27017
+
+

...and it worked! That didn't make any sense, but okay, we can work with it.

+

I then connected to the mongo1 instance and ran the following commands:

+
> rs.initiate()
+
+

and it worked, but only that same database connected. Before adding the second database to the replica, I went ahead and pinged it from the first container (just to check if the network configuration worked):

+
docker exec mongo1 sh -c "rm /bin/ping;apt update;apt install inetutils-ping -y;ping mongo2"
+
+

I removed /bin/ping because I tried to transfer the binary from WSL to the container but it still needed some libraries and I didn't want to bother, so I just installed the package.

+

It worked, so I went ahead and added the second database to the replica set:

+
> rs.add("mongo2")
+
+

After waiting for it, the second database connected and everything was working fine. Let's create a collection and some documents on the primary replica (mongo1):

+
> use test
+> db.createCollection("test")
+> db.test.insertOne({ name: "test" })
+
+

and then, let's check if it's on the second replica (mongo2):

+
$ mongosh mongodb://localhost:27017
+
+
> use test
+> db.getMongo().setReadPref("secondaryPreferred")
+> db.test.find()
+
+

and, yeah, that worked.

+

I don't really know if ORMs will read when connecting to the second replica, but for now it's fine as the main plan is on track.
So, to promote I connected to the primary replica (mongo1) and ran the following command:

+
> rs.stepDown()
+
+

And that worked! Woo! The second replica is now the primary one. We can now start drum rolls please:

+

The migration

+

This is it. We're doing it.

+

I went ahead and created a new docker-compose file on my server with the following content:

+
version: "3.8"
+services:
+    mongo:
+        image: mongo:4.4.17-rc0-focal
+        container_name: mongodb
+        restart: unless-stopped
+        ports:
+            - 27017:27017
+        volumes:
+            - ./mongo:/data/db
+        command: mongod --replSet rs0
+
+

After deploying the stack, I connected using mongosh to the primary db and ran the following command:

+
> rs.add("ip")
+
+

and after waiting for a while it looked like it worked. I then connected to the new database and ran the following command to check if the replica cloned fine:

+
> db.getMongo().setReadPref("secondaryPreferred")
+
+

and let's just let the results speak for themselves:

+
rs0 [direct: secondary] test> show dbs
+# author's note: some dbs are redacted for privacy reasons 
+admin         80.00 KiB
+api           80.00 KiB
+ava           40.00 KiB
+bask         168.00 KiB
+config       144.00 KiB
+local        348.00 KiB
+vinci        428.00 KiB
+rs0 [direct: secondary] test> use vinci
+switched to db vinci
+rs0 [direct: secondary] vinci> show tables
+afk
+birthdays
+chatgpt
+giveaways-enters
+giveaways-message
+padyama
+suggestions
+twitter
+warns
+youtube
+rs0 [direct: secondary] vinci> db.afk.find()
+[
+  {
+    _id: ObjectId("sadfsad fsadfsdf"),
+    id: 'redacted',
+    reason: 'redacted',
+    __v: 0
+  },
+  {
+    _id: ObjectId("asdfsadfadf"),
+    id: 'redacted',
+    reason: 'readacted',
+    __v: 0
+  }
+]
+rs0 [direct: secondary] vinci>
+
+

Nice. let's now try to write something to the database from Vinci:

That just worked and we can see it on the secondary replica:

+
rs0 [direct: secondary] vinci> db.afk.find({ id: '703974042700611634' })
+[
+  {
+    _id: ObjectId("6550eccc6154a8c9030fe76a"),
+    id: '703974042700611634',
+    reason: 'test',
+    __v: 0
+  }
+]
+
+

Let's now edit all .envs and change the database url to the new secondary one. For this I checked all dbs that I have and then go from top to bottom editing the secrets.

+

After that was done I needed to deploy all changes. I went ahead and created too many tabs on my terminal and ran the all deployment commands on each tab. At the same time.
I really hope that doesn't make my server run out of ram, because I'm really short on that.

+

After executing all the commands I rs.stepDown()'ed the primary Raspberry Pi replica and, as expected, the HP Server took over.

+

The last command of the day:

+
> rs.remove("ip")
+
+

...SIKE! I needed to check the logs of the containers to see if everything was working fine. The api and vinci to be exact.
This is because api runs Prisma and vinci runs the now defunct in my stack, mongoose.

+

Luckily enough, both were fine, so I was free. Yay!

+

Conclusion

+

Welp, that was a lot of work. I'm glad it's over. I got my HP server on July and it's now November and I just finished migrating.
Could I have done it in less time? Yes.
Was I lazy? Also yes.

+

So that answers all your questions.

+

I hope you enjoyed this my first blog post, and thankfully it was a big one.
This took 3 hours in total, but at the end of the day, it was worth it.

+

I'll see you in the next one!

+]]>
+
+ + <![CDATA[Welcome to my new blog!]]> + https://srizan.dev/blog/1 + https://srizan.dev/blog/1 + Sat, 19 Aug 2023 22:00:00 GMT + + Hey! +

This is probably the last time I'm going to make a blog. I've made a few in the past, but I've never really stuck to them. I'm hoping that this time will be different.
This one was made entirely from scratch using React and Markdown, initially trying to use MDX, but it was a pain to set up, and it didn't end up working in the end.
I'm hoping to post about my projects, and maybe some other stuff too. I'm not sure yet, but I'll figure it out as I go along.
Anyways, thank you for reading. I hope you enjoyed my UX/UI for this one!

+

PD: I need some help for making the blog text look good and readable, so hit me up on my Discord if you have any ideas.

+]]>
+
+
+
\ No newline at end of file diff --git a/public/collab-highres.webp b/public/collab-highres.webp deleted file mode 100644 index d940b8a..0000000 Binary files a/public/collab-highres.webp and /dev/null differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index b37fdd7..0000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/(pages)/(root)/page.tsx b/src/app/(pages)/(root)/page.tsx new file mode 100644 index 0000000..7ab4ae8 --- /dev/null +++ b/src/app/(pages)/(root)/page.tsx @@ -0,0 +1,27 @@ +import '../../_css/Root.css'; +import React from 'react'; +import { SiOsu } from 'react-icons/si'; +import { FaDiscord, FaGithub, FaMastodon, FaTwitter, FaBlog } from 'react-icons/fa6'; +import Link from "next/link"; +import Image from 'next/image'; + +export default function Page() { + return ( +
+
+ {/* style={{ borderRadius: '70px' }} */} + main profile picture +

A spanish hobbyist developer and osu! player

+

Stalk me on social media:

+
+ + + + + + +
+
+
+ ) +} diff --git a/src/components/BlogPost.tsx b/src/app/(pages)/blog/[id]/page.tsx similarity index 67% rename from src/components/BlogPost.tsx rename to src/app/(pages)/blog/[id]/page.tsx index 721329a..41e493b 100644 --- a/src/components/BlogPost.tsx +++ b/src/app/(pages)/blog/[id]/page.tsx @@ -1,47 +1,36 @@ -import { useParams } from "react-router-dom"; -import { Helmet } from "react-helmet"; -import { useEffect, useState } from "react"; +import Head from "next/head"; +import * as fs from 'node:fs/promises' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism' -import { BlogNavBar } from "./BlogNavBar.tsx"; -import '../css/BlogPost.css'; +import BlogNavBar from "../../../_components/BlogNavBar"; +import '../../../_css/BlogPost.css'; +import React from "react"; +import jsonDataArray from '../../../../../public/blogPosts.json'; +import { redirect } from "next/navigation"; -export function BlogPost() { - const id = Number(useParams().id); - - if (isNaN(id)) { - // if it's not a number, redirect to the blog page - window.location.href = '/blog'; - } - - const [jsonData, setJsonData] = useState({ +export default async function Page({ params }: { params: { id: string } }) { + const id = parseInt(params.id); + if (Number.isNaN(id)) redirect('/blog') + let jsonData = { id: 0, title: '', description: '', date: '', fileName: '', fileContent: '' - }); + } - useEffect(() => { - const fetchData = async () => { - const jsonFetch = await import('../../blogPosts.json'); - const jsonDataArray = jsonFetch.default; - const filteredPost = jsonDataArray.filter((post) => post.id === id)[0]; - if (filteredPost) { - setJsonData(filteredPost); - } else { - document.location.href = '/blog'; - } - }; - - fetchData(); - }, [id]); + const filteredPost = jsonDataArray.filter((post) => post.id === id)[0]; + if (filteredPost) { + jsonData = filteredPost; + } else { + redirect('/blog') + } return (
- + {jsonData.title} @@ -49,21 +38,19 @@ export function BlogPost() { - +
) : ( @@ -77,6 +64,7 @@ export function BlogPost() { ) }, img(props) { + // eslint-disable-next-line jsx-a11y/alt-text return } }}> diff --git a/src/app/(pages)/blog/page.tsx b/src/app/(pages)/blog/page.tsx new file mode 100644 index 0000000..8ce7746 --- /dev/null +++ b/src/app/(pages)/blog/page.tsx @@ -0,0 +1,30 @@ +import '../../../app/_css/Blog.css'; +import Head from 'next/head'; +import blogPosts from '../../../../public/blogPosts.json' +import BlogPostCard from '../../../app/_components/BlogPostCard'; +import BlogNavBar from '../../../app/_components/BlogNavBar'; +import BlogRssDial from '@/app/_components/BlogRssDial'; + +function Blog() { + return ( +
+ + Blog + + + +
+ {blogPosts.map((post) => { + return ( + + ); + })} +
+
+ +
+
+ ); +} + +export default Blog; diff --git a/src/pages/Collab.tsx b/src/app/(pages)/collab/page.tsx similarity index 90% rename from src/pages/Collab.tsx rename to src/app/(pages)/collab/page.tsx index 9cb40d2..fa50618 100644 --- a/src/pages/Collab.tsx +++ b/src/app/(pages)/collab/page.tsx @@ -1,7 +1,9 @@ +import Image from "next/image"; + export default function Collab() { return (
- + Collab image Sr Izan diff --git a/src/components/BlogNavBar.tsx b/src/app/_components/BlogNavBar.tsx similarity index 72% rename from src/components/BlogNavBar.tsx rename to src/app/_components/BlogNavBar.tsx index ef4f11f..08e53c9 100644 --- a/src/components/BlogNavBar.tsx +++ b/src/app/_components/BlogNavBar.tsx @@ -1,8 +1,13 @@ -import { useEffect, useState } from 'react'; -import '../css/BlogNavBar.css' -import { Link } from 'react-router-dom'; +// sadge +'use client'; -export function BlogNavBar(props: Props) { +import { useEffect, useState } from 'react'; +import '../_css/BlogNavBar.css' +import Link from 'next/link'; +import Pfp from '../../../public/pfp.webp'; +import Image from 'next/image'; + +export default function BlogNavBar(props: Props) { const [isScrolled, setIsScrolled] = useState(false); useEffect(() => { @@ -26,7 +31,7 @@ export function BlogNavBar(props: Props) { main profile picture

{props.title || 'Sr Izan\'s blog'}

- Go back {props.title ? 'to posts' : 'home'} + Go back {props.title ? 'to posts' : 'home'}
) } diff --git a/src/components/BlogPostCard.tsx b/src/app/_components/BlogPostCard.tsx similarity index 87% rename from src/components/BlogPostCard.tsx rename to src/app/_components/BlogPostCard.tsx index eaac343..5a72a9a 100644 --- a/src/components/BlogPostCard.tsx +++ b/src/app/_components/BlogPostCard.tsx @@ -1,12 +1,14 @@ +"use client" + import Box from '@mui/material/Box'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import Typography from '@mui/material/Typography'; import dayjs from 'dayjs' import customParseFormat from 'dayjs/plugin/customParseFormat.js' -import '../css/BlogPostCard.css' +import '../_css/BlogPostCard.css' import { Button, CardActions } from "@mui/material"; -import {Link} from "react-router-dom"; +import Link from "next/link"; dayjs.extend(customParseFormat) export default function BlogPostCard(props: Props) { @@ -25,7 +27,7 @@ export default function BlogPostCard(props: Props) { - + diff --git a/src/app/_components/BlogRssDial.tsx b/src/app/_components/BlogRssDial.tsx new file mode 100644 index 0000000..bec0d92 --- /dev/null +++ b/src/app/_components/BlogRssDial.tsx @@ -0,0 +1,44 @@ +'use client' + +import SpeedDial from "@mui/material/SpeedDial"; +import SpeedDialAction from "@mui/material/SpeedDialAction"; +import { FaRss, FaAtom } from "react-icons/fa6"; +import { MdDataObject } from 'react-icons/md' + +const actions = [ + { icon: , name: 'RSS' }, + { icon: , name: 'JSON' }, + { icon: , name: 'Atom' } +]; + +export default function BlogRssDial() { + const handleChange = (event: string) => { + switch (event) { + case 'RSS': + window.location.href = '/blog/rss.xml' + break; + case 'JSON': + window.location.href = '/blog/feed.json' + break; + case 'Atom': + window.location.href = '/blog/atom.xml' + break; + } + } + return ( + } + > + {actions.map((action) => ( + handleChange(action.name)} + /> + ))} + + ) +} \ No newline at end of file diff --git a/src/app/_components/ThemeRegistry/EmotionRootStyleRegistry.tsx b/src/app/_components/ThemeRegistry/EmotionRootStyleRegistry.tsx new file mode 100644 index 0000000..3f0ec99 --- /dev/null +++ b/src/app/_components/ThemeRegistry/EmotionRootStyleRegistry.tsx @@ -0,0 +1,56 @@ +"use client"; +import { CacheProvider } from "@emotion/react"; +import createCache from "@emotion/cache"; +import { useServerInsertedHTML } from "next/navigation"; +import { ReactNode, useState } from "react"; +import { ThemeProvider } from "@mui/material/styles"; +import theme from "./theme"; + +export function RootStyleRegistry({ + children, +}: { + children: ReactNode; +}) { + const [{ cache, flush }] = useState(() => { + const cache = createCache({ key: "my" }); + cache.compat = true; + const prevInsert = cache.insert; + let inserted: string[] = []; + cache.insert = (...args) => { + const serialized = args[1]; + if (cache.inserted[serialized.name] === undefined) { + inserted.push(serialized.name); + } + return prevInsert(...args); + }; + const flush = () => { + const prevInserted = inserted; + inserted = []; + return prevInserted; + }; + return { cache, flush }; + }); + + useServerInsertedHTML(() => { + const names = flush(); + if (names.length === 0) return null; + let styles = ""; + for (const name of names) { + styles += cache.inserted[name]; + } + return ( +