python |
Pythonタグが付けられた新着投稿 - Qiita |
天下一リバーシAI武道会 |
https://qiita.com/y-tetsu/items/2a32a157567655fa12ac
|
ytetsu |
2023-04-24 21:30:24 |
python |
Pythonタグが付けられた新着投稿 - Qiita |
PythonでExcelファイルに画像を挿入する/列の幅を調整する |
https://qiita.com/kaba_san/items/b231a41891ebc240efc7
|
excel |
2023-04-24 21:24:35 |
AWS |
AWSタグが付けられた新着投稿 - Qiita |
【AWS Amplify Studio + Figma + React】Amplify StudioとFigmaを同期してReactコンポーネントを自動生成する手順 |
https://qiita.com/whopper1962/items/2699d9514ac58f738b83
|
figma |
2023-04-24 21:38:36 |
golang |
Goタグが付けられた新着投稿 - Qiita |
UNIQLO Akamai Tシャツコード - Goによる平行処理 - |
https://qiita.com/GL-Kageyama/items/8cf75a6d4bd055ee7857
|
akamai |
2023-04-24 21:04:36 |
Ruby |
Railsタグが付けられた新着投稿 - Qiita |
【rails】simple_calendarを用いたカレンダー機能にて、複数日程にも対応できるようにする。 |
https://qiita.com/00000000/items/b03c373226217daf7e77
|
rails |
2023-04-24 21:56:06 |
技術ブログ |
Developers.IO |
[レポート] Amazon におけるオブザーバビリティのベストプラクティス #COP343 #reinvent |
https://dev.classmethod.jp/articles/cop343-observability-best-practices-at-amazon-reinvent-2022/
|
amazon |
2023-04-24 12:37:44 |
海外TECH |
DEV Community |
Top-10 Posts for FE (Week 3, Apr 2023) |
https://dev.to/fruntend/top-10-posts-for-fe-week-3-apr-2023-5975
|
Top Posts for FE Week Apr Here are the top posts from the past week that will be useful to front end developers and beyond The selection was made on the basis of their interestingness uniqueness presentation usefulness and subjective assessment of the author The Acronyms of Rendering on the WebThe article explains the concepts of frame rate vertical synchronization and graphics processing unit and how they affect the rendering of web content with practical tips on optimization Polyfills for JavaScript A Full OverviewThis article provides a comprehensive overview of polyfills in JavaScript including their usage benefits and how to write your own polyfill code Naming Every Developer s NightmareThe article discusses the importance of naming conventions in software development and provides some tips on how to choose good names for variables functions and classes Unlock CSS Power with These Essential Tips for BeginnersThis article provides five essential tips for beginners to unlock the power of CSS including selecting the right selectors using box sizing mastering positioning understanding the cascade and inheritance and leveraging CSS preprocessors What s new in Angular This article explores the new features and improvements introduced in Angular including updates to the Angular CLI improved support for Web Components and more Understanding CSS Min Max and Clamp FunctionsThis article explores the three new CSS functions min max and clamp and how they can be used to simplify responsive web design by providing flexible and dynamic values for CSS properties Introduction to Web Animations with GSAPThis article provides a exhaustive introduction to web animations using GSAP GreenSock Animation Platform including the basic concepts syntax and techniques for creating engaging and responsive animations on the web A Complete Guide To CSS HeadersThis detailed guide covers everything you need to know about creating headers in CSS including various styling techniques using pseudo elements and responsive design Next js fundamentalsThe article is a teachable guide to Next js covering its core concepts and features such as server side rendering static site generation data fetching and deployment and also provides practical examples to illustrate how to use Next js effectively for building fast scalable and maintainable web applications VS Code Extensions to Take Your Coding to the Next LevelThis article provides a itemized list of Visual Studio Code extensions across different categories such as productivity code editing and version control to enhance the coding experience for developers |
2023-04-24 12:40:52 |
海外TECH |
DEV Community |
Creating A Hot New Food Delivery App with Novu |
https://dev.to/novu/creating-a-hot-new-food-delivery-app-with-novu-2e75
|
Creating A Hot New Food Delivery App with Novu TL DRIn this tutorial we ll create a tool to manage a notification system for a food delivery app To do so we ll use the power of the open source notification infrastructure from Novu alongside our custom platform and PostMark Join the ConnectNovu HackathonShowcase your skills push the boundaries of innovation and meet like minded community members ConnectNovu Hackathon is a global event focused on notifications If you love playing with In App SMSs Push notifications Emails and chats that s the place for you Are you ready to build the next big thing JOIN HERE The Kick OffWe all love the new era of delivery apps No calls complete your order on your phone in minutes pay a huge delivery fee and then eagerly wait until our food arrives at our door But in this process those delivery apps keep you in the loop for the entire operation ーfrom order placed to package delivered But to do so you ll need a robust notification system to take care of it In this tutorial we will learn how to create a notification management system for a food delivery app using Novu a powerful open source notification infrastructure If you want to jump to the source code for this tutorial check it out here Jumping Into BusinessFor this tutorial we ll just start with a simple app named Foody We ll create the project with Nuxt and Supabase but you can tag along with any JavaScript framework you d like You ll also need the LTS version of Node js too Typically there are a set of notifications we d expect to receive in any e commerce service and the food delivery system is no exception For Foody we ll need at least the following types of notifications Customer hospitality notifications Welcoming and thanking users Service specific notifications Order placement delivery status feedback requests promotions Legal and security updates notifications Terms and privacy etc Let s see how Novu can handle some of these notifications in a food delivery service context Getting Our Project StartedWe ll need to sign up for a Novu account and start setting up our project After that we must set up at least one delivery provider That delivery provider will be used to manage all of our notifications within our app So head over to the Integration Store to see our options At the time of writing Novu supports three notification channels email SMS and an in app notification center If you want to create a notification provider other than the provided ones check out their documentation We ll set up a new provider using Postmark for Foody Let s go ahead and do this Setting Up PostMarkStarting off we ll need a PostMark account too Once that s done we ll need to verify a sender and create a new Server API Token if one doesn t already exist Back at the Novu Integration Store page click connect on Postmark fill in the Server API token as the API Key on the form presented and set from email to the sender verified on Postmark Lastly provide a sender name toggle the provider to active and click the connect button Creating Notifications on NovuTo create a new notification on Novu click the Notifications page and the New button on the top right side Fill in the notification settings for the new template by providing the Notification Name Notification Description and Notification Group which is set to General by default Send A Welcome NotificationFor Foody we ll set up a customer welcoming email to demonstrate how to set up notifications in Novu Fill in the fields in the previous figure setting the Notification Name to welcome new user and the Notification Description to Notification for welcoming newly registered users Proceed to the new notification s Workflow Editor tab to add steps In our case we want to send an email notification welcoming the customer and then receive an in app admin dashboard notification for them So on this page drag the email step to the canvas followed by the in app step Select the email step currently inside the canvas and edit the template You can use the visual template editor or write custom markup for email channels We ll be using the template editor The Steps Variables section on the right side of the editor lists the variables we ve used inside the email template in the handlebars These variables will be populated by the submitted email payload sent through a Novu trigger You can preview and test the created email notification for troubleshooting on completion Back in the workflow editor select the In App step and edit its template too Call this trigger after the user account validation to trigger this notification inside Foody Integrating Novu into FoodyIf you followed the Nuxt app provided for this tutorial the following logic has been set up inside a server API endpoint file server api register notifications subscriber js This notification serves two purposes the first being the registration of the app user as a Novu notifications subscriber and the second being the sending of the welcoming email dependency importsexport default defineEventHandler async event gt variable declarations Send welcome notification to new user const firstName lastName user user metadata full name split await novu trigger welcome new user to subscriberId user id email user user metadata email firstName lastName phone user user metadata phone payload firstName other code Despite not using it in the email template we are providing as much subscriber data as possible to the trigger in the above code Why Because when the trigger is called Novu upserts the data to a new subscriber and if none exists it creates a new one To explicitly create a new subscriber use this await novu subscribers identify user id email firstName lastName phone user user metadata phone After having registered some users we should see the following when visiting the Activity Feed section of the Novu dashboard The activity feed monitors all outgoing messages associated with a Novu project It can monitor activity and discover potential issues with providers or channels Sending Order Specific Notifications with NovuNow that we ve seen how it all works for sending welcome emails to our Foody users let s do it again for our actual orders Sending Order ConfirmationsLike any other food delivery app we want to keep our customers in the loop So next we ll need to set up a notification that confirms their order once it s been placed Create a new notification following the previous steps setting the Notification Name to order confirmation and the Notification Descriptionto Notifying users on order placement For this notification we would like to send a list of dishes the user purchased Hence the suitable way to write the email template would be using the following custom markup lt div gt Hello subscriber firstName lt div gt lt div style padding px gt You successfully placed order number orderNumber lt div gt lt ul style padding px gt each dishes lt li gt count x name lt li gt each lt ul gt lt div style padding px gt Delivery Fees deliveryFee lt div gt lt div style padding px font weight gt Total totalFee lt div gt lt div style padding px gt Please notify us if any dish is out of order lt div gt We can see two new things in the above template that differentiate it from the email templates we created earlier First we have the subscriber firstName variable Novu manages an app s users in a specific subscribers data model which allows the API to manage different aspects of the notification flow while providing an easy interface for triggering notifications The subscriber firstName variable comes from the user data point of the subscriber object allowing its placement inside the notification template Other data we can obtain in the user data point include the lastName and avatar The second part that is different from the previous templates is the iteration through the dishes array This is made possible by using the handlebars each helper We also have access to the conditional if handlebars helper which we ll demonstrate its usage in coming sections of notifications To send the order confirmation notifications to our Foody customers using the created template add the following trigger imports and global functionsexport default defineEventHandler async event gt variable declarations order creation logic providing us with orderDetails variable await novu trigger order confirmation to subscriberId user id email user user metadata email payload dishes order dishes orderNumber orderDetails order number deliveryFee order deliveryFee totalFee order totalFee other code Sending Delivery Status NotificationsTo keep customers in the loop we d like to notify them of changes to the delivery status of the orders they place Create a new delivery status notification and use the following code as its template lt div gt Hello subscriber firstName lt div gt lt div style padding px gt You order orderNumber has been status lt div gt lt div style padding px gt Click the following link to give us a feedback of your order if delivered lt p gt lt a href feedbackUrl target blank style padding px gt Give us feedback lt a gt lt p gt if lt div gt Delivery status notifications can be “order picked up “order delivered and more When the order has been delivered with the assistance of the handlebars if helper we can also send the user a link to give us feedback on the delivery The last single subscriber based notification we would create for Foody is a feedback appreciation notification We can use the template editor to make this notification since it s less complex than the last two The following code can be used as the trigger for the notification within the app importsexport default defineEventHandler async event gt Declarations and user feedback database submission logic await novu trigger feedback appreciation to subscriberId user id email user email payload firstName return message Appreciated user Sending Bulk Subscription based Notifications With Novu TopicsWhat about when we need to send bulk notifications to a group or all customers We want to send notifications in bulk for things like promotions discounts service updates and terms and services changes How do we do this without performing the expensive practice of looping through data Novu provides an answer for this pain in the form of Topics Novu Topics allow us to send bulk notifications to a group of users based on any criteria we define With Topics we can send multiple emails to users based on their interests subscriptions or any other possible attribute that can be determined In our scenario we may want to send promotional and discount notifications to customers based on the dishes they frequently buy For instance if we equate a customer buying a particular dish a certain number of times to mean they like it we d add them to a topic that includes customers who like that dish We might name such a topic as customers favorite dish id Adding this sort of functionality to our app will allow us to deliver targeted ads for some of our user bases instead of relying on a shotgun approach to customer engagement Creating a Novu TopicNow that we understand what topics are in Novu let s learn how to create one We will create a topic for Foody that sends promotional notifications to customers based on purchasing behavior just like we discussed earlier But before assigning subscribers to a topic we need to create the topic first In our food delivery service scenario a topic must be created whenever a dish is added to the app s database The following piece of topic creating code would be ideally placed just after the logic that submits a new dish to the database Dish data submission logicconst result await novu topics create key customers favorite newDishData id name Customers that like newDishData name Remember the Novu topic key should be unique and can t be changed once created Adding New Subscribers And Sending NotificationsTo add a new subscriber to a topic we ll need to use the addSubscriber method Order placement logic When customer fulfils criteria to be added to topic involving dish const result await novu topics addSubscribers customer favorites order dishes id subscribers user id Inside the app this should be called just after the order placement code Users will be added to a topic if they fulfill the criteria Having created a topic and added some subscribers the next step would be sending notifications to its subscribers First create a notification for the topic in question such as dish based promotional notification Don t forget to add a template for this too Finally create a trigger that sends the notifications Novu s topic notifications trigger is the same as the one used to send notifications to single subscribers The difference is that on the to field instead of placing the single subscriber s identity we pass an array of topics whose subscribers we d want to receive the notifications Here is a trigger example for the created notification import Novu from novu node import TriggerRecipientsTypeEnum from novu shared export default defineEventHandler async event gt initiate Novu const result await novu trigger dish based promotional notification to type TriggerRecipientsTypeEnum TOPIC topicKey payload promotionTitle promotionDetails Customizing Notification OptionsNot all customers would like to receive every kind of notification from the food delivery service Therefore we should allow them to opt out of some topics What we ll be doing is merely subscriber management within specific topics To demonstrate this we ll go to the dish based promotional notification notification template that we created earlier and add an unsubscribe link at the bottom Since it s not feasible to add a link in the template editor convert the whole template to custom code with the following markup lt div gt Hello subscriber firstName lt div gt lt div style padding px gt We have an offer you wouldn t want to miss lt div gt lt div style padding px gt promotionDetails lt div gt lt div style padding px gt lt a href optOutLink userId subscriber subscriberId amp topicKey topicKey target blank gt Click here lt a gt to unsubcribe from these emails lt div gt We need their subscriber ID and the topic key to remove a subscriber from a topic as demonstrated in the above markup Since we never passed the topic key in the trigger involving this notification we need to make the following changes to it const result await novu trigger dish based promotional notification to type TriggerRecipientsTypeEnum TOPIC topicKey payload promotionTitle promotionDetails topicKey Now we can proceed to create a topic opting out trigger for users As explained we are simply removing the subscriber from the topic To do that we need to call the removeSubscribers method as follows const result await novu topics removeSubscribers topicKey subscribers userId The Wrap UpIt turns out a lot is going on behind the scenes of these food delivery apps While we don t have a fully functioning Foody app we do have an excellent notification infrastructure in place thanks to Novu We used Supabase to handle our user authentication but the most significant part was adding in some notification functionality If you liked what you saw here let us know in the comments below It s been a pleasure and I hope you take Foody to new heights P S ConnectNovu Hackathon is live everybody is invited to register and there are some cool prizes too check it here |
2023-04-24 12:20:01 |
海外TECH |
DEV Community |
A primer on GCP Compute Instance VMs for dockerized Apps [Tutorial Part 8] |
https://dev.to/pascallandau/a-primer-on-gcp-compute-instance-vms-for-dockerized-apps-tutorial-part-8-4k46
|
A primer on GCP Compute Instance VMs for dockerized Apps Tutorial Part Getting started with the Google Cloud Platform GCP to run Virtual Machines VMs and prepare them to run dockerized applications This article appeared first on at A primer on GCP Compute Instance VMs for dockerized Apps Tutorial Part In the eighth part of this tutorial series on developing PHP on Docker we will take a look on the Google Cloud Platform GCP and create a Compute Instance VM to run dockerized applications This includes creating VMsusing a container registryusing a secret managerAll code samples are publicly available in my Docker PHP Tutorial repository on Github You find the branch with the final result of this tutorial at part gcp compute instance vm docker All published parts of the Docker PHP Tutorial are collected under a dedicated page at Docker PHP Tutorial The previous part was Create a CI pipeline for dockerized PHP Apps and the following one is Deploy dockerized PHP Apps to production on GCP via docker compose If you want to follow along please subscribe to the RSS feed or via email to get automatic notifications when the next part comes out Table of contentsIntroductionSet up a GCP projectCreate a service accountCreate service account key fileConfigure IAM permissionsSet up the gcloud CLI toolSet up the Container RegistryAuthenticate dockerPushing images to the registryImages are stored in Google Cloud Storage bucketsPulling images from the registrySet up the Secret ManagerCreate a secret via the UIView a secret via the UIRetrieve a secret via the gcloud cliAdd the secret gpg key and passwordCompute Instances The GCP VMs Create a VMGeneral VM settingsFirewall and networks tagsThe role of the service accountAdding a public SSH keyDefine Availability PoliciesThe actual VM creationLog into a VMLogin via SSH from the GCP UILogin via SSH with your own key from your host machineLogin using the Identity Aware Proxy IAP conceptAdditional notes on IAPGet root permissionsssh and scp commandsgcloud ssh command gcloud scpProvision the VMGet the secret gpg key and password from the Secret ManagerInstalling docker and docker composeAuthenticate docker via gcloudPulling the nginx imageStart the nginx containerAutomate via gcloud commandsPreconditions Project and Owner service accountConfigure gcloud to use the master service accountEnable APIsCreate and configure a deployment service accountCreate secretsCreate firewall rule for HTTP trafficCreate a Compute Instance VMProvisioningDeploymentPutting it all together CleanupWrapping up IntroductionIn the next tutorial we will deploy our dockerized PHP Apps to production via docker compose and will create this production environment on GCP Google Cloud Platform This tutorial serves as a primer on GCP to build up some fundamental knowledge because we will use the platform to provide all the infrastructure required to run our dockerized PHP application In the process we ll learn about GCP projects as our own space in GCP and service accounts as a way to communicate programmatically We ll start by doing everything manually via the UI but will also explain how to do it programmatically via the gcloud cli and end with a fully automated script The following video shows the overall flow Your browser does not support the video tag The API keys see service account key files that I use are not in the repository because I would be billed for any usage I e you must create you own project and keys to follow along Caution Following the steps outlined in this tutorial will incur costs because we will create real infrastructure It won t be much couple of cents and it will very likely be covered by the free grant that you get when trying out GCP or the general unlimited GCP Free Tier But you should still know about that upfront and make sure to shut everything down delete everything in case you re trying it out yourself The safest way to do so is Shutting down deleting the whole project Set up a GCP projectOn GCP resources are organized under so called projects We can create a project via the Create Project UI The project ID must be a globally unique string and I have chosen pl dofroscra p for this tutorial pl gt Pascal Landau dofroscra gt Docker From Scratch p gt production Create a service accountAs a next step we need a service account that we can use to make API requests because we don t want to use our personal GCP account Service accounts are created via the IAM amp Admin gt Service Accounts UI Create service account key fileIn order to use the account programmatically we also need to create a key file by choosing the Manage Keys option of the corresponding service account This will open up a UI at serviceAccountId keyswhere serviceAccountId is the numeric id of the service account e g To create a key click ADD KEY and select Create new key from the drop down menuThis will bring up a modal window to choose the key type select the recommended JSON type and click Create GCP will then generate a new key pair store the public key and offer the private key file as download download the file and make sure to treat it like any other private key ssh gpg i e never share it publicly We will store this file in the root of the codebase at gcp service account key json and add it to the gitignore file Each service account has also a unique email address that consists of its non numeric id and the project id You can also find it directly in the key file grep email gcp service account key json client email docker php tutorial deployment pl dofroscra p iam gserviceaccount com This email address is usually used to reference the service account e g when assigning IAM permissions Configure IAM permissionsIAM stands for Identity and Access Management IAM and is used for managing permissions on GCP The two core concepts are permissions and roles permissions are fine grained for particular actions e g storage buckets create to Create Cloud Storage buckets roles combine a selection of permissions e g the Cloud Storage Admin role has permissions likestorage buckets createstorage buckets getetc roles are assigned to users or service accounts You can find a full overview of all permissions in the Permissions Reference and all roles under Understanding roles gt Predefined roles For this tutorial we ll assign the following roles to the service account user docker php tutorial deployment pl dofroscra p iam gserviceaccount com Storage Admin required to create the GCP bucket for the registry and to pull the images on the VM Secret Manager Adminrequired to retrieve secrets from the Secret ManagerCompute Admin Service Account User and IAP secured Tunnel Userare necessary for logging into a VM via IAP Roles can be assigned through the Cloud Console IAM UI by editing the corresponding user Caution It might take some time usually a couple of seconds until changes in IAM permissions take effect Set up the gcloud CLI toolThe CLI tool for GCP is called gcloud and is available for all operating systems In this tutorial we are using version installed natively on Windows via the GoogleCloudSDKInstaller exe using the Bundled Python option FYI As described under Uninstalling the Google Cloud CLI you can find the installation and config directories via installation directory gcloud info format value installation sdk root C Users Pascal AppData Local Google Cloud SDK google cloud sdk config directory gcloud info format value config paths global config dir C Users Pascal AppData Roaming gcloudI will not use my personal Google account to run gcloud commands thus I m not using the usual initialization process by running gcloud init Instead I will use the service account that we created previously and activate it as described under gcloud auth activate service account viagcloud auth activate service account docker php tutorial deployment pl dofroscra p iam gserviceaccount com key file gcp service account key json project pl dofroscra pOutput gcloud auth activate service account docker php tutorial deployment pl dofroscra p iam gserviceaccount com key file gcp service account key json project pl dofroscra pActivated service account credentials for docker php tutorial deployment pl dofroscra p iam gserviceaccount com FYI Because we are using a json key file that includes the service account ID we can also omit the id in the command i e gcloud auth activate service account key file gcp service account key json project pl dofroscra pActivated service account credentials for docker php tutorial deployment pl dofroscra p iam gserviceaccount com Set up the Container RegistryWe will use docker compose to run our PHP application in the next tutorial part and need to make our docker images available in a container registry Luckily GCP offers a Container Registry product that gives us a ready to use private registry as part of a GCP project Before we can use it the corresponding Google Container Registry API must be enabled You find the Container Registry in the Cloud Console UI under Container Registry Authenticate dockerSince the Container Registry is private we need to authenticate before we can push our docker images The available authentication methods are described in the GCP docu Container Registry Authentication methods For pushing images from our local host system we will use the service account key file that we created previously and run the command shown in the JSON key file section of the the docu key gcp service account key jsoncat key docker login u json key password stdin A successful authentication looks as follows cat key docker login u json key password stdin Login SucceededLogging in with your password grants your terminal complete access to your account For better security log in with a limited privilege personal access token Learn more at So what exactly happens when we run this command According to the docker logindocumentationWhen you log in the command stores credentials in HOME docker config json on Linux or USERPROFILE docker config json on Windows The Docker Engine can keep user credentials in an external credentials store such as the native keychain of the operating system You need to specify the credentials store in HOME docker config json to tell the docker engine to use it By default Docker looks for the native binary on each of the platforms i e “osxkeychain on macOS “wincred on windows and “pass on Linux In other words I won t be able to see the content of the service account key file in plain text anywhere but docker will utilize the OS specific tools to store them securely After I ran the docker login command on Windows I found the following content in docker config json cat docker config json auths gcr io credsStore desktop FYI desktop seems to be a wrapper for the Wincred executable Pushing images to the registryFor this tutorial we will create a super simple nginx alpine image that provides a Hello world hello html file viadocker build t my nginx f lt lt EOFFROM nginx alpineRUN echo Hello world gt gt usr share nginx html hello htmlEOFThe name of the image is my nginx docker image ls grep my nginxmy nginx latest ddd seconds ago MBIn order to push an image to a registry the image name must be prefixed with the corresponding registry This was quite confusing to me because I would have expected to be able to run something like this docker push my nginx registry gcr iounknown flag registrySee docker push help But nope there is no such registry option Even worse Omitting it would cause a push to docker io the default registry docker push my nginxUsing default tag latestThe push refers to repository docker io my nginx According to the GCP docs on Pushing and pulling images the following steps are necessary to push an image to a GCP registry Tag the image with its target path in Container Registry including the gcr io registry host and the project ID my projectPush the image to the registryIn our case the target path to our Container Registry isgcr io pl dofroscra pbecause pl dofroscra p is the id of the GCP project we created previously The full image name becomesgcr io pl dofroscra p my nginxTo push the my nginx image we must first add another name to it via docker tag docker tag my nginx gcr io pl dofroscra p my nginx docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEmy nginx latest baacfafd minutes ago MBgcr io pl dofroscra p my nginx latest baacfafd minutes ago MBand push that name afterwards docker push gcr io pl dofroscra p my nginxUsing default tag latestThe push refers to repository gcr io pl dofroscra p my nginx afaad Preparingcbbcd Preparingdfb Preparingedcb Preparingeeabd Preparingffa Preparingcceaafa Preparingdac Preparingdac Waitingffa Waitingcceaafa Waitingcbbcd Pushedafaad Pusheddfb Pushedeeabd Pushededcb Pusheddac Layer already existsffa Pushedcceaafa Pushedlatest digest sha fbdcdfebfcbaffcaaeeebccaeefdf size You can then find the image in the UI of the Container Registry Don t worry We won t have to do the tagging every time before a push because we will set up make to use the correct name automatically when building the images in the next part Images are stored in Google Cloud Storage bucketsWe assigned the Storage Admin role to the service account previously that contains the storage buckets create permission If we wouldn t have done that the following error would have occurred denied Token exchange failed for project pl dofroscra p Caller does not have permission storage buckets create To configure permissions follow instructions at The Container Registry tries to store the docker images in a Google Cloud Storage bucket that is created on the fly when the very first image is pushed see the GCP docs on Adding a registry The first image push to a hostname triggers creation of the registry in a project and the corresponding Cloud Storage storage bucket This initial push requires project wide permissions to create storage buckets You can find the bucket that in my case is named artifacts pl dofroscra p appspot com in the Cloud Storage UI CAUTION Make sure to delete this bucket once you are done with the tutorial otherwise storage costs will incur Pulling images from the registryAccording to the GCP docs to pull an image from the Container Registry we need to be authenticated with a user that has the permissions of the Storage Object Viewer role to access the raw images FYI The Storage Admin role that we assigned previously has all the permissions of the Storage Object Viewer role Then use the fully qualified image name as before docker pull gcr io pl dofroscra p my nginxOutput if the image is cached docker pull gcr io pl dofroscra p my nginxUsing default tag latestlatest Pulling from pl dofroscra p my nginxDigest sha fbdcdfebfcbaffcaaeeebccaeefdfStatus Image is up to date for gcr io pl dofroscra p my nginx latestgcr io pl dofroscra p my nginx latestor if doesn t existdocker pull gcr io pl dofroscra p my nginxUsing default tag latestlatest Pulling from pl dofroscra p my nginxbfcf Pull complete fdf Pull complete dcfcabdc Pull complete aacef Pull complete adef Pull complete edfebcd Pull complete cacbca Pull complete dbaabeea Pull complete Digest sha fbdcdfebfcbaffcaaeeebccaeefdfStatus Downloaded newer image for gcr io pl dofroscra p my nginx latestgcr io pl dofroscra p my nginx latest Set up the Secret ManagerEven though we use git secret to manage our secrets we still need the gpg secret key for decryption This key is a secret in itself and we will use the GCP Secret Manager to store it and retrieve it later from a VM It can be managed from the Security gt Secret Manager UI once we have enabled the Secret Manager API Create a secret via the UITo create a secret navigate to the Secret Manager UI and click the CREATE SECRET buttonenter the secret name and secret value in the form we can ignore the other advanced settings like Replication policy and Encryption for now FYI the secret name can only contain English letters A Z numbers dashes and underscores click the CREATE SECRET buttonThe following gif shows the creation of a secret named my secret key with the value my secret value View a secret via the UIThe Security gt Secret Manager UI lists all existing secrets Clicking on a secret will lead you to the Secret Detail UI at the URL secretName versionse g for secret name my secret key The UI shows all versions of the secret though we currently only have one To view the actual secret value click on the three dots in the Actions column and select View secret value see gif in the previous section Retrieve a secret via the gcloud cliTo retrieve a secret with a service account via the gcloud cli it needs the permission secretmanager versions access that is part of the Secret Manager Secret Accessor role as well as the Secret Manager Admin role Let s first show all available secrets viagcloud secrets list gcloud secrets listNAME CREATED REPLICATION POLICY LOCATIONSmy secret key T automatic To see the value of my secret key we must also define the corresponding version All versions can be listed viagcloud secrets versions list my secret key gcloud secrets versions list my secret keyNAME STATE CREATED DESTROYED enabled T The actual secret value for version of my secret key is accessed viagcloud secrets versions access secret my secret key gcloud secrets versions access secret my secret keymy secret valueYou can also use the string latest as version to retrieve the latest enabled versionVersion resource Numeric secret version to access or a configured alias including latest to use the latest version gcloud secrets versions access latest secret my secret key gcloud secrets versions access latest secret my secret keymy secret value Add the secret gpg key and passwordWe already know how to create another gpg key pair and add the corresponding email to git secret from when we have set up the CI pipelines see section Add a password protected secret gpg key We will do the same once more for the production environment vianame Production Deployment email production example com passphrase secret secret production protected gpg examplepublic dev gpg keys production public gpg export key pairgpg batch gen key lt lt EOFKey Type Key Length Subkey Type Subkey Length Name Real nameName Email emailExpire Date Passphrase passphraseEOF export the private keygpg output secret pinentry mode loopback passphrase passphrase armor export secret key email export the public keygpg armor export email gt publicYou can find the secret key in the codebase at secret production protected gpg example and the public key at dev gpg keys production public gpg I have also added the secret gpg key and password as secrets to the secret manager Compute Instances The GCP VMsCompute Instances are the equivalent of AWS EC instances To run our application we need a VM with a public IP address so that it can be reached from the internet VMs on GCP are called Compute Instances and can be managed from the Compute Instance UI though we must first activate the Compute Instance API Create a VMWe can simply create a new instance from the Create an instance UI General VM settingsWe ll use the following settings Name dofroscra test Region us central Iowa and Zone us central aMachine family General Purpose gt E gt e micro vCPU GB memory Boot Disk Debian GNU Linux bullseye GBIdentity and API access Choose the Docker PHP Tutorial deployment account service account that we created previously Firewall Allow HTTP traffic Firewall and networks tagsTicking the Allow HTTP traffic checkbox will cause two things when the instance is created a new firewall rule named default allow http is created that allows incoming traffic from port and is only applied to instances with the network tag http server You can see the new rule in the Firewall UIthe network tag http server is added to the instance effectively enabling the aforementioned firewall rule for the instance The role of the service accountThe service account that we have chosen in the previous step will be attached to the Compute Instance I e it will be available on the instance and we will have access to the account when we log into the instance Conveniently thegcloud cli is pre installed on every Compute Instance If you re using an instance on Compute Engine the gcloud CLI is installed by default The exact rules for what the service account can do are described in the Compute Engine docs for Service accounts In short The possible actions will be constrained by the IAM permissions of the service account and the Access scopes of the Compute Instance which are set as outlined in the Default scopes section Just take this as an aside we won t have to modify anything here We will use the service account later when we log into the Compute Instance and run docker pull from there to pull images from the registry Adding a public SSH keyIn addition I added my own public ssh keyssh rsa AAAABNzaCyc row pascal landau MY LAPTOPCAUTION The username for this key will be defined at the end of the key E g in the example above the username would be pascal landau This is important for logging in later via SSH from your local machine Define Availability PoliciesWe will make the instance preemptible by choosing the VM provisioning model Spot This makes it much cheaper but GCP might terminate the instance randomly if the capacity is needed somewhere else and definitely after hours This is completely fine for our test use case The final costs are per month for this instance The actual VM creationFinally click the Create button at the bottom of the pageOnce the instance is created you can see it in the Compute Instances gt VM instances UINext to the instance name dofroscra test we can see the external IP address Opening it in a browser via won t show anything though because we didn t deploy the application yet CAUTION Make sure to shutdown and remove this instance by the end of the tutorial otherwise compute costs will incur Log into a VMThere are multiple ways to log into the VM Compute Instance outlined in Connecting to Linux VMs using advanced methods I m going to describe three of them Login via SSH from the GCP UILogin via SSH with your own key from your host machineLogin using the Identity Aware Proxy IAP conceptPS It s worth keeping the Troubleshooting SSH guide as a bookmark Login via SSH from the GCP UIProbably the easiest way to log in Simply click the SSH button in the Compute Instances gt VM instances UI next to the instance you want to log in This will create a web shell that uses an ephemeral SSH key according to the GCP documentation Connect to Linux VMs gt Connect to VMsWhen you connect to VMs using the Cloud Console Compute Engine creates an ephemeral SSH key for you Login via SSH with your own key from your host machineThis method is probably closest to what you are used to from working with other VMs In this case the instance has to be publicly available i e reachable from the internet and expose a port for SSH connections usually In addition your public SSH key needs to be deployed All of those requirements are true for the Compute Instance that we just created the public ip address is port is open by default via the default allow ssh firewall rule seeHow to Configure Firewall Rules in Google Cloud Platformand the official documentation on Troubleshooting SSH gt By default Compute Engine VMs allow SSH access on port we added our public SSH key using pascal landau as the usernameSo we can now simply login viassh pascal landau or if you need to specify the location of the private key via the i optionssh i ssh id rsa pascal landau ssh pascal landau Linux dofroscra test cloud amd SMP Debian x The programs included with the Debian GNU Linux system are free software the exact distribution terms for each program are described in theindividual files in usr share doc copyright Debian GNU Linux comes with ABSOLUTELY NO WARRANTY to the extentpermitted by applicable law Last login Sun Apr from pascal landau dofroscra test Login using the Identity Aware Proxy IAP conceptNote This is the preferred way of logging into a GCP VMTo login via IAP we need the gcloud CLI that will use API requests via HTTPS under the hood to authenticate the Google user or in our case the service account and then proxy the requests to the VM via GCP s Identity Aware Proxy IAP as described in Connecting through Identity Aware Proxy IAP for TCP and in more detail under Using IAP for TCP forwarding gt Tunneling SSH connections The corresponding command is gcloud compute ssh e g gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p Note the tunnel through iap flag Without it gcloud would instead attempt to use a normal ssh connection if the VM is publicly reachable as per docu If the instance doesn t have an external IP address the connection automatically uses IAP TCP tunneling If the instance does have an external IP address the connection uses the external IP address instead of IAP TCP tunneling Output gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra pWARNING The private SSH key file for gcloud does not exist WARNING The public SSH key file for gcloud does not exist WARNING The PuTTY PPK SSH key file for gcloud does not exist WARNING You do not have an SSH key for gcloud WARNING SSH keygen will be executed to generate a key Updating project ssh metadata Updated done Waiting for SSH key to propagate Under the hood this command will automatically create an SSH key pair on your local machine under ssh named google compute engine unless they already exist and upload the public key to the instance ls l ssh grep google compute engine rw r r Pascal Apr google compute engine rw r r Pascal Apr google compute engine ppk rw r r Pascal Apr google compute engine pubIt also opens a Putty session and logs you into in the instance Using username Pascal Authenticating with public key LAPTOP DNLQ Pascal LAPTOP DNLQ Linux dofroscra test cloud amd SMP Debian x The programs included with the Debian GNU Linux system are free software the exact distribution terms for each program are described in theindividual files in usr share doc copyright Debian GNU Linux comes with ABSOLUTELY NO WARRANTY to the extentpermitted by applicable law Last login Mon Apr from Pascal dofroscra test Caution The Putty session will be closed automatically when you abort the original gcloud compute ssh command Additional notes on IAPIn order to enable SSH connections via IAP our service account needs the following IAM roles roles compute instanceAdmin v role Compute Adminroles iam serviceAccountUser role Service Account Userroles iap tunnelResourceAccessor role IAP secured Tunnel UserOtherwise you might run into a couple of errors like ERROR gcloud compute ssh Could not fetch resource Required compute instances get permission for projects pl dofroscra p zones us central a instances dofroscra test roles compute instanceAdmin v missing ERROR gcloud compute ssh Could not add SSH key to instance metadata The user does not have access to service account docker php tutorial deployment pl dofroscra p iam gserviceaccount com User docker php tutorial deployment pl dofroscra p iam gserviceaccount com Ask a project owner to grant you the iam serviceAccountUser role on the service account roles iam serviceAccountUser missing Remote side unexpectedly closed connection roles iap tunnelResourceAccessor missing Note This error can also occur if you try to use IAP directly after starting a VM In this case wait a couple of seconds and try again The general flow looks like thisUsing IAP might look overly complicated at first but it offers a number of benefits we can leverage Google s authentication system and the powerfulIAM permission management to manage permissions no more need to deploy custom SSH keys to the VMswe don t need a public IP address any longer see Overview of TCP forwarding gt How IAP s TCP forwarding works gt A special case establishing an SSH connection using gcloud compute ssh wraps the SSH gt connection inside HTTPS and forwards it to the remote instance without the need of a gt listening port on local host gt gt gt gt TCP forwarding with IAP doesn t require a public routable IP address assigned to your gt resource Instead it uses internal IPs This is nice because in our final PHP application only the nginx container should be accessible publicly php fpm and the php workers shouldn t Usually we would use a so called Bastion Host or Jump Box to deal with this problem but thanks to IAP we don t have toAdditional resourcesAccessing Secure Servers Using IAPConnecting Securely to Google Compute Engine VMs without a Public IP or VPN Get root permissionsThe group google sudoers exists on each GCP Compute Instance It is configured for passwordless sudo via etc sudoers d google sudoers sudo cat etc sudoers d google sudoers google sudoers ALL ALL ALL NOPASSWD ALLI e each user added to this group can use sudo without password or simply run sudo i to become root Your user should be added automatically to that group This can be verified with the id command run on the VM Pascal dofroscra test iduid Pascal gid Pascal groups Pascal adm dip video plugdev google sudoers gt google sudoers ssh and scp commandsIt is quite common to copy files from to a VM and to run commands on it This is usually done via ssh and scp The gcloud cli offers equivalent commands that can also make use of the Identity Aware Proxy IAP concept gcloud ssh command Documentation gcloud ssh commandExample gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command whoami Output gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command whoami Pascal gcloud scpDocumentation gcloud scpExample gcloud compute scp zone us central a tunnel through iap project pl dofroscra p local file txt local file txt dofroscra test tmp echo gt gt local file txtecho gt gt local file txtgcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command rm rf test mkdir p test gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command ls l test gcloud compute scp zone us central a tunnel through iap project pl dofroscra p local file txt local file txt dofroscra test test gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command ls l test Output echo gt gt local file txt echo gt gt local file txt gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command ls l test total gcloud compute scp zone us central a tunnel through iap project pl dofroscra p local file txt local file txt dofroscra test test local file txt kB kB s ETA local file txt kB kB s ETA gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command ls l test total rw r r Pascal Pascal Jun local file txt rw r r Pascal Pascal Jun local file txtNote According to the examples in the documentation it should also be possible to use the to define that the destination on the remote VM is relative to the home directory However this did not work for me as I kept getting the error gcloud compute scp zone us central a tunnel through iap project pl dofroscra p local file txt dofroscra test testpscp remote filespec test not a directoryeven though the diretory existed But removing the part worked gcloud compute scp zone us central a tunnel through iap project pl dofroscra p local file txt dofroscra test test local file txt kB kB s ETA Provision the VM Get the secret gpg key and password from the Secret ManagerBefore we shift our attention to docker let s quickly deal with the secrets We won t need them for this part of the tutorial but will need the secret gpg key and its password to decrypt the secrets in the php containers in the next part To recap We have added the them previously and can now retrieve them as explained under section Retrieve a secret via the gcloud cli viagcloud secrets versions access secret GPG KEY gt secret gpgGPG PASSWORD gcloud secrets versions access secret GPG PASSWORD gcloud secrets versions access secret GPG KEY gt secret gpg head secret gpg BEGIN PGP PRIVATE KEY BLOCK lQPGBGKApsBCACqzYDTCVZEIWXbUplfAGQZOQJALmzErYpTpjt rpvJhRUxahypqCqCnnyYMEybBpW WcHxWLBDo hePKeLbpwFFjJns uopHgFMElyHpzTGiDQYfx CgYhKzGSqpjmnOaKxYvGvEsbZczyHYWIN YFzbtItYJzTSHI aazRdHynQcCRcIT q VkgzmmgoqVpyeNgQcqJjcdiPWUZdvZCumOvdGPZNlc wPFhqLDmYyLmJptbWIgtyBjYKZNOdUaekqVEJ rHbzwgFLLEgdfhyYgMdWdzFDxVABEBAAH BwMCveBYToigXxExLlfZKVjwlErNpYdXgeWPU qumATJWounzciiETpsYGsbPdzFRJPEJZlsFShp kXYTuenYDwgGkeYyNlmIHfqSnzJMWKzXEODtKJlfjcnZeb GPG PASSWORD gcloud secrets versions access secret GPG PASSWORD echo GPG PASSWORD Installing docker and docker composeSince we created the VM with a Debian OS we ll follow the official Debian installation instructions for Docker Engine and run the following commands while we are logged into the VM install required toolssudo apt get update yq amp amp apt get install yq ca certificates curl gnupg lsb release add Docker s official GPG keycurl fsSL sudo gpg dearmor o usr share keyrings docker archive keyring gpg set up the stable repositoryecho deb arch dpkg print architecture signed by usr share keyrings docker archive keyring gpg lsb release cs stable sudo tee etc apt sources list d docker list gt dev null install Docker Enginesudo apt get update yq amp amp sudo apt get install yq docker ce docker ce cli containerd io docker compose pluginI have also added these instructions to the script infrastructure scripts provision sh Afterwards we check viadocker versiondocker compose versionif docker and docker compose are available docker versionDocker version build fd docker compose versionDocker Compose version v Authenticate docker via gcloudI recommend running the commands as root viasudo ipascal landau dofroscra test sudo iroot dofroscra test Otherwise we might run into docker permission errors likeGot permission denied while trying to connect to the Docker daemon socket at unix var run docker sock Post http Fvar Frun Fdocker sock v images create fromImage dial unix var run docker sock connect permission deniedFYI As an alternative we could also add the non root user to the docker group viauser whoami sudo usermod a G docker user user whoami sudo usermod a G docker user iduid pascal landau gid pascal landau groups pascal landau adm dip video plugdev docker google sudoers Locally we could use the JSON key file of the service account for authentication but we don t have access to that key file on the VM Instead we will authenticate docker via the pre installed gcloud cli and the attached service account as described in the GCP docs for the Container Registry Authentication methods under section gcloud credential helper viagcloud auth configure docker quietAdding credentials for all GCR repositories WARNING A long list of credential helpers may cause delays running docker build We recommend passing the registry name to configure only the registry you are using Docker configuration file updated This creates the file root docker config json that we already encountered when we authenticated docker locally to push images In this case it has the following content cat root docker config json credHelpers gcr io gcloud us gcr io gcloud eu gcr io gcloud asia gcr io gcloud staging ks gcr io gcloud marketplace gcr io gcloud The creadHelpers are described in the docker login docsCredential helpers are similar to the credential store above but act as the designated programs to handle credentials for specific registries The default credential store credsStore or the config file itself will not be used for operations concerning credentials of the specified registries In other words we are using gcr io as registrythis registry is defined to use the credential helper gcloudi e it will use the pre initialized gcloud cli for authentication Pulling the nginx imageOnce we are authenticated we can simply run docker pull with the full image name to retrieve the nginx image that we pushed previouslydocker pull gcr io pl dofroscra p my nginx docker pull gcr io pl dofroscra p my nginxUsing default tag latestlatest Pulling from pl dofroscra p my nginxbfcf Pull complete fdf Pull complete dcfcabdc Pull complete aacef Pull complete adef Pull complete edfebcd Pull complete cacbca Pull complete dbaabeea Pull complete Digest sha fbdcdfebfcbaffcaaeeebccaeefdfStatus Downloaded newer image for gcr io pl dofroscra p my nginx latestgcr io pl dofroscra p my nginx latestIf we wouldn t be authenticated we would run into the following error docker pull gcr io pl dofroscra p my nginxUsing default tag latestError response from daemon unauthorized You don t have the needed permissions to perform this operation and you may have invalid credentials To authenticate your request follow the steps in Start the nginx containerFor now we will simply run the nginx container with docker run viadocker run name nginx p rm d gcr io pl dofroscra p my nginx latestWegive it the name nginx so we can easily reference it later via name nginxmap port from the host to port of the container so that HTTP requests to the VM are handled via the container via p see Docker docs on Publish or expose port p expose make it run in the background via d detach and remove it after shutdownautomatically via rm remove Outputroot dofroscra test docker run p d name nginx gcr io pl dofroscra p my nginx latestddbedadcfdaccadbfeefcfcroot dofroscra test docker logs nginx docker entrypoint sh docker entrypoint d is not empty will attempt to perform configuration docker entrypoint sh Looking for shell scripts in docker entrypoint d docker entrypoint sh Launching docker entrypoint d listen on ipv by default sh listen on ipv by default sh info Getting the checksum of etc nginx conf d default conf listen on ipv by default sh info etc nginx conf d default conf differs from the packaged version docker entrypoint sh Launching docker entrypoint d envsubst on templates sh docker entrypoint sh Launching docker entrypoint d tune worker processes sh docker entrypoint sh Configuration complete ready for start up notice using the epoll event method notice nginx notice built by gcc Alpine git notice OS Linux cloud amd notice getrlimit RLIMIT NOFILE notice start worker processes notice start worker process notice start worker process We re all set to serve HTTP requests The requests will be passed to the nginx container due to the mapped port i e we can simply use the public IP address in a curl request and check the Hello world file we ve added to the image curl s Hello world Automate via gcloud commandsSo far we have mostly used the UI to configure everything This is great for understanding how things work but it s not so great for maintainability UIs change Clicking stuff takes quite some timewe can t automate anythingFortunately we can also use the gcloud cli for most of the tasks Preconditions Project and Owner service accountI ll assume that gcloud is installeda GCP project existsIn addition I ll manually create a new master service account and assign it the role Owner We ll use that service account in the gcloud cli to enable all the APIs and manage the resources FYI We could also do this with our personal GCP user but I plan to use terraform in a later tutorial which will require a service account anyway We will use docker php tutorial master as service account ID and store the key file of the account at the root of the codebase under gcp master service account key json which is also added to the gitignore file Configure gcloud to use the master service accountRungcloud auth activate service account key file gcp master service account key json project pl dofroscra p gcloud auth activate service account key file gcp master service account key json project pl dofroscra pActivated service account credentials for docker php tutorial master pl dofroscra p iam gserviceaccount com Enable APIsAPIs can be enabled via gcloud services enable serviceName see also the Docu on Enabling an API in your Google Cloud project The serviceName is shown on the API overview page of a service see the following example for the Container RegistryWe need the APIs forContainer Registry containerregistry googleapis comSecret Manager secretmanager googleapis comCompute Engine compute googleapis comIAM iam googleapis comCloud Storage storage googleapis comCloud Resource Manager cloudresourcemanager googleapis comgcloud services enable containerregistry googleapis com secretmanager googleapis com compute googleapis com iam googleapis com storage googleapis com cloudresourcemanager googleapis com gcloud services enable containerregistry googleapis com secretmanager googleapis com compute googleapis com iam googleapis com storage googleapis com cloudresourcemanager googleapis comOperation operations acat p b ceb b b cbbf finished successfully Create and configure a deployment service accountWe won t use the master Owner service account for the deployment but create a custom one with only the necessary permissions Service accounts are created via gcloud iam service accounts create serviceAccountId see also the Docu on Creating and managing service accounts The serviceAccountId is the id of the service account e g docker php tutorial deployment in our previous example In addition we can define a description and a display name gcloud iam service accounts create docker php tutorial deployment description Used for the deployment of the Docker PHP Tutorial application display name Docker PHP Tutorial Deployment Account gcloud iam service accounts create docker php tutorial deployment gt description Used for the deployment of the Docker PHP Tutorial application gt display name Docker PHP Tutorial Deployment Account Created service account docker php tutorial deployment Then we need a key file for authentication It can be created via gcloud iam service accounts keys create localPathToKeyFile iam account serviceAccountEmail see also the Docu on Create and manage service account keys The localPathToKeyFile is used to store the key file locally e g gcp service account key json in our previous example and serviceAccountEmail is the email address of the service account It has the form serviceAccountId projectId iam gserviceaccount come g docker php tutorial deployment pl dofroscra p iam gserviceaccount comExample gcloud iam service accounts keys create gcp service account key json iam account docker php tutorial deployment pl dofroscra p iam gserviceaccount com gcloud iam service accounts keys create gcp service account key json gt iam account docker php tutorial deployment pl dofroscra p iam gserviceaccount comcreated key dfcdfdedcedbdbaf of type json as gcp service account key json for docker php tutorial deployment pl dofroscra p iam gserviceaccount com Finally we must assign the required IAM roles via gcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roleId see also the Docu on Manage access to projects folders and organizations The projectName is the name of the GCP project serviceAccountEmail the email address from before and the roleId the name of the role as listed under Understanding roles In our case that s Storage Admin roles storage adminSecret Manager Admin roles secretmanager adminCompute Admin roles compute adminService Account User roles iam serviceAccountUserIAP secured Tunnel User roles iap tunnelResourceAccessorprojectName pl dofroscra p serviceAccountEmail docker php tutorial deployment pl dofroscra p iam gserviceaccount com gcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roles storage admingcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roles secretmanager admingcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roles compute admingcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roles iam serviceAccountUsergcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roles iap tunnelResourceAccessor projectName pl dofroscra p serviceAccountEmail docker php tutorial deployment pl dofroscra p iam gserviceaccount com gcloud projects add iam policy binding projectName member serviceAccount serviceAccountEmail role roles storage adminUpdated IAM policy for project pl dofroscra p bindings members serviceAccount service compute system iam gserviceaccount com role roles compute serviceAgent members serviceAccount service containerregistry iam gserviceaccount com role roles containerregistry ServiceAgent members serviceAccount compute developer gserviceaccount com serviceAccount cloudservices gserviceaccount com role roles editor members serviceAccount docker php tutorial master pl dofroscra p iam gserviceaccount com user pascal landau gmail com role roles owner members serviceAccount service gcp sa pubsub iam gserviceaccount com role roles pubsub serviceAgent members serviceAccount docker php tutorial deployment pl dofroscra p iam gserviceaccount com role roles storage adminetag BwXgKxHggA version Updated IAM policy for project pl dofroscra p bindings members serviceAccount docker php tutorial deployment pl dofroscra p iam gserviceaccount com role roles compute admin members serviceAccount service compute system iam gserviceaccount com role roles compute serviceAgent members serviceAccount service containerregistry iam gserviceaccount com role roles containerregistry ServiceAgent members serviceAccount compute developer gserviceaccount com serviceAccount cloudservices gserviceaccount com role roles editor members serviceAccount docker php tutorial deployment pl dofroscra p iam gserviceaccount com role roles iam serviceAccountUser members serviceAccount docker php tutorial deployment pl dofroscra p iam gserviceaccount com role roles iap tunnelResourceAccessor members serviceAccount docker php tutorial master pl dofroscra p iam gserviceaccount com user pascal landau gmail com role roles owner members serviceAccount service gcp sa pubsub iam gserviceaccount com role roles pubsub serviceAgent members serviceAccount docker php tutorial deployment pl dofroscra p iam gserviceaccount com role roles secretmanager admin members serviceAccount docker php tutorial deployment pl dofroscra p iam gserviceaccount com role roles storage adminetag BwXgKxmVtk version Create secretsSecrets are created via gcloud secrets create secretId see also the Docu on Creating and accessing secrets The secretId is the name of the secret e g my secret key in our previous example and we must also add a new version with the value of the secret via gcloud secrets versions add secretId data file path to file txt gcloud secrets create my secret keyecho n my secret value gcloud secrets versions add my secret key data file gcloud secrets create my secret keyCreated secret my secret key echo n my secret value gcloud secrets versions add my secret key data file Created version of the secret my secret key We also need to do the same for the gpg secret key and its password gcloud secrets create GPG KEYecho gcloud secrets versions add GPG KEY data file secret production protected gpg examplegcloud secrets create GPG PASSWORDecho n gcloud secrets versions add GPG PASSWORD data file gcloud secrets create GPG KEYCreated secret GPG KEY gcloud secrets versions add GPG KEY data file secret production protected gpg exampleCreated version of the secret GPG KEY gcloud secrets create GPG PASSWORDCreated secret GPG PASSWORD echo n gcloud secrets versions add GPG PASSWORD data file Created version of the secret GPG PASSWORD Create firewall rule for HTTP trafficFirewall rules can be created via gcloud compute firewall rules create ruleName see also the Docu on Using firewall rules We ll stick to the same conventions that have been used when creating the VM via the UI by using default allow http as the ruleName and http server as the network tag via the target tags option gcloud compute firewall rules create default allow http allow tcp target tags http server gcloud compute firewall rules create default allow http allow tcp target tags http serverCreating firewall Created done NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLEDdefault allow http default INGRESS tcp False Create a Compute Instance VMCompute Instances can be created via gcloud compute instances create vmName see also the Docu on Creating and starting a VM instance The vmName defines the name of the VM e g dofroscra test in the previous example In addition there are a lot of options to customize the VM e g image family and image projectdefine the operating system e g image family debian and image project debian cloudSee Docu on Operating system details for a list of available values machine typedefines the machine type i e the specs like CPUs and memory e g machine type e microSee Docu on About machine families that contains links to the machine type categories with the concrete values e g theGeneral purpose machine familyetc The docu is doing a great job at describing all available configuration options Luckily we can make our lives a little easier configure the VM via UI and then click the EQUIVALENT COMMAND LINE button at the end of the page to get a copy paste ready gcloud compute instances create command Your browser does not support the video tag Note that we are using dofroscra test as the instance name and us central a as thezone gcloud compute instances create dofroscra test project pl dofroscra p zone us central a machine type e micro network interface network tier PREMIUM subnet default no restart on failure maintenance policy TERMINATE provisioning model SPOT instance termination action STOP service account docker php tutorial deployment pl dofroscra p iam gserviceaccount com scopes tags http server create disk auto delete yes boot yes device name dofroscra test image projects debian cloud global images debian bullseye v mode rw size type projects pl dofroscra p zones us central a diskTypes pd balanced no shielded secure boot shielded vtpm shielded integrity monitoring reservation affinity anyCreated NAME ZONE MACHINE TYPE PREEMPTIBLE INTERNAL IP EXTERNAL IP STATUSdofroscra test us central a e small true RUNNING ProvisioningFor provisioning we need to install docker and authenticate the root user to pull images from our registry We ve already created an installation script at infrastructure scripts provision sh and the easiest way to run it on the VM is to transmit it via scpgcloud compute scp zone us central a tunnel through iap project pl dofroscra p infrastructure scripts provision sh dofroscra test provision sh gcloud compute scp zone us central a tunnel through iap project pl dofroscra p infrastructure scripts provision sh dofroscra test provision shprovision sh kB kB s ETA The previous command transmitted the script in the home directory of the user and we can now execute it viagcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command bash provision sh gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command bash provision sh Hit bullseye InReleaseHit cloud sdk bullseye InRelease The following additional packages will be installed dbus user session docker ce rootless extras docker scan plugin git git man libcurl gnutls liberror perl libgdbm compat libltdl libperl libslirp patch perl perl modules pigz slirpnetnsSuggested packages aufs tools cgroupfs mount cgroup lite git daemon run git daemon sysvinit git doc git el git email git gui gitk gitweb git cvs git mediawiki git svn ed diffutils doc perl doc libterm readline gnu perl libterm readline perl perl make libtap harness archive perlThe following NEW packages will be installed containerd io dbus user session docker ce docker ce cli docker ce rootless extras docker compose plugin docker scan plugin git git man libcurl gnutls liberror perl libgdbm compat libltdl libperl libslirp patch perl perl modules pigz slirpnetns upgraded newly installed to remove and not upgraded Need to get MB of archives After this operation MB of additional disk space will be used Setting up docker ce debian bullseye Created symlink etc systemd system multi user target wants docker service → lib systemd system docker service Created symlink etc systemd system sockets target wants docker socket → lib systemd system docker socket Setting up liberror perl Setting up git Processing triggers for man db Processing triggers for libc bin debu Once docker is installed we can run the authentication of the root user using sudo su root c viagcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command sudo su root c gcloud auth configure docker quiet gcloud compute ssh dofroscra test zone us central a tunnel through iap project pl dofroscra p command sudo su root c gcloud auth configure docker quiet Adding credentials for all GCR repositories WARNING A long list of credential helpers may cause delays running docker build We recommend passing the registry name to configure only the registry you are using gcloud credential helpers already registered correctly DeploymentWe re almost done the last step in the process consists of building the docker image locally using the correct tag gcr io pl dofroscra p my nginx docker build t gcr io pl dofroscra p my nginx f lt lt EOF FROM nginx alpine RUN echo Hello world gt gt usr share nginx html hello html EOF docker build t gcr io pl dofroscra p my nginx no cache f lt lt EOF FROM nginx alpine RUN echo Hello world gt gt usr share nginx html hello html EOF internal load build definition from Dockerfile sha eecceddefddeade RUN echo Hello world gt gt usr share nginx html hello html sha deefabffeeeebeeeefcbbbdc DONE s exporting to image sha ecebbffbfadefbdcfbdcbdcab exporting layers s done writing image sha dbaebdeeffbeeeeefffffe done naming to gcr io pl dofroscra p my nginx done DONE slocal authentication cat gcp service account key json docker login u json key password stdin cat gcp service account key json docker login u json key password stdin Login Succeeded Logging in with your password grants your terminal complete access to your account For better security log in with a limited privilege personal access token Learn more at pushing it to the registry docker push gcr io pl dofroscra p my nginx docker push gcr io pl dofroscra p my nginx Using default tag latest The push refers to repository gcr io pl dofroscra my nginx ad Preparing ad Pushed latest digest sha bcebcafeffbadeedfbcdfe size and deploying it on the VM For the last step we will once again use a script that we transmit to the VM infrastructure scripts deploy sh usr bin env bashusage Usage deploy sh image name z amp amp echo No image name given usage amp amp exit image name container name nginxecho Pulling image name from registry sudo docker pull image name echo Starting container sudo docker kill container name sudo docker run name container name p rm d image name echo Getting secret GPG KEY gcloud secrets versions access latest secret GPG KEY gt gt secret gpghead secret gpgecho Getting secret GPG PASSWORD GPG PASSWORD gcloud secrets versions access latest secret GPG PASSWORD echo GPG PASSWORDThe script will pull the image on the VM from the registry sudo docker pull gcr io pl dofroscra p my nginx Using default tag latestlatest Pulling from pl dofroscra p my nginx Digest sha bcebcafeffbadeedfbcdfeStatus Downloaded newer image for gcr io pl dofroscra p my nginx latestgcr io pl dofroscra p my nginx lateststart a container with the image docker kill container name sudo docker run name container name p rm d image name Error response from daemon Cannot kill container nginx No such container nginxacccedcededcbeeccfcdefcbfbcband finally retrieve the secrets just to demonstrate that it works gcloud secrets versions access latest secret GPG KEY gt gt secret gpg head secret gpg BEGIN PGP PRIVATE KEY BLOCK lQPGBGKApsBCACqzYDTCVZEIWXbUplfAGQZOQJALmzErYpTpjt rpvJhRUxahypqCqCnnyYMEybBpW WcHxWLBDo hePKeLbpwFFjJns uopHgFMElyHpzTGiDQYfx CgYhKzGSqpjmnOaKxYvGvEsbZczyHYWIN YFzbtItYJzTSHI aazRdHynQcCRcIT q VkgzmmgoqVpyeNgQcqJjcdiPWUZdvZCumOvdGPZNlc wPFhqLDmYyLmJptbWIgtyBjYKZNOdUaekqVEJ rHbzwgFLLEgdfhyYgMdWdzFDxVABEBAAH BwMCveBYToigXxExLlfZKVjwlErNpYdXgeWPU qumATJWounzciiETpsYGsbPdzFRJPEJZlsFShp kXYTuenYDwgGkeYyNlmIHfqSnzJMWKzXEODtKJlfjcnZeb GPG PASSWORD gcloud secrets versions access latest secret GPG PASSWORD echo GPG PASSWORDBonus For retrieving the puplic IP address of the Compute Instance VM we can use the gcloud compute instances describe instanceName command gcloud compute instances describe dofroscra test zone us central a project pl dofroscra p format get networkInterfaces accessConfigs natIP ip gcloud compute instances describe dofroscra test zone us central a project pl dofroscra p format get networkInterfaces accessConfigs natIP echo ip curl s http ip hello html Hello world Putting it all togetherSince none of the previous steps requires manual intervention any longer I have created a script at infrastructure setup gcp sh to run everything from Configure gcloud to use the master service account to Provisioning usr bin env bashusage Usage deploy sh project id vm name z amp amp echo No project id given usage amp amp exit z amp amp echo No vm name given usage amp amp exit GREEN m NO COLOR m project id vm name vm zone us central amaster service account key location gcp master service account key jsondeployment service account id deploymentdeployment service account key location gcp service account key jsondeployment service account mail deployment service account id project id iam gserviceaccount com gpg secret key location secret production protected gpg examplegpg secret key password printf GREEN Setting up GCP project for NO COLOR n echo echo project id project id echo vm name vm name printf GREEN Activating master service account NO COLOR n gcloud auth activate service account key file master service account key location project project id printf GREEN Enabling APIs NO COLOR n gcloud services enable containerregistry googleapis com secretmanager googleapis com compute googleapis com iam googleapis com storage googleapis com cloudresourcemanager googleapis comprintf GREEN Creating deployment service account with id deployment service account id NO COLOR n gcloud iam service accounts create deployment service account id description Used for the deployment application display name Deployment Account printf GREEN Creating JSON key file for deployment service account at deployment service account key location NO COLOR n gcloud iam service accounts keys create deployment service account key location iam account deployment service account mail printf GREEN Adding roles for service account NO COLOR n roles storage admin secretmanager admin compute admin iam serviceAccountUser iap tunnelResourceAccessor for role in roles do gcloud projects add iam policy binding project id member serviceAccount deployment service account mail role roles role done printf GREEN Creating secrets NO COLOR n gcloud secrets create GPG KEYecho gcloud secrets versions add GPG KEY data file gpg secret key location gcloud secrets create GPG PASSWORDecho n gpg secret key password gcloud secrets versions add GPG PASSWORD data file printf GREEN Creating firewall rule to allow HTTP traffic NO COLOR n gcloud compute firewall rules create default allow http allow tcp target tags http serverprintf GREEN Creating a Compute Instance VM NO COLOR n gcloud compute instances create vm name project project id zone vm zone machine type e micro network interface network tier PREMIUM subnet default no restart on failure maintenance policy TERMINATE provisioning model SPOT instance termination action STOP service account deployment service account mail scopes tags http server create disk auto delete yes boot yes device name vm name image projects debian cloud global images debian bullseye v mode rw size type projects project id zones vm zone diskTypes pd balanced no shielded secure boot shielded vtpm shielded integrity monitoring reservation affinity anyprintf GREEN Activating deployment service account NO COLOR n gcloud auth activate service account key file deployment service account key location project project id printf GREEN Transferring provisioning script NO COLOR n echo Waiting s for the instance to be fully ready to receive IAP connections sleep gcloud compute scp zone vm zone tunnel through iap project project id infrastructure scripts provision sh vm name provision shprintf GREEN Executing provisioning script NO COLOR n gcloud compute ssh vm name zone vm zone tunnel through iap project project id command bash provision sh printf GREEN Authenticating docker via gcloud in the VM NO COLOR n gcloud compute ssh vm name zone vm zone tunnel through iap project project id command sudo su root c gcloud auth configure docker quiet printf n n GREEN Provisioning done NO COLOR n bash infrastructure setup gcp sh pl dofroscra p dofroscra testSetting up GCP project for project id pl dofroscra pvm name dofroscra testActivating master service accountActivated service account credentials for master pl dofroscra p iam gserviceaccount com Enabling APIsOperation operations acf p aa a ef e acc finished successfully Creating deployment service account with id deployment Created service account deployment Creating JSON key file for deployment service account at gcp service account key jsoncreated key fadfafabbeeeabb of type json as gcp service account key json for deployment pl dofroscra p iam gserviceaccount com Adding roles for service accountUpdated IAM policy for project pl dofroscra p bindings members serviceAccount deployment pl dofroscra p iam gserviceaccount com role roles storage adminetag BwXgwMPTM version Creating secretsCreated secret GPG KEY Created version of the secret GPG KEY Created secret GPG PASSWORD Created version of the secret GPG PASSWORD Creating firewall rule to allow HTTP trafficCreating firewall Created done Creating a Compute Instance VMCreated NAME ZONE MACHINE TYPE PREEMPTIBLE INTERNAL IP EXTERNAL IP STATUSdofroscra test us central a e micro true RUNNINGActivating deployment service accountActivated service account credentials for deployment pl dofroscra p iam gserviceaccount com Transferring provisioning scriptUpdating project ssh metadata Updated done Waiting for SSH key to propagate provision sh kB kB s ETA Executing provisioning scriptGet bullseye security InRelease kB Processing triggers for man db Processing triggers for libc bin debu Authenticating docker via gcloud in the VM Adding credentials for all GCR repositories WARNING A long list of credential helpers may cause delays running docker build We recommend passing the registry name to configure only the registry you are using Docker configuration file updated Provisioning done In addition I also created a script for the Deployment at infrastructure deploy sh usr bin env bashusage Usage deploy sh project id vm name z amp amp echo No project id given usage amp amp exit z amp amp echo No vm name given usage amp amp exit GREEN m NO COLOR m project id vm name vm zone us central aimage name gcr io project id nginx latest container name nginxdeployment service account key location gcp service account key jsonprintf GREEN Building nginx docker image with name image name NO COLOR n docker build t image name f lt lt EOFFROM nginx alpineRUN echo Hello world gt gt usr share nginx html hello htmlEOFprintf GREEN Authenticating docker NO COLOR n cat deployment service account key location docker login u json key password stdin printf GREEN Pushing image name to registry NO COLOR n docker push image name printf GREEN Transferring deployment script NO COLOR n gcloud compute scp zone vm zone tunnel through iap project project id infrastructure scripts deploy sh vm name deploy shprintf GREEN Executing deployment script NO COLOR n gcloud compute ssh vm name zone vm zone tunnel through iap project project id command bash deploy sh image name printf GREEN Retrieving external IP of the VM NO COLOR n ip address gcloud compute instances describe vm name zone vm zone project project id format get networkInterfaces accessConfigs natIP printf http ip address hello html n printf n n GREEN Deployment done NO COLOR n bash infrastructure deploy sh pl dofroscra p dofroscra testBuilding nginx docker image with name gcr io pl dofroscra p nginx latest writing image sha ffefddbcfffecdaebbbbc done naming to gcr io pl dofroscra p nginx latest done DONE sUse docker scan to run Snyk tests against images to find vulnerabilities and learn how to fix themAuthenticating dockerLogin SucceededLogging in with your password grants your terminal complete access to your account For better security log in with a limited privilege personal access token Learn more at Pushing gcr io pl dofroscra p nginx latest to registryThe push refers to repository gcr io pl dofroscra p nginx ad Preparing cceaafa Pushedlatest digest sha bcebcafeffbadeedfbcdfe size Transferring deployment scriptdeploy sh kB kB s ETA Executing deployment scriptPulling gcr io pl dofroscra p nginx latest from registrylatest Pulling from pl dofroscra p nginxDigest sha facabfdeddbdaebeccbdbaab gcr io pl dofroscra p nginx latestStarting containernginxcacacbeccbdcdedffedaeacGetting secret GPG KEY BEGIN PGP PRIVATE KEY BLOCK lQPGBGKApsBCACqzYDTCVZEIWXbUplfAGQZOQJALmzErYpTpjt rpvJhRUxahypqCqCnnyYMEybBpW WcHxWLBDo hePKeLbpwFFjJns uopHgFMElyHpzTGiDQYfx CgYhKzGSqpjmnOaKxYvGvEsbZczyHYWIN YFzbtItYJzTSHI aazRdHynQcCRcIT q VkgzmmgoqVpyeNgQcqJjcdiPWUZdvZCumOvdGPZNlc wPFhqLDmYyLmJptbWIgtyBjYKZNOdUaekqVEJ rHbzwgFLLEgdfhyYgMdWdzFDxVABEBAAH BwMCveBYToigXxExLlfZKVjwlErNpYdXgeWPU qumATJWounzciiETpsYGsbPdzFRJPEJZlsFShp kXYTuenYDwgGkeYyNlmIHfqSnzJMWKzXEODtKJlfjcnZebGetting secret GPG PASSWORDRetrieving external IP of the VMDeployment done CleanupThe easiest way to cleanup everything that might create any costs e g the docker images stored on Cloud Storagethe secrets in the Secret Managerthe VM itselfis to delete the whole project e g via the Settings UI Your browser does not support the video tag FYI GCP projects have day grace period during that you can revert the deletion Wrapping upCongratulations you made it If some things are not completely clear by now don t hesitate to leave a comment You should now be familiar enough with GCP to create a Compute Instance VM and configure it to run dockerized applications on it In the next part of this tutorial we will deploy our dockerized PHP application to production on GCP via docker compose Please subscribe to the RSS feed or via email to get automatic notifications when this next part comes out |
2023-04-24 12:14:13 |
海外TECH |
DEV Community |
10 more Javascript Challenges! |
https://dev.to/this-is-learning/10-more-javascript-challenges-3812
|
more Javascript Challenges Do you know Javascript After the success of the previous video I ve decided to make a second one with more challenges to test your knowledge of the language These are out of the challenges you ll find in the video The operator is really handy and you can put it either before or after the variable But do you know the difference between the two let value console log value console log value You can use and the letter e in numbers and they re still valid const THE ANSWER e console log THE ANSWER Isn t the output here supposed to be on both cases Actually none of them is const x console log x console log x Can you spot any unintended side effect here let me name Leonardo socials twitter balastrong let luca me luca name Luca luca socials twitter puppo console log me console log luca If you re curious about the answers you can find them in the video below I hope you enjoy it In the video above I go through all challenges and show the answer but I also recorded a slower version where I actually explain them in more detail If you re curious and want to learn more you can find it here Let me know how many did you got right DThanks for reading this article I hope you found it interesting I recently launched my Discord server to talk about Open Source and Web Development feel free to join Do you like my content You might consider subscribing to my YouTube channel It means a lot to me ️You can find it here Feel free to follow me to get notified when new articles are out Leonardo MontiniFollow I talk about Open Source GitHub and Web Development I also run a YouTube channel called DevLeonardo see you there |
2023-04-24 12:06:46 |
Apple |
AppleInsider - Frontpage News |
Apple's M1 Mac mini dips to $479 today only |
https://appleinsider.com/articles/23/04/24/apples-m1-mac-mini-dips-to-479-today-only?utm_medium=rss
|
Apple x s M Mac mini dips to today onlyFlash deals on Apple Mac mini computers are in effect today with the M model discounted to for hours only and the M configuration on sale for Apple s M Mac mini is today Apple Authorized Reseller B amp H Photo is hosting the promotion on the standard M Mac mini that s equipped with GB of memory and a GB SSD This is the cheapest price we ve seen on the closeout compact desktop Read more |
2023-04-24 12:26:52 |
Cisco |
Cisco Blog |
The Value of a Collaborative Security Community |
https://feedpress.me/link/23532/16089485/the-value-of-a-collaborative-security-community
|
The Value of a Collaborative Security CommunitySecurity has become a C suite topic a business problem and that has prompted organizations of all sizes to dedicate resources to improve security resiliency and to prepare for a breach Cisco is helping tackle some of these problems by taking a risk based approach Looking at the threat the vulnerability the probability and the impact of a threat or threats and then fortifying defenses operations and continuity plans accordingly |
2023-04-24 12:25:19 |
海外TECH |
CodeProject Latest Articles |
dcr(digital camera raw) file format |
https://www.codeproject.com/Articles/5359536/dcr-digital-camera-raw-file-format
|
files |
2023-04-24 12:18:00 |
海外科学 |
NYT > Science |
Inside the Scramble to Make a Half-Million Ants Feel at Home |
https://www.nytimes.com/2023/04/24/science/leafcutter-ants-museum-insectarium.html
|
making |
2023-04-24 12:38:03 |
海外ニュース |
Japan Times latest articles |
Japan plans to expand scope of long-term foreign worker program |
https://www.japantimes.co.jp/news/2023/04/24/national/foreign-workers-program-planned-expansion/
|
Japan plans to expand scope of long term foreign worker programThe number of sectors covered by the Type status which allows workers to stay indefinitely will be increased to from the current two |
2023-04-24 21:26:25 |
ニュース |
BBC News - Home |
Prezzo to close more a third of its restaurants as bills rise |
https://www.bbc.co.uk/news/business-65375395?at_medium=RSS&at_campaign=KARANGA
|
bills |
2023-04-24 12:40:54 |
ニュース |
BBC News - Home |
Diane Abbott's comments were antisemitic, Labour leader says |
https://www.bbc.co.uk/news/uk-politics-65374104?at_medium=RSS&at_campaign=KARANGA
|
racism |
2023-04-24 12:16:28 |
ニュース |
BBC News - Home |
Man jailed for attempting to throw woman in front of Tube at King's Cross |
https://www.bbc.co.uk/news/uk-england-london-65373479?at_medium=RSS&at_campaign=KARANGA
|
august |
2023-04-24 12:07:57 |
ニュース |
BBC News - Home |
Nikolai Peskov: Putin spokesman's son 'joined Wagner in Ukraine' |
https://www.bbc.co.uk/news/world-europe-65370222?at_medium=RSS&at_campaign=KARANGA
|
group |
2023-04-24 12:30:12 |
ニュース |
BBC News - Home |
Bonus BeReal: BeReal increases daily post limit |
https://www.bbc.co.uk/news/newsbeat-65374359?at_medium=RSS&at_campaign=KARANGA
|
social |
2023-04-24 12:02:04 |
ニュース |
BBC News - Home |
Tottenham: What is going on at club after 6-1 thrashing by Newcastle? |
https://www.bbc.co.uk/sport/football/65375207?at_medium=RSS&at_campaign=KARANGA
|
Tottenham What is going on at club after thrashing by Newcastle With no permanent manager a disgruntled fanbase and a number of players underperforming BBC Sport s Simon Stone looks at what is happening at Tottenham |
2023-04-24 12:24:24 |
ニュース |
BBC News - Home |
Sri Lanka v Ireland: Andrew Balbirnie's 95 helps tourists post 319-4 on day one |
https://www.bbc.co.uk/sport/cricket/65375322?at_medium=RSS&at_campaign=KARANGA
|
Sri Lanka v Ireland Andrew Balbirnie x s helps tourists post on day oneIreland battle back from the first Test hammering by Sri Lanka to reach on day one of the second Test in Galle |
2023-04-24 12:11:44 |
ニュース |
Newsweek |
韓国ユン大統領「100年前のことで日本が謝罪、あり得ない」 また支持率下落 |
https://www.newsweekjapan.jp/stories/world/2023/04/post-101480.php
|
ユン大統領は今回の訪米について「最も重要なのは、韓米同盟の歴史的意義と成果を両国国民が十分に認識する機会になること」と付け加えた。 |
2023-04-24 21:11:53 |
コメント
コメントを投稿