Anh ơi em đang làm một trong những project mà anh hướng dẫn đó là docker-laravel-real-time-chat ạ. Khi em chạy lệnh docker-compose exec app php artisan migrate --seed thì hệ thống lại báo lỗi là SQLSTATE[HY000] [1045] Access denied for user 'laraveluser'@'172.24.0.7' (using password: YES). Em đã search google rồi ạ những vẫn không tìm ra nguyên nhân của việc này. Mong anh có thể giúp em giải đáp thắc mắc ạ. Em cảm ơn anh
Hi Đức, mình thấy các nội dung update và kiến thức của bạn rất bổ ích và thiết thực cho ae dev. Không biết mình muốn liên hệ đăng share bài viết hoặc hợp tác share bài với bạn, mình có thể liên hệ như thế nào ha? Cảm ơn Đức
rất nhiều!
Dạ em chào anh,
Em là Phượng - HR tại Remitano, hiện tại Remitano đang tuyển Full Stack Dev - với range lương $2500 - $4000 - làm việc full time - Remotely. Không biết hiện tại anh có đang open cho công việc mới không ạh.
Nếu có, em rất mong sớm nhận được phản hồi từ anh qua Comment hoặc email ngocphuong@remitano.com.
Have a nice day anh nhé.
Chất quá Đức.
Nhiều kiến thức hay và rất bổ ích. Không những vậy cách truyền đạt rất dễ hiểu và hấp dẫn.
Chúc ông nhiều sức khỏe và có thêm nhiều bài viết hay chia sẻ cho mọi người!
Container MySQL -----> Host machine ------> Outside World
Ví dụ e map từ port 3306 ra port 8080 ở ngoài Host, và e ko muốn Outside World truy cập được vào cổng 8080 ở Host
khi e map port thì ở Host Machine sẽ truy cập được, Outside World chỉ truy cập được nếu như Host Machine mở cho traffic đi vào port 8080 (thường mặc định là ko để bảo mật)
Nếu ở Host machine của e đang mở cho traffic đi vào mọi cổng (có 8080) thì e đơn giản là block traffic ở cổng đó lại. Nhưng trường hợp này nếu có xảy ra thì a thấy host machine của e đang bị hổng bảo mật nghiêm trọng ). Best security đó là mở càng ít cổng càng tốt
Nếu host machine của e là VPS mua ở các cloud provider lớn như Google, AWS, Azure, ... thì họ có sẵn security group bao phía ngoài VPS của e, e đơn giản là lên trang web giao diện của họ để allow/block traffic đi vào cổng nào đó
hiện tại a đang làm ở Singapore e, a cũng muốn về thăm HN quá mà dịch bệnh hơn năm nay chưa có đc về và cũng ko biết bao giờ về đc . Khi nào a có đk về a ới lên (facebook), ae nào muốn thì mình gặp nhau học hỏi
Chào anh ạ! Thấy anh có các bài viết hay chia sẻ về DevOps. Bên em muốn liên hệ hợp tác cùng anh tham gia dự án đào tạo về DevOps (parttime) và chia sẻ các bài viết. Nếu anh quan tâm, anh có thể cho em xin thông tin email để em tiện kết nối ạ. Hoặc anh có thể gửi thông tin qua mail: manpham@techmaster.vn hoặc zalo: 0963023185 để em tiện liên hệ với ạ. Em cảm ơn!
Hi anh, em đang gặp vấn đề access denied của mysql trên docker. Khi em docker compose down rồi lại bật lên thì dính lỗi access denied không thể truy cập db kể cả dùng tài khoản root và phải import lại db. Em đã thử các cách như đổi tên service, sử dụng file .env rồi nhưng không được. Mong anh giải đáp giúp em, em cảm ơn ! Dưới đây là file docker-compose.yml em đang dùng.
thật khó để nói chính xác lỗi của e là gì nếu không debug, nhưng với các dạng lỗi như thế này, phỏng đoán khả năng rất cao là đoạn e mount volumn cho db kia có vấn đề lúc shutdown.
Và thường nếu dính lỗi về volume mà không hiểu gì đang xảy ra thì tốt nhất là ta đổi từ local volume sang dùng Docker volume
Chào Đức. Mình đang tìm hiểu về mô hình microfrontend, bài viết của Đức rất hay. Mình muốn hỏi KN của Đức về bảo mật microfrontend. Giải pháp nào để chỉ cho phép người dùng truy cập link appshell mà không cho phép truy cập trực tiếp link microfrontend (nếu họ biết được link). Thanks Đức
bên mình đang deploy MFE và host nó private (trong private network) và chỉ đc access qua app shell, thông qua proxy, ở app shell thì luôn có authentication. Ở đây ta sẽ chỉ có 1 link public (app shell) và các link private (MFE)
cách khác là: vì bản chất MFE nó cũng chỉ là các file static (css, js), nên bạn có thể copy chúng và host chung với app shell trong 1 deployment luôn cũng đc. Tức là chỉ có 1 link chung cho cả app shell và MFE, 1 public link, ko có private. Rồi bạn thêm authentication vào.
Cách khác nữa là, tất cả các link của app shell và MFE đều public. Nhưng ở phía MFE nếu user truy cập vào link của nó thì ta check và yêu cầu authentication, hoặc từ chối phục vụ, kiểu "please access through app-shell..."
Lý do bên mình làm theo cách 1 là muốn giữ tất cả các app (app shell, các MFE), mỗi chúng nó là 1 deployment riêng (kiểu 1 microservice), độc lập, quy trình build+deploy như nhau, cả kiến trúc đồng nhất, và MFE có thể chạy đc ở nhiều app shell khác nhau nữa.
Về vấn đề bảo mật thì mình thấy sẽ có ti tỉ cách làm, tuỳ công ty, tuỳ project nữa, bên trên là vài cách mình vừa nghĩ ra )
Hi Đức Master, anh hỏi chút về docker. A làm theo bài này: https://geshan.com.np/blog/2023/01/nextjs-docker/
gặp lỗi: Error: EACCES: permission denied, unlink '/app/.next/build-manifest.json'. Đức có thể fix và giải thích cái lỗi này giúp anh được không ?
@maitrungduc1410 Ubuntu 22.04.3, docker compose version 2, còn file docker-compose.yml là ở trong bài post đó. Anh build và run bằng docker compose như bài đó.
@maitrungduc1410 Được rồi em ơi, cái này có cách nào không phải chạy lệnh cấp quyền kia không nhỉ, ví dụ lỡ có ngày đổi user trong docker-compose.yml ý
@dangduytung bởi vì cái bài a đang xem nó dùng user 1001:1001 và ở docker-compose.yml nó còn map volume toàn bộ folder ngoài vào trong container, nên permission của folder ở ngoài có thể ảnh hưởng tới bên trong container:
volumes:- .:/app
Đó là lí do vì sao phải chạy lại lệnh cấp quyền như e nói.
Nếu a ko muốn đau đầu vụ user non-root này thì a đơn giản là dùng mặc định user root của image thôi ạ:
FROM node:18-alpine AS depsRUN apk add --no-cache libc6-compatWORKDIR /appCOPY package.json package-lock.json ./RUN npm install --productionFROM node:18-alpine AS builderWORKDIR /appCOPY--from=deps /app/node_modules ./node_modulesCOPY . .ENV NEXT_TELEMETRY_DISABLED 1RUN npm run buildFROM node:18-alpine AS runnerWORKDIR /appENV NODE_ENV productionENV NEXT_TELEMETRY_DISABLED 1# RUN addgroup --system --gid 1001 nodejs# RUN adduser --system --uid 1001 nextjs# COPY --from=builder --chown=nextjs:nodejs /app/.next ./.nextCOPY--from=builder /app/node_modules ./node_modulesCOPY--from=builder /app/package.json ./package.json# USER nextjsEXPOSE 3000ENV PORT 3000CMD ["npm", "start"]
A để ý những chỗ bên trên e comment ạ, e đã bỏ đoạn đổi sang chạy với user nextjs
Chào e!
A xem series docker của e và thấy có rất nhiều kiến thức bổ ích. a cũng muốn triển khai 1 vài cái app nhỏ ở cty anh trên 1 cái host trong mạng nội bộ dưới dạng docker. Đọc bài của e a cảm thấy khi triển khai trên docker windows (windows là OS của host, ko phải của container) có vẻ có 1 số điểm không được tương thích toàn bộ như trên docker linux. hiện tại host của a chạy windows vì khi cần sửa đổi cập nhật gì a có thể làm từ xa ở nhà thông qua teamview. a đang định cái headless linux lên host chỉ để chuyên chạy docker container nhưng đang lo ngại là khi chỉnh sửa, cập nhật gì thì mình không thể ssh từ nhà lên host được (cơ quan anh ko có ip tĩnh). A muốn hỏi kinh nghiệm của em là có cách nào có thể truy cập máy linux từ xa mà không cần ip tĩnh không, như giải pháp của teamview vậy?
Cám ơn em trước nhé.
về vụ dynamic IP, thì a viết 1 cái script nhỏ, đặt trên host trên cty của a (theo như a nói thì host này đang chạy windows), script chạy như cronjob, check IP hiện tại của host, và nếu có thay đổi thì gửi nó về cho a (qua email chẳng hạn)
@maitrungduc1410 Cám ơn e đã phản hồi. a quên mất là ngoài việc không có ip tĩnh, lại còn không open port được modem ở cơ quan nữa ý e, vì mạng dùng chung với cả các đơn vị khác, 1 mình mình không thể open port được
@maitrungduc1410 đúng rồi e, không có port SSH để vào ý. nếu ngồi trong mạng LAN thì có thể SSH thoải mái. nhưng khi ngồi nhà, muốn SSH qua internet thì có 2 hạn chế là: ko có ip tĩnh và không có SSH port. thế nên hiện tại a phải dùng windows và cài docker desktop lên đó. Nếu cần chỉnh sửa gì từ nhà thì chạy teamviewer vào là xong. Giờ a ko muốn dùng windows nữa mà muốn cài linux lên máy đó, chuyên để chạy docker nhưng lại vướng khoản remote
@maitrungduc1410 a đã thử cài teamviewer trên linux rồi nhưng không được e ạ. Vì cài linux cũng mất công nên trước khi cài chính thức, a cài teamviewer trên docker container ubuntu:jammy. việc cài đặt thì không báo lỗi gì tuy nhiên khi chạy lệnh teamviewer setup để cài unattended access thì nó bảo lỗi teamviewer daemon not running trong khi a đã thử restart cái daemon này nhiều lần. chạy lệnh teamviewer status cũng cho thấy daemon đang ở trạng thái running
@maitrungduc1410 a cám ơn Đức nhé, cám ơn e đã nhiệt tình trả lời. Hôm nay a đã cài teamviewer thành công lên bản ubuntu server được cài lên virtualbox rồi. Có lẽ ubuntu container nó bị lược đi những package nào đó rất đến việc khởi chạy teamviewerd không được. A đang tính thêm 1 số cách khác như: sử dụng ssh tunneling, máy chủ trung gian có thể dùng azure virtual machines cấu hình thấp; hoặc sử dụng ssh thông qua tor hidden services. em có thấy những cách này có kỳ quái lắm ko 😅
Chào anh. Không biết có ai hỏi chưa nhưng e đang có nhu cầu deploy project cá nhân lên vps bằng docker. Nhưng vì project có vài ba repository và mỗi repo e lại setup docker compose riêng lẻ cho nó nên giờ e đang mắc 2 vấn đề hi vọng đc a giái đáp:
Nên setup docker compose file thế nào cho hợp lí. Vì FE, BE của đều cần dùng chung nginx service nên e đang setup nginx trong cả 2 file docker compose của 2 repo khi code và test trên local. Nhưng khi lên production thì đó có phải là ý tưởng tốt ko ạ? Và nếu chỉ muốn có 1 nginx service thì e nên setup nó ở đâu, compose của BE hay FE hay 1 file riêng ạ?
Trong trường hợp các service thuộc repo này muốn gọi đến service của repo kia. E đang tính sử dụng external docker network hoặc external_link để giúp các service resolve đc nhau. Nhưng với kiến thức hạn hẹp của e thì kb đó có phải phương án tối ưu. Nếu có giải pháp tốt hơn thì hi vọng a có chỉ cho e hướng hoặc keyword để e tự research cũng tốt lắm rồi ạ :3
Nếu e đọc tới các bài deploy ứng dụng Docker của a thì sẽ thấy a khuyên dùng cách deploy Nginx ở môi trường gốc thì xử lý HTTPS sẽ tiện hơn (proxy_pass vào port mà container map ra môi trường gốc)
E chạy nginx trong Docker luôn cũng được vậy thì chú ý phải cho chúng join vào cùng 1 network, đoạn xử lý nhiều domain cũng mất công hơn chút
uk như vậy thì cần cho chúng vô cùng 1 external network rồi gọi e ạ (kiểu này thì traffic sẽ là container - container), hoặc với mỗi container e có thể map port ra môi trường gốc, rồi ở container khác khi gọi thì gọi tới mt gốc bằng host.docker.internal:<mapped_port> (kiểu này traffic sẽ là container -> gốc -> container, ưu điểm là ko cần cho vào cùng 1 network)
A khuyên nên dùng kiểu container -> container e ạ (cho join vào 1 network), traffic ko đi ra mt ngoài, về mặt kĩ thuật thì sẽ bảo mật và cũng nhanh hơn nữa, đồng thời việc gom nhóm những container chung business cũng giúp phân tách nhiệm vụ rõ ràng khi nhìn vào kiến trúc hệ thống
@maitrungduc1410 em cảm ơn a nhiều ạ. Còn vấn đề nếu e có bao nhiều repo và bấy nhiêu repo đó cần sử dùng webserver như nginx thì điều này lên prod hoàn toàn ko có vấn đề gì ngoại trừ chắc là sẽ tốn tài nguyên hơn so với dùng chung 1 con nginx (chưa tính nginx ở ngoài host làm proxy) đúng ko ạ.
hello anh, em chỉ muốn để lại lời cảm ơn vì những nội dung anh đã phổ cập, rất clean và dễ hiểu, giúp em gỡ rối được rất nhiều khuất mắc, em mong có dịp được nói chuyện và học hỏi từ anh trên facebook lẫn ngoài đời
hi anh, em có vài câu hỏi về asynchronous trong c# mong anh giải ngố giúp em
Sự khác nhau giữa Task và async - await
việc chờ của Task.whenAll(task1, task2) khác nhau chỗ nào với await 2 function
Khi nào nên dùng task?
Tác động của 2 thằng với thread ra sao? em có research thì thấy Task chạy trên thread pool và async - await thì chạy trên main thread nhưng em còn mơ hồ về nó quá
A sẽ giải thích từng câu hỏi của e về Task và async/await trong C# nhé:
Sự khác nhau giữa Task và async - await
Task là một loại đối tượng đại diện cho một công việc (job) sẽ chạy bất đồng bộ, có thể có hoặc không có kết quả trả về. Task thường được sử dụng khi e muốn chạy một công việc ở background
async - await là cú pháp trong C# giúp e có thể dễ dàng viết mã bất đồng bộ hơn. Khi sử dụng async và await, C# sẽ giúp ta "chờ" công việc chạy xong mà không khóa luồng chính. async được thêm vào trước định nghĩa hàm để đánh dấu hàm đó là bất đồng bộ, còn await được dùng để chờ một Task hoàn thành.
Sự khác nhau giữa Task.WhenAll(task1, task2) và await 2 function
Task.WhenAll(task1, task2): Khi e gọi Task.WhenAll, nó sẽ bắt đầu chạy cả hai task1 và task2 đồng thời và chờ cho đến khi cả hai hoàn thành. Đây là cách để e chờ nhiều tác vụ cùng một lúc và nhận kết quả của cả hai khi hoàn thành.
await hai lần (ví dụ await func1() rồi await func2()): Khi e await từng hàm một, nó sẽ chờ func1 hoàn thành trước rồi mới chạy func2. Điều này khác với Task.WhenAll, vì trong trường hợp này các hàm sẽ chạy tuần tự thay vì chạy song song.
Khi nào nên dùng Task?
Sử dụng Task khi:
E có một công việc cần chạy bất đồng bộ nhưng không cần "chờ" nó trong luồng chính, hoặc có thể để cho nhiều công việc chạy cùng lúc.
E cần quản lý các tác vụ (tasks) trong một mảng hoặc danh sách, ví dụ như xử lý nhiều yêu cầu đồng thời từ API.
Task có thể giúp e tận dụng CPU tốt hơn vì nó không block thread khi chờ.
Tác động của Task và async - await đến thread
Task thường chạy trên thread pool, có nghĩa là nó sẽ tìm và sử dụng một thread trong pool để chạy. Nó không nhất thiết là main thread. Nếu một Task chỉ đợi I/O, thread của nó có thể được giải phóng và sử dụng lại, giúp tối ưu CPU và bộ nhớ.
async - await: Khi e await một công việc bất đồng bộ, await sẽ tạm thời "trả lại" quyền điều khiển main thread cho các công việc khác (nếu await đang ở trong main thread). async - await sẽ không nhất thiết chạy trên main thread nếu các công việc có thể chạy ở background, nhưng khi có kết quả, kết quả sẽ quay về main thread.
Nếu e đã code Javascript thì mấy cái này nghe rất giống async/await, Promise.all() 😆
Hy vọng giải thích này giúp e hiểu rõ hơn về Task và async - await trong C#.
A thì không chuyên C# đâu nhưng cũng có đọc về mô hình async/await của nó (tại vì lúc xem qua thấy nó na ná bên JS nên dễ tiếp cận 😜)
Chuẩn r e, ở các công nghệ như WPF, WinForms của .NET và Swift trên iOS, Main Thread thường được gọi là UI Thread vì nó chịu trách nhiệm xử lý và cập nhật giao diện người dùng (UI).
WPF và WinForms: Trong các ứng dụng desktop C# này, Main Thread là UI Thread. Các thao tác như vẽ giao diện, cập nhật các thành phần UI (như Button, TextBox) đều diễn ra trên thread này. Nếu thực hiện các công việc nặng trên UI Thread, như xử lý dữ liệu lớn hay gọi API lâu, thì UI sẽ bị "đơ" (không phản hồi) vì các công việc này đang chiếm tài nguyên của UI Thread.
Swift (iOS): Trong ứng dụng iOS, UI Thread cũng là Main Thread, và việc cập nhật UI phải được thực hiện trên thread này. Apple khuyến cáo rằng các công việc liên quan đến UI đều phải chạy trên Main Thread để đảm bảo tính nhất quán và mượt mà.
Do đó, khi làm việc với các công nghệ này, e cần tránh thực hiện các công việc nặng trên UI Thread. Thay vào đó, e nên dùng các tác vụ bất đồng bộ hoặc các thread khác để xử lý chúng, sau đó chuyển kết quả về UI Thread để cập nhật giao diện khi cần thiết (ví dụ như sử dụng DispatchQueue.main.async trong Swift hoặc Dispatcher.Invoke trong WPF).
Hi anh, em đang nghiên cứu về SOLID, về mặt lý thuyết thì em có thể thuộc lòng nhưng cách triển khai trong thực tế thì em còn đang mơ màng quá, anh có thể giải ngố giúp em bằng một ví dụ về nó không? em cảm ơn anh
hello e, SOLID là một bộ nguyên tắc rất hữu ích để giúp code dễ bảo trì và mở rộng. Tuy nhiên, a cũng đồng ý là trong thực tế, không phải lúc nào mình cũng áp dụng máy móc tất cả các nguyên tắc này được, vì còn phụ thuộc vào bối cảnh dự án, thời gian, và cả đội ngũ nữa.
Ví dụ đơn giản, với nguyên tắc Single Responsibility Principle (S), giả sử em viết một class để quản lý User. Nếu class này vừa lo việc xử lý logic tài khoản, vừa gửi email thông báo, thì em đã vi phạm S. Để cải thiện, em có thể tách việc gửi email ra thành một class hoặc service riêng. Điều này giúp code rõ ràng hơn và dễ thay đổi khi, ví dụ sau này mà mình cần chuyển từ gửi email sang gửi SMS thì cũng dễ hơn.
Các nguyên tắc khác e search thêm gg nhé
Tuy nhiên, anh nghĩ điều quan trọng nhất là hiểu mục đích của SOLID và áp dụng linh hoạt, chứ không nên gò bó. Có lúc em sẽ thấy việc làm theo tất cả các nguyên tắc ngay từ đầu có thể khiến code phức tạp không cần thiết, nhưng khi dự án lớn lên, việc đó lại phát huy tác dụng. Vì vậy, cứ từ từ rèn luyện tư duy thiết kế code, kết hợp với kinh nghiệm thực tế, dần dần em sẽ tìm ra cách áp dụng SOLID phù hợp nhất cho mình.
@maitrungduc1410 dạ em cảm ơn anh, sau khi tìm hiểu thì em cũng đã nắm được các ý của S.O.L.I, còn chữ D - Dependency inversion principle thì em chưa hiểu lắm, theo lý thuyết thì sẽ là :
"Đảo ngược Phụ thuộc nói rằng các class nên phụ thuộc vào interface hoặc abstraction thay vì các class và chức năng cụ thể. Điều này làm cho các class mở rộng, tuân theo nguyên tắc Mở/đóng."
theo em hiểu thì trong thực tế nguyên tắc này sẽ liên quan tới Dependency injection, nhưng em không hiểu nguyên lý triển khai nó, anh có thể giải thích giúp em chỗ này không ạ?
E đúng rồi đó, Dependency Inversion Principle (DIP) liên quan chặt chẽ đến Dependency Injection (DI) trong thực tế. Để anh giải thích thêm nhé.
Về nguyên tắc, DIP nói rằng:
Các module cấp cao (High-level modules) không nên phụ thuộc trực tiếp vào các module cấp thấp (Low-level modules), mà cả hai nên phụ thuộc vào abstraction (interface hoặc lớp trừu tượng).
Abstraction không nên phụ thuộc vào chi tiết, mà chi tiết nên phụ thuộc vào abstraction.
Trong thực tế, DI là một cách triển khai nguyên tắc này. DI giúp "tiêm" các dependency (phụ thuộc) từ bên ngoài vào, thay vì để các class tự tạo hoặc quản lý chúng. Điều này làm cho code linh hoạt hơn và dễ dàng thay đổi các dependency khi cần.
Ví dụ thực tế:
Giả sử e đang xây dựng một ứng dụng gửi thông báo, có hai cách gửi là Email và SMS.
Nếu không áp dụng DIP:
classNotificationService{privateEmailService emailService =newEmailService();// Phụ thuộc trực tiếp vào EmailServicepublicvoidsendNotification(String message){
emailService.sendEmail(message);}}
Ở đây, NotificationService bị "gắn cứng" với EmailService. Nếu muốn đổi sang SMSService, e phải sửa code trong NotificationService, vi phạm nguyên tắc Open/Closed.
Nếu áp dụng DIP và sử dụng DI:
interfaceMessageService{voidsendMessage(String message);}classEmailServiceimplementsMessageService{publicvoidsendMessage(String message){System.out.println("Sending Email: "+ message);}}classSMSServiceimplementsMessageService{publicvoidsendMessage(String message){System.out.println("Sending SMS: "+ message);}}classNotificationService{privateMessageService messageService;// Inject dependency qua constructorpublicNotificationService(MessageService messageService){this.messageService = messageService;}publicvoidsendNotification(String message){
messageService.sendMessage(message);}}// Sử dụngpublicclassMain{publicstaticvoidmain(String[] args){MessageService emailService =newEmailService();NotificationService notification =newNotificationService(emailService);
notification.sendNotification("Hello World!");// Thay đổi sang SMS mà không cần sửa NotificationServiceMessageService smsService =newSMSService();
notification =newNotificationService(smsService);
notification.sendNotification("Hello SMS!");}}
Trong ví dụ này, NotificationService chỉ phụ thuộc vào abstraction (MessageService), không phụ thuộc vào implementation cụ thể (EmailService hay SMSService). Dependency Injection giúp "tiêm" dependency từ bên ngoài vào, giúp code dễ mở rộng và thay đổi mà không phá vỡ các module khác.
Hi vọng giải thích này giúp e hiểu rõ hơn về DIP nhé 😁
Anh ơi em đang làm một trong những project mà anh hướng dẫn đó là docker-laravel-real-time-chat ạ. Khi em chạy lệnh docker-compose exec app php artisan migrate --seed thì hệ thống lại báo lỗi là SQLSTATE[HY000] [1045] Access denied for user 'laraveluser'@'172.24.0.7' (using password: YES). Em đã search google rồi ạ những vẫn không tìm ra nguyên nhân của việc này. Mong anh có thể giúp em giải đáp thắc mắc ạ. Em cảm ơn anh
chào e, sorry e vì reply chậm, e nên comment vào bài post đó của a chứ
Lỗi của e là do ko kết nối tới được service
db
nhé e. E check lại..env
và trong filedocker-compose.yml
(phần servicedb
) đã chính xác và giống nhau hay chưa?docker-compose ps
xem servicedb
đã chạy ổn định hay chưa, state phải làUp
nhéHi Đức, mình thấy các nội dung update và kiến thức của bạn rất bổ ích và thiết thực cho ae dev. Không biết mình muốn liên hệ đăng share bài viết hoặc hợp tác share bài với bạn, mình có thể liên hệ như thế nào ha? Cảm ơn Đức rất nhiều!
chào bạn,
Cám ơn bạn đã theo dõi blog của mình. Bạn trao đổi qua FB với mình nhé: https://www.facebook.com/maitrungduc1410/ hoặc mail của mình: maitrungduc1410@gmail.com
Hi there, how can we talk? Do you speak English? Let's talk by e-mail? alex@2captcha.com
Here's my email: maitrungduc1410@gmail.com.
Dạ em chào anh, Em là Phượng - HR tại Remitano, hiện tại Remitano đang tuyển Full Stack Dev - với range lương $2500 - $4000 - làm việc full time - Remotely. Không biết hiện tại anh có đang open cho công việc mới không ạh.
Nếu có, em rất mong sớm nhận được phản hồi từ anh qua Comment hoặc email ngocphuong@remitano.com. Have a nice day anh nhé.
chào Phượng,
Cám ơn e đã quan tâm tới profile của a,
hiện tại a chưa open cho job mới nên a xin từ chối cơ hội từ Remitano.
Chúc e tìm được nhiều ứng viên tiềm năng
Chất quá Đức. Nhiều kiến thức hay và rất bổ ích. Không những vậy cách truyền đạt rất dễ hiểu và hấp dẫn. Chúc ông nhiều sức khỏe và có thêm nhiều bài viết hay chia sẻ cho mọi người!
cám ơn ô đã theo dõi, chúc ô bạn đạt đc nhiều thành công
Khi dùng docker mysql, thì docker nó mở port ra outsite truy cập được luôn. Vậy mình làm sao hạn chế chỉ trong host truy cập còn outsite thì không ạ?
Theo a hiểu là e đang muốn như sau:
Ví dụ e map từ port
3306
ra port8080
ở ngoài Host, và e ko muốn Outside World truy cập được vào cổng 8080 ở Host8080
(thường mặc định là ko để bảo mật)mấy bài viết của a hay quá. k biết a có ở hà nội k, xin được học hỏi a chút kinh nghiệm ạ
hiện tại a đang làm ở Singapore e, a cũng muốn về thăm HN quá mà dịch bệnh hơn năm nay chưa có đc về và cũng ko biết bao giờ về đc . Khi nào a có đk về a ới lên (facebook), ae nào muốn thì mình gặp nhau học hỏi
@maitrungduc1410 về là phải thông báo nhé a.
@diephung oke e
@maitrungduc1410 a ơi em có thể xin facebook của a được không ạ.
@diephung e search trên FB "maitrungduc1410" nhé
@maitrungduc1410 e có gửi kết bạn rồi nhé, mong lúc gặp khó khăn có thể nhờ a qua fb được ạ.
@diephung okie e nhé
chào bạn, bạn có email cá nhân hk bạn, minh xin trao đổi kinh nghiệm được ko ạ
Mình cám ơn
ping mình qua FB nhé: https://www.facebook.com/maitrungduc1410/
Chào anh ạ! Thấy anh có các bài viết hay chia sẻ về DevOps. Bên em muốn liên hệ hợp tác cùng anh tham gia dự án đào tạo về DevOps (parttime) và chia sẻ các bài viết. Nếu anh quan tâm, anh có thể cho em xin thông tin email để em tiện kết nối ạ. Hoặc anh có thể gửi thông tin qua mail: manpham@techmaster.vn hoặc zalo: 0963023185 để em tiện liên hệ với ạ. Em cảm ơn!
Hi anh, em đang gặp vấn đề access denied của mysql trên docker. Khi em docker compose down rồi lại bật lên thì dính lỗi access denied không thể truy cập db kể cả dùng tài khoản root và phải import lại db. Em đã thử các cách như đổi tên service, sử dụng file .env rồi nhưng không được. Mong anh giải đáp giúp em, em cảm ơn ! Dưới đây là file docker-compose.yml em đang dùng.
thật khó để nói chính xác lỗi của e là gì nếu không debug, nhưng với các dạng lỗi như thế này, phỏng đoán khả năng rất cao là đoạn e mount volumn cho
db
kia có vấn đề lúc shutdown.Và thường nếu dính lỗi về volume mà không hiểu gì đang xảy ra thì tốt nhất là ta đổi từ local volume sang dùng Docker volume
Chào Đức. Mình đang tìm hiểu về mô hình microfrontend, bài viết của Đức rất hay. Mình muốn hỏi KN của Đức về bảo mật microfrontend. Giải pháp nào để chỉ cho phép người dùng truy cập link appshell mà không cho phép truy cập trực tiếp link microfrontend (nếu họ biết được link). Thanks Đức
hi bạn, có rất nhiều cách để bảo mật MFE
Lý do bên mình làm theo
cách 1
là muốn giữ tất cả các app (app shell, các MFE), mỗi chúng nó là 1 deployment riêng (kiểu 1 microservice), độc lập, quy trình build+deploy như nhau, cả kiến trúc đồng nhất, và MFE có thể chạy đc ở nhiều app shell khác nhau nữa.Về vấn đề bảo mật thì mình thấy sẽ có ti tỉ cách làm, tuỳ công ty, tuỳ project nữa, bên trên là vài cách mình vừa nghĩ ra )
Hi Đức Master, anh hỏi chút về docker. A làm theo bài này: https://geshan.com.np/blog/2023/01/nextjs-docker/ gặp lỗi: Error: EACCES: permission denied, unlink '/app/.next/build-manifest.json'. Đức có thể fix và giải thích cái lỗi này giúp anh được không ?
A đang dùng docker trên win/mac hay linux ạ?
A có đang chạy với docker compose ko? Có thì cho e xem file docker-compose.yml ạ
@maitrungduc1410 Ubuntu 22.04.3, docker compose version 2, còn file docker-compose.yml là ở trong bài post đó. Anh build và run bằng docker compose như bài đó.
@dangduytung ở môi trường ngoài, root folder project a chạy command này sau đó khởi động lại project nhé:
@maitrungduc1410 Được rồi em ơi, cái này có cách nào không phải chạy lệnh cấp quyền kia không nhỉ, ví dụ lỡ có ngày đổi user trong docker-compose.yml ý
@dangduytung bởi vì cái bài a đang xem nó dùng user 1001:1001 và ở
docker-compose.yml
nó còn map volume toàn bộ folder ngoài vào trong container, nên permission của folder ở ngoài có thể ảnh hưởng tới bên trong container:Đó là lí do vì sao phải chạy lại lệnh cấp quyền như e nói.
Nếu a ko muốn đau đầu vụ user non-root này thì a đơn giản là dùng mặc định user
root
của image thôi ạ:A để ý những chỗ bên trên e comment ạ, e đã bỏ đoạn đổi sang chạy với user
nextjs
@maitrungduc1410 ok, thanks e, phần này anh đã hiểu sơ sơ rùi.
Chào e! A xem series docker của e và thấy có rất nhiều kiến thức bổ ích. a cũng muốn triển khai 1 vài cái app nhỏ ở cty anh trên 1 cái host trong mạng nội bộ dưới dạng docker. Đọc bài của e a cảm thấy khi triển khai trên docker windows (windows là OS của host, ko phải của container) có vẻ có 1 số điểm không được tương thích toàn bộ như trên docker linux. hiện tại host của a chạy windows vì khi cần sửa đổi cập nhật gì a có thể làm từ xa ở nhà thông qua teamview. a đang định cái headless linux lên host chỉ để chuyên chạy docker container nhưng đang lo ngại là khi chỉnh sửa, cập nhật gì thì mình không thể ssh từ nhà lên host được (cơ quan anh ko có ip tĩnh). A muốn hỏi kinh nghiệm của em là có cách nào có thể truy cập máy linux từ xa mà không cần ip tĩnh không, như giải pháp của teamview vậy? Cám ơn em trước nhé.
hello a,
về vụ dynamic IP, thì a viết 1 cái script nhỏ, đặt trên host trên cty của a (theo như a nói thì host này đang chạy windows), script chạy như cronjob, check IP hiện tại của host, và nếu có thay đổi thì gửi nó về cho a (qua email chẳng hạn)
và a vẫn SSH vào như bình thường với
user@IP
ạ@maitrungduc1410 Cám ơn e đã phản hồi. a quên mất là ngoài việc không có ip tĩnh, lại còn không open port được modem ở cơ quan nữa ý e, vì mạng dùng chung với cả các đơn vị khác, 1 mình mình không thể open port được
@tienhung1611 ý a là ko có port để SSH vào ạ?
@maitrungduc1410 đúng rồi e, không có port SSH để vào ý. nếu ngồi trong mạng LAN thì có thể SSH thoải mái. nhưng khi ngồi nhà, muốn SSH qua internet thì có 2 hạn chế là: ko có ip tĩnh và không có SSH port. thế nên hiện tại a phải dùng windows và cài docker desktop lên đó. Nếu cần chỉnh sửa gì từ nhà thì chạy teamviewer vào là xong. Giờ a ko muốn dùng windows nữa mà muốn cài linux lên máy đó, chuyên để chạy docker nhưng lại vướng khoản remote
@tienhung1611 vậy thì a cài Ubuntu lên máy cty rồi vẫn dùng TeamViewer được mà đúng ko ạ?
@maitrungduc1410 a đã thử cài teamviewer trên linux rồi nhưng không được e ạ. Vì cài linux cũng mất công nên trước khi cài chính thức, a cài teamviewer trên docker container ubuntu:jammy. việc cài đặt thì không báo lỗi gì tuy nhiên khi chạy lệnh teamviewer setup để cài unattended access thì nó bảo lỗi teamviewer daemon not running trong khi a đã thử restart cái daemon này nhiều lần. chạy lệnh teamviewer status cũng cho thấy daemon đang ở trạng thái running
@tienhung1611 a đã thử trên ubuntu chưa ạ? https://www.teamviewer.com/apac/download/linux/
E thấy có vẻ khả thi mà (ý e là a cài Ubuntu lên máy ko phải là headless linux đâu ạ)
@maitrungduc1410 a cám ơn Đức nhé, cám ơn e đã nhiệt tình trả lời. Hôm nay a đã cài teamviewer thành công lên bản ubuntu server được cài lên virtualbox rồi. Có lẽ ubuntu container nó bị lược đi những package nào đó rất đến việc khởi chạy teamviewerd không được. A đang tính thêm 1 số cách khác như: sử dụng ssh tunneling, máy chủ trung gian có thể dùng azure virtual machines cấu hình thấp; hoặc sử dụng ssh thông qua tor hidden services. em có thấy những cách này có kỳ quái lắm ko 😅
@tienhung1611 dạ vậy thì hơi cách rách a ạ ),
tập trung vào cái chính mình muốn làm đấy là chạy mấy app dùng container ạ.
nếu khó quá thì a xem mua 1 con VPS cùi cùi 5-10$ tháng (e thấy trên digital ocean rẻ lăm)
Cho mình hỏi chút! Nếu dùng micro frontend như bạn hướng dẫn và sử dụng nx thì bạn đánh giá nso thế nào
ổn áp đó bạn, nx làm monorepo thì ưng rồi, share dependencies + build cũng tối ưu và nhanh hơn.
Thực tế ở trên cty (cũ) mình build microfrontend framework với nx đó 😄
idol viết bài hay quá, kb a có ny chưa
a sắp lấy vợ rồi e ạ 🤪
@maitrungduc1410 haha tiếc quá, chưa có thì cho e lq :v
🤣🤣 @Sammy26 🤣
@maitrungduc1410 a có kn bn năm làm frontend r ạ.
@Sammy26 ko tính thực tập thì từ lúc a ra trường, tầm 6 năm e ạ
Chào anh. Không biết có ai hỏi chưa nhưng e đang có nhu cầu deploy project cá nhân lên vps bằng docker. Nhưng vì project có vài ba repository và mỗi repo e lại setup docker compose riêng lẻ cho nó nên giờ e đang mắc 2 vấn đề hi vọng đc a giái đáp:
hi e
proxy_pass
vào port mà container map ra môi trường gốc)host.docker.internal:<mapped_port>
(kiểu này traffic sẽ là container -> gốc -> container, ưu điểm là ko cần cho vào cùng 1 network)@maitrungduc1410 em cảm ơn a nhiều ạ. Còn vấn đề nếu e có bao nhiều repo và bấy nhiêu repo đó cần sử dùng webserver như nginx thì điều này lên prod hoàn toàn ko có vấn đề gì ngoại trừ chắc là sẽ tốn tài nguyên hơn so với dùng chung 1 con nginx (chưa tính nginx ở ngoài host làm proxy) đúng ko ạ.
@just-pthai-it đúng r e ạ, nhưng nginx khá nhỏ nhẹ và nhanh, thường thì resource nó tiêu tốn cũng ko đáng kể e ạ
@maitrungduc1410 e cảm ơn a nhiều
hello anh, em chỉ muốn để lại lời cảm ơn vì những nội dung anh đã phổ cập, rất clean và dễ hiểu, giúp em gỡ rối được rất nhiều khuất mắc, em mong có dịp được nói chuyện và học hỏi từ anh trên facebook lẫn ngoài đời
thanks e đã theo dõi blog của a. kb qua fb của a nhé: https://www.facebook.com/maitrungduc1410/
@maitrungduc1410
hi anh, em có vài câu hỏi về asynchronous trong c# mong anh giải ngố giúp em
Sự khác nhau giữa Task và async - await
việc chờ của Task.whenAll(task1, task2) khác nhau chỗ nào với await 2 function
Khi nào nên dùng task?
Tác động của 2 thằng với thread ra sao? em có research thì thấy Task chạy trên thread pool và async - await thì chạy trên main thread nhưng em còn mơ hồ về nó quá
@kvi
A sẽ giải thích từng câu hỏi của e về Task và async/await trong C# nhé:
async - await
là cú pháp trong C# giúp e có thể dễ dàng viết mã bất đồng bộ hơn. Khi sử dụng async và await, C# sẽ giúp ta "chờ" công việc chạy xong mà không khóa luồng chính. async được thêm vào trước định nghĩa hàm để đánh dấu hàm đó là bất đồng bộ, còn await được dùng để chờ một Task hoàn thành.Task.WhenAll
, nó sẽ bắt đầu chạy cả hai task1 và task2 đồng thời và chờ cho đến khi cả hai hoàn thành. Đây là cách để e chờ nhiều tác vụ cùng một lúc và nhận kết quả của cả hai khi hoàn thành.await hai lần (ví dụ await func1() rồi await func2()): Khi e await từng hàm một, nó sẽ chờ func1 hoàn thành trước rồi mới chạy func2. Điều này khác với
Task.WhenAll
, vì trong trường hợp này các hàm sẽ chạy tuần tự thay vì chạy song song.E có một công việc cần chạy bất đồng bộ nhưng không cần "chờ" nó trong luồng chính, hoặc có thể để cho nhiều công việc chạy cùng lúc. E cần quản lý các tác vụ (tasks) trong một mảng hoặc danh sách, ví dụ như xử lý nhiều yêu cầu đồng thời từ API. Task có thể giúp e tận dụng CPU tốt hơn vì nó không block thread khi chờ.
async - await: Khi e await một công việc bất đồng bộ, await sẽ tạm thời "trả lại" quyền điều khiển main thread cho các công việc khác (nếu await đang ở trong main thread). async - await sẽ không nhất thiết chạy trên main thread nếu các công việc có thể chạy ở background, nhưng khi có kết quả, kết quả sẽ quay về main thread.
Hy vọng giải thích này giúp e hiểu rõ hơn về Task và async - await trong C#.
A thì không chuyên C# đâu nhưng cũng có đọc về mô hình async/await của nó (tại vì lúc xem qua thấy nó na ná bên JS nên dễ tiếp cận 😜)
@maitrungduc1410 dạ em cảm ơn anh, anh cho em hỏi, Main thread trên 1 số công nghệ như WPF, Winform, swift... chính là UI Thread đúng không anh ?
@kvi
Chuẩn r e, ở các công nghệ như WPF, WinForms của .NET và Swift trên iOS, Main Thread thường được gọi là UI Thread vì nó chịu trách nhiệm xử lý và cập nhật giao diện người dùng (UI).
WPF và WinForms: Trong các ứng dụng desktop C# này, Main Thread là UI Thread. Các thao tác như vẽ giao diện, cập nhật các thành phần UI (như
Button
,TextBox
) đều diễn ra trên thread này. Nếu thực hiện các công việc nặng trên UI Thread, như xử lý dữ liệu lớn hay gọi API lâu, thì UI sẽ bị "đơ" (không phản hồi) vì các công việc này đang chiếm tài nguyên của UI Thread.Swift (iOS): Trong ứng dụng iOS, UI Thread cũng là Main Thread, và việc cập nhật UI phải được thực hiện trên thread này. Apple khuyến cáo rằng các công việc liên quan đến UI đều phải chạy trên Main Thread để đảm bảo tính nhất quán và mượt mà.
Do đó, khi làm việc với các công nghệ này, e cần tránh thực hiện các công việc nặng trên UI Thread. Thay vào đó, e nên dùng các tác vụ bất đồng bộ hoặc các thread khác để xử lý chúng, sau đó chuyển kết quả về UI Thread để cập nhật giao diện khi cần thiết (ví dụ như sử dụng
DispatchQueue.main.async
trong Swift hoặcDispatcher.Invoke
trong WPF).Hi anh, em đang nghiên cứu về SOLID, về mặt lý thuyết thì em có thể thuộc lòng nhưng cách triển khai trong thực tế thì em còn đang mơ màng quá, anh có thể giải ngố giúp em bằng một ví dụ về nó không? em cảm ơn anh
hello e, SOLID là một bộ nguyên tắc rất hữu ích để giúp code dễ bảo trì và mở rộng. Tuy nhiên, a cũng đồng ý là trong thực tế, không phải lúc nào mình cũng áp dụng máy móc tất cả các nguyên tắc này được, vì còn phụ thuộc vào bối cảnh dự án, thời gian, và cả đội ngũ nữa.
Ví dụ đơn giản, với nguyên tắc Single Responsibility Principle (S), giả sử em viết một class để quản lý User. Nếu class này vừa lo việc xử lý logic tài khoản, vừa gửi email thông báo, thì em đã vi phạm S. Để cải thiện, em có thể tách việc gửi email ra thành một class hoặc service riêng. Điều này giúp code rõ ràng hơn và dễ thay đổi khi, ví dụ sau này mà mình cần chuyển từ gửi email sang gửi SMS thì cũng dễ hơn.
Tuy nhiên, anh nghĩ điều quan trọng nhất là hiểu mục đích của SOLID và áp dụng linh hoạt, chứ không nên gò bó. Có lúc em sẽ thấy việc làm theo tất cả các nguyên tắc ngay từ đầu có thể khiến code phức tạp không cần thiết, nhưng khi dự án lớn lên, việc đó lại phát huy tác dụng. Vì vậy, cứ từ từ rèn luyện tư duy thiết kế code, kết hợp với kinh nghiệm thực tế, dần dần em sẽ tìm ra cách áp dụng SOLID phù hợp nhất cho mình.
@maitrungduc1410 dạ em cảm ơn anh, sau khi tìm hiểu thì em cũng đã nắm được các ý của S.O.L.I, còn chữ D - Dependency inversion principle thì em chưa hiểu lắm, theo lý thuyết thì sẽ là :
"Đảo ngược Phụ thuộc nói rằng các class nên phụ thuộc vào interface hoặc abstraction thay vì các class và chức năng cụ thể. Điều này làm cho các class mở rộng, tuân theo nguyên tắc Mở/đóng."
theo em hiểu thì trong thực tế nguyên tắc này sẽ liên quan tới Dependency injection, nhưng em không hiểu nguyên lý triển khai nó, anh có thể giải thích giúp em chỗ này không ạ?
@kvi
E đúng rồi đó, Dependency Inversion Principle (DIP) liên quan chặt chẽ đến Dependency Injection (DI) trong thực tế. Để anh giải thích thêm nhé.
Về nguyên tắc, DIP nói rằng:
Trong thực tế, DI là một cách triển khai nguyên tắc này. DI giúp "tiêm" các dependency (phụ thuộc) từ bên ngoài vào, thay vì để các class tự tạo hoặc quản lý chúng. Điều này làm cho code linh hoạt hơn và dễ dàng thay đổi các dependency khi cần.
Ví dụ thực tế:
Giả sử e đang xây dựng một ứng dụng gửi thông báo, có hai cách gửi là Email và SMS.
Nếu không áp dụng DIP:
Ở đây,
NotificationService
bị "gắn cứng" vớiEmailService
. Nếu muốn đổi sangSMSService
, e phải sửa code trongNotificationService
, vi phạm nguyên tắc Open/Closed.Nếu áp dụng DIP và sử dụng DI:
Trong ví dụ này,
NotificationService
chỉ phụ thuộc vào abstraction (MessageService
), không phụ thuộc vào implementation cụ thể (EmailService
haySMSService
). Dependency Injection giúp "tiêm" dependency từ bên ngoài vào, giúp code dễ mở rộng và thay đổi mà không phá vỡ các module khác.Hi vọng giải thích này giúp e hiểu rõ hơn về DIP nhé 😁