Cloud Service Provider
for Developers and Teams

We make it simple to get started in the cloud and scale up as you grow —
whether you have one virtual machine or ten thousand.
Cloud Service Provider
99.9% Uptime
Our cloud service provides the ultimate in server dependability and stability.
Money-back Guarantee
Experience our high-speed cloud services without any risk, assured by our money-back guarantee.
Easy to Deploy
Manage your services with ease using our intuitive control panel, where deploying software is a matter of minutes.
Reliable and Available
Select from 6 datacenter regions around the world based on latency or deploy across regions for redundancy.

Robust cloud services for every demand

See all Products

Hostman's commitment to simplicity
and budget-friendly solutions

1 CPU
2 CPU
4 CPU
8 CPU
Configuration
1 CPU, 1 GB RAM, 25 GB SSD
Hostman
DigitalOcean
Google Cloud
AWS
Vultr
Price
$4
$6
$6.88
$7.59
$5
Tech support
Free
$24/mo
$29/mo + 3% of
monthly charges
$29/mo or 3% of
monthly charges
Free
Backups
from $0.07/GB
20% or 30% higher
base daily/weekly fee
$0.03/GB per mo
$0.05/GB per mo
20% higher base
monthly/hourly fee
Bandwidth
Free
$0.01 per GB
$0.01 per GB
$0.09/GB first
10 TB / mo
$0.01 per GB
Live chat support
Avg. support response time
<15 min
<24 hours
<4 hours
<12 hours
<12 hours
Anup k.
Associate Cloud Engineer
5.0 out of 5

"Hostman Comprehensive Review of Simplicity and Potential"

It been few years that I have been working on Cloud and most of the cloud service...
Mansur H.
Security Researcher
5.0 out of 5

"A perfect fit for everything cloud services!"

Hostman's seemless integration, user-friendly interface and its robust features (backups, etc) makes it much easier...
Adedeji E.
DevOps Engineer
5.0 out of 5

"Superb User Experience"

For me, Hostman is exceptional because of it's flexibility and user-friendliness. The platform's ability to offer dedicated computing resources acr...
Yudhistira H.
Mid-Market(51-1000 emp.)
5.0 out of 5

"Streamlined Cloud Excellence!"

What I like best about Hostman is their exceptional speed of deployment, scalability, and robust security features. Their...
Mohammad Waqas S.
Biotechnologist and programmer
5.0 out of 5

"Seamless and easy to use Hosting Solution for Web Applications"

From the moment I signed up, the process has been seamless and straightforward...
Mohana R.
Senior Software Engineer
5.0 out of 5

"Availing Different DB Engine Services Provided by Hostman is Convenient for my Organization usecases"

Hostman manages the cloud operations...
Faizan A.
5.0 out of 5

"Hostman is a great fit for me"

Hostman is a great fit for me. What do you like best about Hostman? It was very easy to deploy my application and create database, I didn't have
Adam M.
5.0 out of 5

"Perfect website"

This website is extremely user friendly and easy to use. I had no problems so didn't have to contact customer support. Really good website and would recommend to others.
Anup K.
4.0 out of 5

"Simplifying Cloud Deployment with Strengths and Areas for Growth"

What I like best about Hostman is its unwavering commitment to simplicity...
Naila J.
5.0 out of 5

"Streamlined Deployment with Room for Improvement"

Hostman impresses with its user-friendly interface and seamless deployment process, simplifying web application hosting...

Trusted by 500+ companies and developers worldwide

Recognized as a Top Cloud Hosting Provider by HostAdvice

Hostman review

Deploy a cloud server
in just a few clicks

Set up your сloud servers at Hostman swiftly and without any fees, customizing them for your business with a quick selection of region, IP range, and details—ensuring seamless integration and data flow.

Code locally, launch worldwide

Our servers, certified with ISO/IEC 27001, are located in Tier 3 data
centers across the US, Europe, and Asia.
Hostmans' Locations
🇺🇸 San Francisco
🇺🇸 San Jose
🇺🇸 Texas
🇺🇸 New York
🇳🇱 Amsterdam
🇳🇬 Lagos
🇩🇪 Frankfurt
🇵🇱 Gdansk
🇦🇪 Dubai
🇸🇬 Singapore

Latest News

Docker

Using Traefik in Docker as a Reverse Proxy for Docker Containers

Docker containers allow for quick and easy deployment of services and applications. However, as the number of deployed applications grows, and when multiple instances of a single service are required (especially relevant for microservices architecture), we must distribute network traffic. For this purpose, you can use Traefik, a modern open-source reverse proxy server designed specifically to work with Docker containers. In this guide, we will configure Traefik as a reverse proxy for several applications running in Docker containers. Prerequisites To use Traefik, the following are required: A cloud server or a virtual machine with any pre-installed Linux distribution. We will be using Ubuntu 22.04. Docker and Docker Compose installed. See our installation guide.  You can also use a pre-configured image with Docker. To do this, go to the Cloud servers section in your Hostman control panel, click Create server, and select Docker in the Marketplace tab. In this guide, we will use two containers with the Nginx web server. Each container will display a specific message when accessed by its domain name. We will cover the creation of these containers further below. Configuring Traefik Let's start by setting up Traefik: Create a directory for storing configuration files and navigate into it: mkdir ~/test-traefik && cd ~/test-traefik Inside the project’s root directory, create three subdirectories: one for the Traefik configuration file and two others for the configuration files of the applications that will use Traefik: mkdir traefik app1 app2 Create the main configuration file for Traefik named traefik.yml in the previously created traefik directory: nano traefik/traefik.yml Insert the following code into the file: entryPoints: web: address: ":80" providers: docker: exposedByDefault: false api: dashboard: true insecure: true Let’s look closer at the parameters. entryPoints define the ports and protocols through which Traefik will accept requests. They specify on which port and IP address the service will listen for traffic. web — A unique name for the entry point, which can be referenced in routes. In this example, we use the name web. address: ":80" — Indicates that the entry point will listen for traffic on port 80 (HTTP) across all available network interfaces on the system. providers specify the sources of information about which routes and services should be used (e.g., Docker, Kubernetes, files, etc.). docker — Enables and uses the Docker provider. When using the Docker provider, Traefik automatically detects running containers and routes traffic to them. exposedByDefault: false — Disables automatic exposure of all Docker containers as services. This makes the configuration more secure: only containers explicitly enabled through labels (traefik.enable=true) will be routed (i.e., will accept and handle traffic). The api section contains settings for the administrative API and Traefik's built-in monitoring web interface. dashboard: true — Enables Traefik's web-based monitoring dashboard, which allows you to track active routes, entry points, and services. The dashboard is not a mandatory component and can be disabled by setting this to false. insecure: true — Allows access to the monitoring dashboard over HTTP. This is convenient for testing and getting familiar with the system but is unsafe to use in a production environment. To ensure secure access to the dashboard via HTTPS, set this to false. Preparing Configuration Files for Applications Now, let's prepare the configuration files for the applications that will use Traefik as a reverse proxy. We will deploy two Nginx containers, each displaying a specific message when accessed via its address. Create the Nginx configuration file for the first application: nano app1/default.conf Contents: server { listen 80; server_name app1.test.com; location / { root /usr/share/nginx/html; index index.html; } } For the server name, we specify the local domain app1.test.com. You can use either an IP address or a domain name. If you don't have a global domain name, you can use any name that is accessible only at the local level. Additionally, you will need to add the chosen domain to the /etc/hosts file (explained later). Next, create the html directory where the index.html file for the first application will be stored: mkdir app1/html Write the message "Welcome to App 1" into the index.html file using input redirection: echo "<h1>Welcome to App 1</h1>" > app1/html/index.html Repeat the same steps for the second application, but use values specific to the second app: nano app2/default.conf Contents: server { listen 80; server_name app2.test.com; location / { root /usr/share/nginx/html; index index.html; } } Set the local domain name for the second application as app2.test.com. Create the html directory for the second application: mkdir app2/html Write the message "Welcome to App 2" into the index.html file: echo "<h1>Welcome to App 2</h1>" > app2/html/index.html Since we used local domain names, they need to be registered in the system. To do this, open the hosts file using any text editor: nano /etc/hosts Add the following entries: 127.0.0.1 app1.test.com  127.0.0.1 app2.test.com   The final project structure should look like this: test-traefik/ ├── app1/ │ ├── default.conf │ └── html/ │ └── index.html ├── app2/ │ ├── default.conf │ └── html/ │ └── index.html └── traefik/ └── traefik.yml Launching Traefik and Applications Now let's proceed with launching Traefik and the applications. To do this, create a docker-compose.yml file in the root project directory (test-traefik): nano docker-compose.yml Insert the following configuration: version: "3.9" services: traefik: image: traefik:v2.10 container_name: traefik restart: always command: - "--configFile=/etc/traefik/traefik.yml" ports: - "80:80" - "8080:8080" volumes: - "./traefik/traefik.yml:/etc/traefik/traefik.yml" - "/var/run/docker.sock:/var/run/docker.sock:ro" app1: image: nginx:1.26-alpine container_name: nginx-app1 restart: always volumes: - "./app1/default.conf:/etc/nginx/conf.d/default.conf" - "./app1/html:/usr/share/nginx/html" labels: - "traefik.enable=true" - "traefik.http.routers.app1.rule=Host(`app1.test.com`)" - "traefik.http.services.app1.loadbalancer.server.port=80" app2: image: nginx:1.26-alpine container_name: nginx-app2 restart: always volumes: - "./app2/default.conf:/etc/nginx/conf.d/default.conf" - "./app2/html:/usr/share/nginx/html" labels: - "traefik.enable=true" - "traefik.http.routers.app2.rule=Host(`app2.test.com`)" - "traefik.http.services.app2.loadbalancer.server.port=80" Use the following command to launch the containers: docker compose up -d If Docker Compose was installed using the docker-compose-plugin package, the command to launch the containers will be as follows: docker-compose up -d Check the status of the running containers using the command: docker ps All containers should have the status Up. Let's verify whether the running containers with Nginx services can handle the traffic. To do this, send a request to the domain names using the curl utility. For the first application: curl -i app1.test.com For the second application: curl -i app2.test.com As you can see, both services returned the previously specified messages. Next, let's check the Traefik monitoring dashboard. Open a browser and go to the server's IP address on port 8080: In the Routers section, you will see the previously defined routes app1.test.com and app2.test.com. Conclusion Today, we explored Traefik's functionality using two Nginx services as an example. With Traefik, you can easily proxy applications running in Docker containers.
17 January 2025 · 7 min to read
HTML

How to Add Images in Markdown

When visiting any website, you’ve likely noticed that images make the pages more engaging and visually appealing. If content were limited to text alone, it would look dull and monotonous. Visual elements help users better understand and remember information while also making the interface more user-friendly. Markdown is a simple and user-friendly markup language used to create text with minimal effort. It’s widely used for writing documentation, articles, and blog posts. Markdown also allows you to add images to your text, which play a crucial role in visualizing content, making it more comprehensible and memorable. Key Methods for Adding Images There are two primary methods for adding images in Markdown: using local images and external links. Local Images It’s essential to correctly specify the file path to insert images stored locally. It’s recommended to store images either in the same directory as the Markdown file or at the same hierarchical level. If the image is in the same directory as the .md file, simply provide the file name: ![Computer](computer.png) If the image is in a subdirectory (e.g., /img) within the project folder, specify the path as follows: ![Computer](img/computer.png) The text in square brackets ([Computer]) is the alternative text (alt-text). This text appears if the image fails to load and helps screen readers describe the image for visually impaired users. The image path is enclosed in parentheses. Ensure the path is correct to avoid issues with image display after uploading to a server. External Images To insert an image hosted on the internet, use its URL: ![Image Description](https://site/photo.png) Advantages of using external images: Saves repository space: You don’t need to store large image files locally. Easy content management: It’s convenient when images are updated frequently. Disadvantages: Dependency on the external source: If the image is removed or the URL changes, the image will no longer display. Image Size In standard Markdown, there is no built-in support for controlling image sizes (except for platforms like GitHub and others where this feature has been manually added), but you can use HTML for this purpose: <img src="/img/computer.png" alt="Computer" width="500" height="300"> Enhanced Formatting Enhanced formatting helps draw attention and makes the content more accessible and easier to read. Image Caption Captions for images are important as they provide additional information to the reader. ![Computer](/img/computer.png "Text below the image") Clickable Image To create a clickable image that links to another resource, wrap the image syntax in square brackets with a link: [![Computer](/img/computer.png)](https://site) Effective Alt Text Alt text should describe the content of the image and be clear for all users. Bad alt text: ![Computer](/images/picture.jpg) Good alt text: ![The first computer ever built](/img/computer.png) Why is Alt Text Important? Accessibility: Users with visual impairments use screen reader programs that read the alt text aloud. SEO: Search engines index alt text, helping your content to be found through search queries. Tips for Working with Images Try to use images with the smallest file size possible to speed up page loading. Optimize images before uploading to avoid large file sizes and long loading times. Ensure that the alt text is unique and accurate. The file name should be relevant and include keywords. For example, instead of img123.png, use computer-setup.png. Comparison of Methods for Inserting Images There are various methods to insert images, each with its own pros and cons. Below is a comparison table. Method Advantages Disadvantages Markdown syntax Simple and fast insertion Less flexibility in customization HTML markup Full control over style and size More complex syntax Combination of Markdown and HTML Combines simplicity and flexibility Requires basic HTML knowledge Conclusion Now you know how to insert images in Markdown, control their size, add captions, and make content more accessible using alt text. Using images makes the text more visual and helps readers better comprehend the information. Check out our reliable and high-performance WordPress hosting solutions for your WordPress websites.
17 January 2025 · 4 min to read
CSS

Customizing Scrollbars in CSS

You can style scrollbars to be narrow or wide, change colors, or even hide them. This is a relatively simple task, but it comes with some challenges regarding cross-browser compatibility. Let's explore how to properly create a custom scrollbar. Suppose the project manager came up with an updated design for the website server page. The mockups show that the scrollbars have custom styles using corporate colors. It looks interesting, and now we need to figure out how to implement this scrollbar styling. The solution is quick. In 2018, the CSS Scrollbars specification was introduced, which defines how the scrollbar's appearance can be customized. This specification introduced two new properties that affect the visual style of the scrollbar: scrollbar-color — controls the color of the scrollbar. scrollbar-width — controls the width of the scrollbar. Customizing the scrollbar is now a five-minute task. Let’s check this in practice. Applying CSS Scrollbars Properties Before diving into how to style the scrollbars, let’s first understand their components. The operating system and browser do not matter here. All scrollbars have at least two elements: Thumb — the draggable part that allows us to scroll. Track — the area along which the thumb moves. Now, let’s apply some properties to style these elements. First, we will start with the width of the scrollbar. The scrollbar-width property has three possible values: auto — the default width. thin — a thin scrollbar. none — hides the scrollbar. You cannot specify the width in pixels or percentages. This restriction is in place to ensure consistency in how control elements are displayed across different browsers and operating systems — or, in simpler terms, to avoid a mess of custom solutions that could confuse users. The scrollbar-color property accepts two values: the first one sets the color of the thumb, and the second one sets the color of the track. The default value is auto, which tells the browser to use the default system settings. Let’s combine both properties and apply the following styling: body { scrollbar-width: thin; scrollbar-color: green black; } When you check this in a browser, you will see that the scrollbar on the page becomes thin and black and green. Cross-Browser Compatibility In the test environment, styling the scrollbar with scrollbar-color and scrollbar-width looks great. But before sending it to production, we need to check cross-browser compatibility — after all, not everyone uses the same browser. When we open the styled page in Safari, we notice that the scrollbar remains in its default style. To check our suspicions, let’s look up the support for the CSS Scrollbars properties on Can I Use. The situation is disappointing. Four years after the specification was introduced, the convenient scrollbar customization is still unavailable in this browser.  So, does this mean we won’t be able to implement the designed layout and will have to change everything? Don't worry, there’s a solution. To modify the appearance of the scrollbar in Safari, we can use pseudo-elements: ::-webkit-scrollbar — controls the entire navigation element. ::-webkit-scrollbar-track — controls the track. ::-webkit-scrollbar-thumb — controls the thumb (draggable part). Using pseudo-elements may seem like a hack, but there's no other option. Let’s add some styles for cross-browser compatibility: body::-webkit-scrollbar { width: 15px; /* Width of the entire navigation element */ } body::-webkit-scrollbar-track { background: #fff; /* Color of the track */ } body::-webkit-scrollbar-thumb { background-color: #050c26; /* Thumb color */ border-radius: 20px; /* Roundness of the thumb */ border: 3px solid #050c26; /* Thumb border styling */ } The obvious advantage of this approach is that we can explicitly set the width of the scrollbar. The large header will match the color of a very wide scrollbar. A separate specification for the scrollbar element doesn't offer this flexibility. The options are limited to either automatic width calculation or displaying a thin navigation element (as much as possible, considering system settings). The same goes for colors. With pseudo-elements, we can set not just colors but also gradients. Let’s slightly modify the thumb style: body::-webkit-scrollbar-thumb { background: linear-gradient(45deg, #EECFBA, #C5DDE8); /* Gradient effect */ border-radius: 20px; border: 3px solid #050c26; } Now, the thumb will have a gradient effect that changes colors. The downside is that this is outdated syntax. The CSS Scrollbars specification explicitly mentions that using prefixed pseudo-elements related to the scrollbar is considered incorrect. However, until other browsers support the new properties, we are forced to use prefixed pseudo-elements to maintain cross-browser compatibility. Conclusion For now, to create scrollbar styles, you still need to use both approaches — if cross-browser compatibility is important to you. However, when adding pseudo-elements, keep in mind that their use may soon become obsolete. According to modern standards, this is not the best solution for styling scrollbars. But aside from standards, there’s also the practical need, which forces us to make compromises.
16 January 2025 · 5 min to read
Go

How to Create and Deploy a Gin App on Hostman App Platform

Gin is a highly efficient HTTP web framework written in the Go programming language, providing developers with powerful tools for building web applications, RESTful APIs, and microservices. It stands out among other frameworks due to its high request processing speed, flexible configuration, and ease of use. One of Gin’s key advantages is its performance. Gin uses a minimalist approach to handling HTTP requests, making it one of the fastest frameworks on the market. It is built on the net/http module from Golang’s standard library, ensuring excellent integration with Go’s ecosystem and enabling the use of Go’s concurrency features to handle a large number of simultaneous requests. Another important advantage of Gin is its simplicity. The syntax and structure of Gin are intuitive, reducing the learning curve for developers and speeding up the development process. Its built-in routing system makes it easy to define and handle routes, while its powerful middleware system allows flexible request handling. Gin’s flexibility is also worth mentioning. It allows you to extend functionality  through plugins and middleware, enabling adaptation to specific project requirements. Built-in support for JSON and other data formats simplifies the creation of RESTful APIs, and tools for handling requests and responses make data management straightforward. In addition, Gin has an active community and solid documentation, making it an excellent choice for developers looking for a reliable and well-supported framework. There are plenty of resources, including code examples, guides, and libraries, that make the learning and development process easier. Creating the Application Functionality Overview Our application will support basic CRUD operations (Create, Read, Update, Delete) for notes through a RESTful API. During development, we will discuss key aspects of integrating Gin with the GORM ORM library and demonstrate how to ensure the security and performance of our web application. The main features of our application include: Creating a New Note The user can add a new note by sending a POST request with the note’s title and content. The application will save the new note in the database and return its unique identifier. Retrieving All Notes The user can request a list of all notes by sending a GET request. The application will return all notes from the database in JSON format. Retrieving a Note by ID The user can retrieve a specific note by its ID by sending a GET request with the specified ID. The application will find the note in the database and return it in JSON format. Updating an Existing Note The user can update an existing note by sending a PUT request with a new title and content. The application will update the note’s data in the database and return the updated note. Deleting a Note The user can delete a note by its ID by sending a DELETE request with the specified ID. The application will remove the note from the database and return a status indicating the successful completion of the operation. Project Setup It is assumed that you have Go version 1.22 installed (you can install it using one of these guides: Windows, Ubuntu, MacOS). If you use an earlier version, errors may occur during the project setup and launch process. Additionally, you should have a basic understanding of Git and an account on one of the Git repository hosting services (GitHub, GitLab, Bitbucket, Gitea, etc.). Step 1: Create a Project Directory Run the following command to create the project directory: mkdir GinApp Navigate into the newly created directory: cd GinApp Step 2: Initialize a New Go Module Run the following command to initialize a new Golang module: go mod init gin-notes-api Step 3: Install Required Packages We will install the necessary packages for the project: Gin, GORM, and SQLite (for database interaction) using the following commands: go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/sqlite Step 4: Create the Project Structure The project structure should look like this: GinApp/ ├── go.mod ├── main.go ├── models/ │ └── note.go ├── handlers/ │ └── note_handlers.go ├── storage/ │ ├── storage.go │ └── database.go You can create this structure using your IDE’s file explorer or by running the following command in the terminal: mkdir -p models handlers storage && touch go.mod main.go models/note.go handlers/note_handlers.go storage/storage.go storage/database.go Application Structure models/note.go Defines the data structure for notes. The Note model describes the fields of a note and is used to interact with the database through the GORM ORM library. package models // Definition of the Note structure type Note struct { ID int `json:"id" gorm:"primaryKey;autoIncrement"` // Unique identifier, auto-incremented Title string `json:"title"` // Note title Content string `json:"content"` // Note content } storage/database.go This file contains functions for initializing the database and retrieving the database instance. GORM is used to work with the SQLite database. package storage import ( "gorm.io/driver/sqlite" // Driver for SQLite "gorm.io/gorm" // GORM ORM library "gin-notes-api/models" // Importing the package with data models ) // Declare a global variable to store the database instance var db *gorm.DB // Function to initialize the database func InitDatabase() error { var err error db, err = gorm.Open(sqlite.Open("notes.db"), &gorm.Config{}) // Connect to SQLite using GORM if err != nil { return err // Return an error if the connection fails } return db.AutoMigrate(&models.Note{}) // Automatically create the Note table if it doesn’t exist } // Function to retrieve the database instance func GetDB() *gorm.DB { return db // Return the global db variable containing the database connection } storage/storage.go This file provides CRUD (Create, Read, Update, Delete) operations for the Note model using GORM to interact with the SQLite database. package storage import ( "gin-notes-api/models" // Importing the package with data models ) // Function to retrieve all notes from the database func GetAllNotes() []models.Note { var notes []models.Note db.Find(¬es) // Use GORM to execute a SELECT query and fill the notes slice return notes // Return all retrieved notes } // Function to retrieve a note by ID func GetNoteByID(id int) *models.Note { var note models.Note if result := db.First(¬e, id); result.Error != nil { return nil // Return nil if the note with the specified ID is not found } return ¬e // Return the found note } // Function to create a new note func CreateNote(title, content string) models.Note { note := models.Note{ Title: title, Content: content, } db.Create(¬e) // Use GORM to execute an INSERT query and save the new note return note // Return the created note } // Function to update an existing note by ID func UpdateNote(id int, title, content string) *models.Note { var note models.Note if result := db.First(¬e, id); result.Error != nil { return nil // Return nil if the note with the specified ID is not found } note.Title = title note.Content = content db.Save(¬e) // Use GORM to execute an UPDATE query and save the updated note return ¬e // Return the updated note } // Function to delete a note by ID func DeleteNoteByID(id int) bool { if result := db.Delete(&models.Note{}, id); result.Error != nil { return false // Return false if deletion fails } return true // Return true if the note is successfully deleted } handlers/note_handlers.go This file contains handler functions for processing HTTP requests. These functions are triggered in response to different routes and perform actions such as creating, retrieving, updating, and deleting notes. package handlers import ( "net/http" // HTTP package "strconv" // For converting strings to other data types "github.com/gin-gonic/gin" // Gin web framework "gin-notes-api/storage" // Import the storage module for database operations ) // Handler for retrieving all notes func GetNotes(c *gin.Context) { notes := storage.GetAllNotes() // Fetch all notes from storage c.JSON(http.StatusOK, notes) // Return notes in JSON format with a 200 OK status } // Handler for retrieving a note by ID func GetNoteByID(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) // Convert the ID parameter from string to integer if err != nil { c.JSON(http.StatusBadRequest, gin.H{ // Return 400 Bad Request if the ID is invalid "error": "Invalid note ID", }) return } note := storage.GetNoteByID(id) // Fetch the note by ID from storage if note == nil { c.JSON(http.StatusNotFound, gin.H{ // Return 404 Not Found if the note is not found "error": "Note not found", }) return } c.JSON(http.StatusOK, note) // Return the found note in JSON format with a 200 OK status } // Handler for creating a new note func CreateNote(c *gin.Context) { var input struct { Title string `json:"title" binding:"required"` Content string `json:"content" binding:"required"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{ // Return 400 Bad Request if the input data is invalid "error": err.Error(), }) return } note := storage.CreateNote(input.Title, input.Content) // Create a new note in storage c.JSON(http.StatusCreated, note) // Return the created note in JSON format with a 201 Created status } // Handler for updating an existing note by ID func UpdateNoteByID(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) // Convert the ID parameter from string to integer if err != nil { c.JSON(http.StatusBadRequest, gin.H{ // Return 400 Bad Request if the ID is invalid "error": "Invalid note ID", }) return } var input struct { Title string `json:"title" binding:"required"` Content string `json:"content" binding:"required"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{ // Return 400 Bad Request if the input data is invalid "error": err.Error(), }) return } note := storage.UpdateNote(id, input.Title, input.Content) // Update the note in storage if note == nil { c.JSON(http.StatusNotFound, gin.H{ // Return 404 Not Found if the note is not found "error": "Note not found", }) return } c.JSON(http.StatusOK, note) // Return the updated note in JSON format with a 200 OK status } // Handler for deleting a note by ID func DeleteNoteByID(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) // Convert the ID parameter from string to integer if err != nil { c.JSON(http.StatusBadRequest, gin.H{ // Return 400 Bad Request if the ID is invalid "error": "Invalid note ID", }) return } if success := storage.DeleteNoteByID(id); !success { c.JSON(http.StatusNotFound, gin.H{ // Return 404 Not Found if the note is not found "error": "Note not found", }) return } c.Status(http.StatusNoContent) // Return 204 No Content on successful deletion } main.go This file serves as the main entry point of the application. It initializes the database and sets up routes for handling HTTP requests using the Gin web framework. package main import ( "log" // Package for logging "github.com/gin-gonic/gin" // Gin web framework "gin-notes-api/handlers" // Importing the module with request handlers "gin-notes-api/storage" // Importing the module for database operations ) func main() { // Initialize the database if err := storage.InitDatabase(); err != nil { log.Fatalf("Failed to initialize database: %v", err) // Log the error and terminate the program if database initialization fails } // Create a new Gin router with default settings router := gin.Default() // Define routes and bind them to their respective handlers router.GET("/notes", handlers.GetNotes) // Route for retrieving all notes router.GET("/notes/:id", handlers.GetNoteByID) // Route for retrieving a note by ID router.POST("/notes", handlers.CreateNote) // Route for creating a new note router.PUT("/notes/:id", handlers.UpdateNoteByID) // Route for updating a note by ID router.DELETE("/notes/:id", handlers.DeleteNoteByID) // Route for deleting a note by ID // Start the web server on port 8080 router.Run(":8080") } Now we can run the application locally and test its functionality. To start the application, use the following command: go run main.go Examples of curl Requests for Testing Functionality Create a New Note This request creates a new note with a specified title and content. curl -X POST http://localhost:8080/notes \ -H "Content-Type: application/json" \ -d '{"title":"Title","content":"Note body"}' Get All Notes This request retrieves a list of all notes stored in the database. curl -X GET http://localhost:8080/notes Get a Note by ID This request fetches a specific note by its unique ID. curl -X GET http://localhost:8080/notes/1 Update a Note by ID This request updates an existing note by its ID, providing a new title and content. curl -X PUT http://localhost:8080/notes/1 \ -H "Content-Type: application/json" \ -d '{"title":"Updated Title","content":"Updated note body"}' Delete a Note by ID This request deletes a note with a specific ID. curl -X DELETE http://localhost:8080/notes/1 Deploying the Gin Application on Hostman App Platform Creating and Uploading the Repository To deploy the application using Hostman App Platform, first ensure your project is hosted in a Git repository. This example uses GitHub. Initialize a Git repository locally in your project directory: git init -b main git add . git commit -m 'First commit' Push the repository to a remote server using the commands provided when creating a new GitHub repository: git remote add origin [email protected]:your_user/your_repository.git git push -u origin main Setting Up Hostman App Platform Go to the App Platform section in Hostman and click Create app. Under the Type section, choose the Backend tab and select the Gin framework. Connect your GitHub account by granting access to the repositories, or manually select the necessary repository. After connecting your GitHub account, select the repository containing your application in the Repository section. Choose a region where your application will be hosted. In the Configuration section, select the minimum settings; they are sufficient for this project. You can modify them later if needed. Leave the default values in the App settings section. For more complex projects, you may specify environment variables and custom build commands. Specify a name for your application and click Start deploy. Deployment Process The deployment process can take up to 10 minutes. Once it’s completed, you will see the message “Deployment successfully completed” in the deployment logs. Navigate to the Settings tab on the application page to view the domain assigned to your app.In the same section, you can modify the server configuration, edit deployment settings, and update the domain binding. If you connect a custom domain, a Let’s Encrypt SSL certificate will be automatically issued and renewed 7 days before expiration. Testing the Application To verify that the application is working correctly, execute a curl request, replacing localhost with the assigned domain: curl -X GET https://your_domain/notes Conclusion In this tutorial, we have developed a basic web application for managing notes using the Gin framework and GORM library. The created RESTful API supports basic CRUD operations, making the application simple and user-friendly. Gin proved to be an efficient and easy-to-learn tool. Its routing system and support for concurrent requests made development smoother. GORM facilitated database interaction by automating many tasks. The application was successfully deployed on the Hostman App Platform, providing a fast and reliable deployment process.  In the future, we can enhance the application by adding new features such as user authentication and advanced note search capabilities. This project demonstrated how modern development tools like Gin and GORM simplify web application creation.
16 January 2025 · 14 min to read
CSS

How to Create a Draggable Element

The term Drag-and-Drop refers to the action of moving items using the mouse. Most often, this action is associated with moving files into folders. The ability to drag and drop blocks and elements from one section to another makes website builders like Tilda and Wix so convenient. These platforms allow users to create pages without any programming knowledge. The easy-to-use interface makes it possible to build a landing page in just a couple of hours. Today, we will show you how to create similar draggable elements. How to Implement Drag and Drop Effect Using JavaScript The first thing to note is that we will implement the drag-and-drop functionality without loading any frameworks or JavaScript libraries. For the desired result, knowledge of the browser API and support for the following versions is enough: Firefox 3.5+, Chrome 4, 9+, Safari 6+, Opera 12+. Before writing the code, we must address two tasks: Determine what and where we are dragging (draggable element and dropzone). Decide what will happen to the dragged element once it is dropped. As usual, events are triggered in the browser when the specified conditions are met. Now, let's take a closer look at the events that occur until the object reaches the target area. Events When dragging elements, seven events are triggered. Even though their functions are intuitive, it's important to understand the circumstances under which they are triggered. Dragstart: This event is triggered when the dragging of the element begins as soon as the mouse presses down on the element. Dragenter: This event is triggered when the dragged element enters the target area (object). Dragover: The Dragover event occurs when the dragged element is within the target object's area but has not yet been released. Dragleave: This event occurs when the dragged element leaves the target object while the mouse button is still held down. Drag: This event is triggered throughout the entire duration of the dragging process. Drop: If this event is triggered, the dragged element has been "dropped" when the mouse button is released. Dragend: This event signifies the end of the drag process (either the element has been successfully moved or the dragging action canceled). This list of events is divided into two subgroups. Events #1, #5, and #7 apply to the dragged element, while the others are used for the target area. The events do not function the other way around and cannot occur simultaneously. Therefore, you need to determine what will happen on the screen when your element is dragged into the dropzone.  Now, let's get to the practical implementation. Step-by-Step Guide Draggable elements can be blocks, images, or text. We’ll provide an example using a to-do list, where the draggable element will be labeled “TASK,” and the target area will be labeled “DONE.” There will be two <div> elements in the HTML markup since one is the draggable element and the other is the drop zone. You can create as many elements and drop zones as needed. Step 1: Create the Draggable Element Create an HTML file in the new project directory and place the basic code for a web page into it. Also, create a .css and .js files in the same folder. To ensure the styles are applied, include the link to the style.css file between the <head> tags and the link to script.js just before the closing <body> tag. <!DOCTYPE html> <html lang="en"> <head> <title> Example to Perform Drag and Drop</title> <link rel="stylesheet" href=" css/ style.css" /> </head> <body> <script src="script.js"></script> </body> </html> Now, you need to create the draggable element and the target zone. As mentioned earlier, place the draggable element called "TASK" and the drop zone (where it will be dropped) between the <body> tags. Also, make sure to enable element dragging by setting the draggable attribute to true. To disable dragging or set the default behavior, use draggable="false | auto". <!DOCTYPE html> <html lang="en"> <head> <title> Example to Perform Drag and Drop</title> <link rel="stylesheet" href=" css/ style.css" /> </head> <body> <div class="parent"> <div class="origin"> <div id="element-1" class="draggable-element" draggable="true" > TASK </div> </div> <div class="example-dropzone" > DONE </div> </div> <script src="script.js"></script> </body> </html> Copy the code into your file, save it, and you can close it. Step 2: Style the Elements As we all know, CSS (Cascading Style Sheets) offers many styling possibilities. Let's style each class individually. .parent { border: 40px solid #DEB887; color: #800000; display: flex; font-family: verdana; font-weight: bold; } .origin { flex-basis: 100%; flex-grow: 3; padding: 5px; } .draggable-element { background-color: #FFDEAD; font-family: verdana; font-weight: bold; margin-bottom: 5px; margin-top: 5px; padding: 5px; } .dropzone { background-color: #FFEBCD; flex-basis: 100%; flex-grow: 2; padding: 5px;} Since we’ve already linked the CSS file in our HTML, open the page in a browser. You'll see a prohibited sign if you try to grab the draggable element. This means dragging is not yet implemented, so let’s move to the next step. Step 3: Triggering Events Nothing will happen when we try to move the element without handling the drag-and-drop events. We’ll use HTML attributes to assign event handlers and trigger the drag operation with the format on{event}. Remember that the draggable element and the target zone have different events. In our project, we will use the main event handlers: The ondragstart event handler triggers when the dragstart event occurs on the draggable element. As mentioned earlier, the dragover event refers to the drop zone. It is triggered when the dragged element moves within the target zone. The ondrop event handler signals the completion of the drag operation, meaning when the dragged element is dropped into the drop zone. To store data during the drag process, we’ll use the dataTransfer object. This object is linked to the Event object. You can use three methods of dataTransfer: setData() – sets the data for the drag operation. clearData() – removes all data when called. getData() – returns all data set during the dragstart event. Now, open the script.js file and create a corresponding function for each of the events that will be triggered. Since our block contains text, we will use text/plain for dragging. function onDragStart(event) { event .dataTransfer .setData('text/plain', event.target.id); event .currentTarget .style .backgroundColor = 'red'; } function onDragOver(event) { event.preventDefault(); } function onDrop(event) { const id = event .dataTransfer .getData('text'); const draggableElement = document.getElementById(id); const dropzone = event.target; dropzone.appendChild(draggableElement); event .dataTransfer .clearData(); } We’ll apply the preventDefault() method to cancel the default browser behavior. This way, the events will only occur when the specific conditions are met. We will add three event handlers in the first and second <div> elements in the HTML file. Final code: <!DOCTYPE html> <html lang="en"> <head> <title> Example to Perform Drag and Drop</title> <link rel="stylesheet" href=" css/ style.css" /> </head> <body> <div class="example-parent"> <div class="example-origin"> <div id="draggable-1" class="example-draggable" draggable="true" ondragstart="onDragStart(event);" > draggable </div> </div> <div class="example-dropzone" ondragover="onDragOver(event);" ondrop="onDrop(event);"> dropzone </div> </div> <script src="script.js"></script> </body> </html> Conclusion Our example demonstrated how to move elements using HTML Drag and Drop with pure JavaScript. By following this step-by-step approach, you can move on to implement larger projects (which can always be hosted on cloud servers like Hostman). Remember, in development, a well-thought-out graphical interface establishes effective communication between the user and the application or website.
15 January 2025 · 7 min to read
Python

How to Install pip on Windows

pip is a utility that turns Python package installation and management into a straightforward task. From Python beginners to coding wizards, having this utility on your Windows computer is a true game-changer. It effortlessly facilitates the setup of crucial frameworks and libraries for your development needs. Automating package management with pip frees up your time and reduces the complications linked to manual installations. Follow this guide to become proficient in configuring pip and overseeing your Python packages seamlessly. pip Setup Process for Windows Here are the guidelines to set up pip on a Windows machine. Step 1: Confirm Installation Verify Python is operational on your device before starting the pip setup. To carry out this operation, run command prompt and apply: python --version   If Python's not present on your system, download it from the official site. Step 2: Download get-pip.py Python's standard installation package automatically includes pip. However, in case of accidental removal, grab the get-pip.py script.  You have a couple of options: either visit the pip.py webpage, or use the curl command for a quick install: curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py Note: Installing Python again to get pip is also an option. However, it can sometimes lead to conflicts with other dependencies or settings. Your existing Python setup stays unchanged with this script. Step 3: Run get-pip.py Move to the script’s location through the command prompt and apply: python get-pip.py This will smoothly install pip on your device. Step 4: Confirm pip Installation Validate the installation by executing: pip --version Applying this command ensures pip is installed on the system. Step 5: Add pip to System PATH If the command doesn't execute properly, update your system PATH with these instructions to incorporate pip: Access Properties by right-clicking on My Computer or This PC from the drop-down menu. Opt for Advanced system settings. Select Environment Variables. Head over to System Variables, spot the Path variable, and choose Edit. Insert the Python Scripts directory into your system PATH, for example, C:\Python39\Scripts. Alternative Ways for pip Installation on Windows Let's discuss a few other ways to effortlessly get pip running on Windows. Via Built-in ensurepip Module From Python 3.4 onward, there's an awesome built-in module named ensurepip. With this tool, pip installation is simplified, eliminating the need for the get-pip.py script. Step 1: Run ensurepip Input the command below to set up pip: python -m ensurepip --default-pip Step 2: Verify pip Installation Check pip version through: pip --version Python Installer Approach for pip Installation Ensure the pip checkbox is marked during the Python setup. Here's how: Step 1: Download Installer Fire up your favorite browser, go to the official Python website, and acquire the most recent installation file. Step 2: Launch the Installer Launch the installer you've downloaded and remember to pick the Add Python to PATH option while setting up. Step 3: Install pip While progressing through the setup, don't forget to enable the Install pip option. Step 4: Validate pip is Installed When the setup wraps up, check pip installation via: pip --version Adjusting pip Version: Upgrade or Downgrade pip can be adjusted to suit your requirements by upgrading or downgrading. Here's how: Upgrading pip To give pip a fresh upgrade, execute: python -m pip install --upgrade pip Downgrading pip To roll back pip, apply: python -m pip install pip==<version> Enter the desired version number to install instead of <version> (e.g., 21.0). Resolving pip Installation Issues: Essential Commands Let's discover common pip installation issues and their fixes: Issue 1: "pip" is not recognized as an internal or external command Solution: This implies the pip path isn't set in your system PATH. Simply follow the instructions in "Step 5" to fix this. Issue 2: Permission Denied Solution: Elevate your command prompt privileges by right-clicking the Command Prompt icon and choosing Run as administrator. Afterward, rerun the commands. Issue 3: Missing Dependencies Solution: Sometimes, you'll run into trouble because of missing dependencies. To correct this, manually install the essential dependencies with pip. For example: pip install package_name Swap out package_name for the appropriate dependency. Utilizing Virtual Environments Employing virtual environments keeps dependencies distinct and avoids any conflicts. Here's how to utilize a virtual environment with pip: Creating a Virtual Environment python -m venv env_name Replace env_name with your desired environment name. Initiating Your Virtual Environment env_name\Scripts\activate Standard pip Commands To explore pip's usage, check these essential commands: Installing a Package pip install package_name Modify package_name to accurately reflect the package you're aiming to install. Uninstalling a Package pip uninstall package_name Showing Installed Packages pip list Showing Package Information pip show package_name Optimal Strategies for Package Management Employ virtual environments to handle dependencies efficiently in multiple projects. Regularly inspect and upgrade your packages to keep everything running smoothly. Prepare requirements files to ease the management of dependencies in your projects. Securing pip Installation Ensuring the protection of packages handled by pip is critical. Here are some tips to keep your environment secure: Maintain project isolation to avoid conflicts and secure installations. Check the trustworthiness and verification of package sources before installing. Always refer to official repositories and examine reviews if they are available. Consistently update pip and your packages to stay protected with the latest security patches and improvements. Periodically review your dependencies for known vulnerabilities. Tools such as pip-audit can assist in identifying and resolving security concerns. Adhere to secure coding standards and steer clear of deprecated or insecure packages. Integrating pip with IDEs pip can be effortlessly embedded into various Integrated Development Environments (IDEs), significantly boosting your development efficiency: VS Code: Utilize the built-in terminal for direct pip command and package management within the editor. PyCharm: Streamline package management by setting up pip configurations via the project interpreter. This simplifies the process of installing and managing packages customized to your project's specific needs. Jupyter Notebook: Employ magic commands in the notebook interface for direct package installation. This provides a smooth and integrated experience for managing dependencies while you work on your interactive notebooks.  Conclusion Windows offers several methods to set up pip, catering to different preferences and requirements. No matter if you select the .py script, use Python's built-in ensurepip module, or enable pip during the initial setup, these approaches will make sure pip is properly configured on your system. This all-in-one guide empowers you to handle and install Python packages with ease. Don't forget, keeping pip updated is essential for ensuring the security and efficiency of your Python setup. Routinely check for updates and keep pip upgraded. In addition, on our application platform you can find Python apps, such as Celery, Django, FastAPI and Flask.
15 January 2025 · 6 min to read
Java

Java Date Format

Handling dates and times effectively is a critical aspect of many software applications. In Java, the SimpleDateFormat class from the java.text package offers developers a robust mechanism for formatting Date objects into strings and parsing strings back into Date objects. This guide explores the features, use cases, and best practices for leveraging SimpleDateFormat in your Java projects. Overview of SimpleDateFormat A method for creating unique patterns for date and time data representation is offered by SimpleDateFormat. These patterns are versatile, allowing developers to adapt date formats to their specific application requirements. Here’s an introductory example: import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo { public static void main(String[] args) { SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); Date currentDate = new Date(); System.out.println("Formatted Date: " + formatter.format(currentDate)); } } This sample produces a string that is formatted in accordance with the given pattern and contains the current date and time: Formatted Date: 07/01/2025 14:35:00 Pattern Syntax for Formatting Dates The SimpleDateFormat class employs a symbolic pattern language to precise how dates and times should appear. Below is a table summarizing some key symbols: Symbol Description Example y Year 2025 (yyyy), 25 (yy) M Month 01 (MM), Jan (MMM) d Day of the month 07 (dd) H Hour (0-23) 14 (HH) h Hour (1-12) 02 (hh) m Minute 35 (mm) s Second 00 (ss) a AM/PM marker PM E Day of the week Tue (EEE), Tuesday (EEEE) z Time zone PST (z), Pacific Standard Time (zzzz) d Day of the month 07 (dd) H Hour (0-23) 14 (HH) h Hour (1-12) 02 (hh) m Minute 35 (mm) s Second 00 (ss) a AM/PM marker PM E Day of the week Tue (EEE), Tuesday (EEEE) z Time zone PST (z), Pacific Standard Time (zzzz) Combining these symbols allows developers to create highly tailored date and time formats. Customizing Date Formats Using SimpleDateFormat, you can craft custom formats to suit various requirements. Here’s an example demonstrating three distinct patterns: import java.text.SimpleDateFormat; import java.util.Date; public class DateFormatExamples { public static void main(String[] args) { Date currentDate = new Date(); SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat verboseFormat = new SimpleDateFormat("EEEE, MMMM dd, yyyy"); SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm a z"); System.out.println("ISO Format: " + isoFormat.format(currentDate)); System.out.println("Verbose Format: " + verboseFormat.format(currentDate)); System.out.println("Time Format: " + timeFormat.format(currentDate)); } } Sample Output: ISO Format: 2025-01-07 Verbose Format: Tuesday, January 07, 2025 Time Format: 02:35 PM PST Parsing Strings to Date Objects SimpleDateFormat also facilitates converting string representations of dates back into Date objects. This is especially useful for handling user input or reading data from external sources. import java.text.SimpleDateFormat; import java.util.Date; public class DateParsingDemo { public static void main(String[] args) { String inputDate = "07-01-2025 14:35:00"; SimpleDateFormat parser = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); try { Date parsedDate = parser.parse(inputDate); System.out.println("Parsed Date: " + parsedDate); } catch (Exception e) { System.out.println("Parsing failed: " + e.getMessage()); } } } Expected Output: Parsed Date: Tue Jan 07 14:35:00 PST 2025 Incorporating Time Zones The setTimeZone method in SimpleDateFormat allows for explicit handling of different time zones. Here’s an example: import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class TimeZoneHandling { public static void main(String[] args) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); System.out.println("UTC Time: " + formatter.format(new Date())); formatter.setTimeZone(TimeZone.getTimeZone("America/New_York")); System.out.println("New York Time: " + formatter.format(new Date())); } } Output Example: UTC Time: 2025-01-07 22:35:00 UTC New York Time: 2025-01-07 17:35:00 EST Locale-Aware Formatting The SimpleDateFormat class supports locale-specific date formatting. By specifying a Locale, you can adapt your application for different regions and languages: import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class LocaleFormatting { public static void main(String[] args) { Date today = new Date(); SimpleDateFormat usFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy", Locale.US); SimpleDateFormat frFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy", Locale.FRANCE); System.out.println("US Format: " + usFormatter.format(today)); System.out.println("French Format: " + frFormatter.format(today)); } } Output Example: US Format: Tuesday, January 07, 2025French Format: mardi, janvier 07, 2025 Working with Legacy Code For projects that rely on legacy systems, SimpleDateFormat can be instrumental in ensuring compatibility with older data formats. By crafting patterns that match the specific requirements of legacy systems, developers can seamlessly bridge modern and older systems. However, it is critical to perform rigorous testing when working with legacy code. Edge cases like leap years, daylight saving time adjustments, or unusual formats often surface in older implementations. Developers should document the specific formats being used and verify the results using multiple test cases. In certain situations, refactoring legacy systems to use modern libraries like DateTimeFormatter may offer long-term benefits. While it might require upfront effort, the enhanced performance and reduced bug risk in newer libraries often justify the transition. Date Validation Techniques Validating dates is a common requirement in applications that accept user input. With SimpleDateFormat, you can ensure that input strings conform to the expected format before further processing. For example: import java.text.SimpleDateFormat; import java.util.Date; public class DateValidation { public static void main(String[] args) { String dateString = "31-02-2025"; SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); formatter.setLenient(false); try { Date validatedDate = formatter.parse(dateString); System.out.println("Valid Date: " + validatedDate); } catch (Exception e) { System.out.println("Invalid Date: " + e.getMessage()); } } } Output Example: Invalid Date: Unparseable date: "31-02-2025" Using the setLenient(false) method ensures that only logically valid dates are accepted, reducing the risk of errors in downstream processes. Common Pitfalls and Recommendations Thread Safety: Avoid sharing SimpleDateFormat instances across multiple threads. Use ThreadLocal or Java’s DateTimeFormatter for thread-safe alternatives. Error Handling: Always handle potential ParseException errors when parsing strings. ISO Standards: Utilize ISO 8601 formats (e.g., yyyy-MM-dd'T'HH:mm:ss'Z') for better interoperability. Dynamic Time Zones: Refrain from hardcoding time zones; instead, fetch them dynamically when necessary. Input Validation: Before parsing, make sure the input strings have the correct format. Transitioning to Modern Alternatives With the introduction of the java.time package in Java 8, many developers prefer DateTimeFormatter over SimpleDateFormat for its enhanced features and thread safety. import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class ModernDateFormatting { public static void main(String[] args) { LocalDateTime currentDateTime = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); System.out.println("Formatted Date-Time: " + currentDateTime.format(formatter)); } } Sample Output: Formatted Date-Time: 2025-01-07 14:35:00 Additionally, DateTimeFormatter supports advanced features such as optional sections, localized styles, and predefined constants for ISO-compliant formats. These features make it a more versatile and robust choice for modern applications. Final Thoughts SimpleDateFormat remains a practical choice for date and time handling in Java. However, it is essential to understand its limitations, especially in terms of thread safety and modern compatibility. By adopting best practices and considering newer options like DateTimeFormatter, you can ensure robust and efficient date manipulation in your Java applications. Whether you are working with legacy systems, processing user inputs, or developing new features, a thorough knowledge of Java's date formatting features will empower you to handle date and time operations with confidence and precision. In addition, check out our app platform to find cloud apps, such as React, Angular, Vue and more.
15 January 2025 · 8 min to read
Debian

How to Install MySQL on Debian

Installing MySQL on Debian effectively creates a robust and flexible database (DB) infrastructure that accommodates a wide range of applications as well as services. It is renowned for its scalability, dependability, and durability. By setting it, individuals experience the operations in an efficient manner and enhance the overall efficiency of DB infrastructure. This combination is especially beneficial for administrators, DB analysts, and industries that demand a dependable database solution for dealing with huge data. Additionally, MySQL's comprehensive guide and supporters help make it simpler to troubleshoot problems and enhance operations.  In this guide, we will demonstrate the thorough procedure for installing and configuring MySQL on Debian. How to Install MySQL on Debian The default repositories do not contain the MySQL database server package on Debian. To install it on a  Linux system follow the below instructions. We will download the recent version of the MySQL. Step 1: Download MySQL Package Let us obtain the MySQL repository information package, which is in the .deb format: wget https://dev.mysql.com/get/mysql-apt-config_0.8.30-1_all.deb Note: To authenticate the most updated release, go to the MySQL repository webpage. Step 2: MySQL Configuration Package Installation Then, employ the .deb file for initializing the installation via dpkg: sudo dpkg -i mysql-apt-config_0.8.30-1_all.deb Respond to the prompt. For instance, pick MySQL Server & Cluster and hit Enter for starting configurations: For picking a version such as (mysql-8.4-lts), scroll downward and hit OK for the next step: Step 3: Refresh the System Now, update the server's package indexes to implement the updated MySQL info: sudo apt update Step 4: MySQL Installation Debian's default manager makes sure to install MySQL in an easier manner. Installing the package with this command: sudo apt install mysql-server -y You will see the interface for setting the root account. Input a stronger password to secure the database. In the end, hit the Ok button: Check the version on the server via the --version utility: mysql --version Step 5: Managing the Services Now, you can enable the MySQL service to initialize automatically at boot time: sudo systemctl enable mysql Activate the service via the systemctl utility: sudo systemctl start mysql Check if the system service is operational by viewing its status: sudo systemctl status mysql Step 6: MySQL Secure Installation The key or password that the individual created at the initialising procedure is currently protecting the root DB user on the server. MySQL also includes other insecure defaults, such as remote access to test databases and the root database user on the server.  It is vital to secure the MySQL installation after it has been completed as well as disable all unsafe default settings. There is a security script that can assist us in this procedure. Run the script: sudo mysql_secure_installation To activate the VALIDATE PASSWORD component and guarantee stringent password procedures, type Y and hit Enter. Next, you will need to configure several security settings: Set the Root Password: Select a strong password and make sure that it is correct. Configure the password policy for the DB server. For instance, type 2 to permit only the strong passwords on the server and hit Enter. When required to modify the root password, input N; alternatively, input Y to modify the password. Eliminate Anonymous Users: It is advised to eliminate the accessibility of anonymous users. For this, input Y and Enter when prompted. Prevent Accessibility of Remote Root: It is a better practice to avoid remote root login for multiple security concerns. To prevent the root user from having a remote access, input Y and hit Enter. Delete the Test DB: For enhancing security, the test database, which is utilized for testing, can be deleted. To do so, input Y and hit Enter. Refreshing Privilege Tables: It guarantees that all modifications are implemented instantly. To implement the configuration and edit the privileges table, hit Enter. Step 7: Access MySQL Utilizing the mysql client utility, MySQL establishes the connection and provides access to the database server console.  Now, access the shell interface and run general statements on the DB server. Let’s input the root and the password created at the time of the safe installation procedure: sudo mysql -u root -p Step 8: Basic MySQL Operations The creation of a DB and a new user for your applications rather than utilizing the root is a better practice. To accomplish the task, employ the given instructions: Create a Database: First, create a database. For instance, hostmandb is created via the below command: CREATE DATABASE hostmandb; Display All Databases: List all databases to make sure hostmandb is created: SHOW DATABASES; Create of a New User: Create a user and assign a strong password. In our example, we set Qwer@1234 as a password for the user  minhal. Replace these values with your data. CREATE USER 'minhal'@'localhost' IDENTIFIED BY 'Qwer@1234'; Give Permissions to the User: Give complete access to the hostmandb to the new user: GRANT ALL PRIVILEGES ON hostmandb.* TO 'minhal'@'localhost'; Flush Privileges: To implement the modifications, refresh the table: FLUSH PRIVILEGES; Exit the Shell: For closing the interface, utilize the EXIT statement: EXIT; Access MySQL Console as the Particular User For the purpose of testing hostmandb access, log in to MySQL as the new user, in our case minhal. sudo mysql -u minhal -p It accesses the console after entering the minhal user password when prompted: For verification, display all DBs and confirm that the hostmandb is available: SHOW DATABASES; Step 9: Configuration for Remote Access Setting up the server for supporting remote accessibility is necessary if an individual is required to access MySQL remotely. Follow these steps: Access the mysql.cnf file and modify the particular file for MySQL: sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf Look for the line with the bind-address and change it to: bind-address = 0.0.0.0 Reload the MySQL service: sudo systemctl restart mysql Permit the user to have remote access: sudo mysql -u root -p GRANT ALL PRIVILEGES ON hostmandb.* TO 'minhal'@'localhost';FLUSH PRIVILEGES;EXIT; Step 10: Firewall Configuration If you have a firewall activated, you need to open the MySQL port 3306 to traffic. Set up the firewall following the below steps: Allow traffic through MySQL: sudo ufw allow mysql Now, activate the UFW on the system: sudo ufw enable Reload the firewall: sudo ufw reload Step 11: Restore and Backup Maintaining regular backups is crucial to avoiding data loss. The mysqldump utility is provided by MySQL for backup creation. To achieve this, consider these instructions: Backup a Single Database: This command employs mysqldump to create the backup of the hostmandb as a hostmandb_backup.sql file: sudo mysqldump -u root -p hostmandb> hostmandb_backup.sql Backup All Databases: For creating a backup of all databases as a file named all_databases_backup.sql with root privileges, utilize mysqldump: sudo mysqldump -u root -p --all-databases > all_databases_backup.sql Restore a Particular Database: Now, restore the hostmandb from the backup file hostmandb_backup.sql: sudo mysql -u root -p hostmandb < hostmandb_backup.sql Step 12: Optimize MySQL Operations (Optional) Depending on the workload and server resources, you can adjust settings to guarantee peak performance. These instructions will help you maximize MySQL's speed: Adjust InnoDB Buffer Pool Size: Caches for data and indexes are kept in the InnoDB buffer pool. Expanding its size can enhance its functionality. Edit the MySQL configuration file: sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf The below line should be added or changed: innodb_buffer_pool_size = 1G Its size should be adjusted according to the amount of memory on the server. Enable Query Cache: The query cache stores the outcome of SELECT queries. Enabling it can enhance operations for repetitive queries. Modify the .cnf file: sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf Add or edit the below lines: query_cache_type = 1query_cache_size = 64M Optimize Table Structure: Frequently optimize your customers table in hostmandb to recover wasted space and boost efficiency: USE hostmandb;OPTIMIZE TABLE customers; Analyze Operations: DB operations can be tracked and analyzed with tools like MySQL Workbench and mysqltuner. Using the command below, install mysqltuner: sudo apt install mysqltuner Run mysqltuner to get performance recommendations: sudo mysqltuner Conclusion Installing a MySQL environment is important in today's digital world. By following this instruction, you'll be able to safely install and connect to your MySQL database. This strategy not only increases security but also improves remote database maintenance efficiency. It helps to prevent breaches and ensures the confidentiality of your data. This article has given thorough instructions for the installation of MySQL's database environment on Debian. It is suggested that MySQL servers should be regularly monitored and optimized to guarantee optimum performance and dependability. In addition, Hostman offers pre-configured and ready-to-use cloud databases, including cloud MySQL. 
14 January 2025 · 8 min to read
Apache

How To Install the Apache Web Server on Ubuntu 22.04

Apache stands out as one of the most recognized and broadly utilized open-source web platforms across the globe. It is renowned for its dependability, adaptability, and profound usage. Its modular design, rich feature set, and compatibility with diverse operating systems make it a preferred choice for developers and IT professionals. For both novice and seasoned administrators, knowing how to do the installation and configuration of Apache properly is crucial, whether they are managing a sophisticated online infrastructure or setting up a simple website. With the help of this tutorial, users will build a reliable foundation for their web hosting requirements by installing Apache on Ubuntu 22.04, setting it up for maximum performance, and confirming that it is operating successfully. By employing the outlined procedures, administrators can guarantee a secure, scalable, and efficient environment, ready to support diverse online platform applications and services. Prerequisites Make sure the following requirements are satisfied before starting the installation of the Apache web server on Ubuntu 22.04 to lower the possibility of mistakes and guarantee a flawless setup. Ubuntu 22.04 System: Make sure Ubuntu 22.04 is installed on the cloud server or virtual machine. Access Rights: User must have root or sudo access to the platform. Online Connection: In order to download and install Apache and related software, a steady web connection is necessary. Domain Name (optional): Having a registered domain name is advised for anyone wishing to deploy a website. Before configuring the Apache web server, the DNS settings should be set up to point the domain to the server's IP address. System Update Ensure the engine is fully updated prior to starting the installation process. System updates reduce compatibility problems during installation by verifying that every software packages, libraries, and dependencies are up to date. Log in with administrative credentials to the server. Execute the following command for updating the system's package index. sudo apt update This will retrieve the most recent data on software and package versions from the repositories. Subsequently, upgrade the installed packages to the most recent versions by deploying the instruction below:  sudo apt upgrade Apache Installation Ubuntu's default repositories contain Apache. Employ the following command to install the core Apache package and its dependencies.  sudo apt install apache2 -y Once the installation is finished, validate if Apache was successfully installed by looking up its version. apache2 -v Next, verify that Apache is operational. sudo systemctl status apache2 Permit Apache Traffic Through the Firewall Apache traffic must be permitted if your server has the Uncomplicated Firewall (UFW) enabled. Add the necessary rules. First, make sure SSH connections are allowed: sudo ufw allow ssh Then, add the specific rule for Apache: sudo ufw allow 'Apache Full' To verify that the Apache traffic is allowed, check the status of the UFW rules. sudo ufw status Test Apache Installation Launch an internet browser and navigate to your server's IP address to make sure Apache is operating. The default Apache "Welcome Page" will be displayed if Apache is installed correctly. http://server-ip You can find the server's IP address on the server Dashboard in your Hostman control panel. You can also determine the IP address for the server by employing the command below. Check the inet field for the IP address. ip addr show In this case, the IP address of the server is 166.1.227.224. So we visit it in the web browser: http:// 166.1.227.224 Control the Apache Service To manage the Apache service, use these fundamental commands: sudo systemctl start apache2  – employ this to initialise Apache engine. sudo systemctl stop apache2  – employ this command to halt the Apache. sudo systemctl restart apache2  – employ this to reinitialise the Apache engine. sudo systemctl enable apache2  – to configure the Apache engine to start automatically upon reboot. sudo systemctl disable apache2  – to prevent the Apache service from launching automatically after a system reboot. Set up Apache (Optional) The Apache configuration files are located in /etc/apache2/. Typical configuration tasks include the techniques mentioned below. sudo nano /etc/apache2/apache2.conf This will open the main configuration file for modifying. This file manages a variety of server settings, including Apache's behavior, security protocols, and how it processes incoming web requests. /etc/apache2/sites-available This is a directory that houses virtual host configuration files in the Apache web server's configuration hierarchy. By setting distinct domains or subdomains, virtual hosts enable users to operate several websites or apps on a single Apache server. Virtual hosts allow administrators to employ several websites or web applications on a single Apache server, making it an effective solution for minimising infrastructure expenses and simplifying server management. This capability streamlines operations by consolidating multiple sites onto one server, reducing the need for additional hardware and enhancing resource utilisation. sudo a2ensite apache-config.conf This method is utilised to activate a site-specific Apache web server configuration file on systems located on /etc/apache2/sites-available/. Whenever this command is executed, the file /etc/apache2/sites-available/apache-config.conf is linked to /etc/apache2/sites-enabled/. sudo a2dissite apache-config.conf This method is used to disable a site-specific Apache web server configuration file on systems located on /etc/apache2/sites-available/. Whenever this command is executed, the file /etc/apache2/sites-available/apache-config.conf is unlinked to /etc/apache2/sites-enabled/. sudo apache2ctl configtest The goal is to verify the syntax of the configuration files for the Apache web server prior to making any modifications or restarting the service. It makes sure that the configuration files don't contain any invalid directives or syntax mistakes that could cause Apache to crash on a restart or reload. sudo systemctl reload apache2 This is used to refresh the settings of the Apache web server without halting or disrupting ongoing connections whenever there is change made on the apache configuration. Secure Apache with SSL (Optional) Installing Certbot and the Apache plugin with the command below is the standard way to secure the Apache server with HTTPS. sudo apt install certbot python3-certbot-apache -y Use Certbot to set up SSL automatically by employing the command below. Set up the SSL certificate by following the instructions on prompt (see highlighted in yellow). sudo certbot --apache Conclusion One essential step in hosting web apps or providing webpages on Ubuntu 22.04 is installing and configuring the Apache web server. Administrators can create a dependable and expandable web server environment by following the described procedures, which include installing and maintaining virtual hosts as well as testing settings. By ensuring the integrity of configuration files, operations such as sudo apache2ctl configtest lower the possibility of errors or outages. Because of its adaptability, stability, and broad community support, Apache remains a fundamental component of web hosting solutions, making it a necessary competency for both developers and IT professionals.
14 January 2025 · 6 min to read
Python

How to Split a String Using the split() Method in Python

Working with strings is integral to many programming tasks, whether it involves processing user input, analyzing log files, or developing web applications. One of the fundamental tools that simplifies string manipulation in Python is the split() method. This method allows us to easily divide strings into parts based on specified criteria, making data processing and analysis more straightforward. In this article, we'll take a detailed look at the split() method, its syntax, and usage features. You'll learn how to use this method for solving everyday tasks and see how powerful it can be when applied correctly. Regardless of your programming experience level, you'll find practical tips and techniques to help you improve your string-handling skills in Python. What is the split() Method? The split() method is one of the core tools for working with strings in Python. It is designed to split a string into individual parts based on a specified delimiter, creating a list from these parts. This method is particularly useful for dividing text into words, extracting parameters from a string, or processing data separated by special characters, such as commas or tabs. The key idea behind the split() method is to transform a single string into a set of smaller, more manageable elements. This significantly simplifies data processing and allows programmers to perform analysis and transformation tasks more quickly and efficiently. Syntax of split() The split() method is part of Python's standard library and is applied directly to a string. Its basic syntax is as follows: str.split(sep=None, maxsplit=-1) Let’s break down the parameters of the split() method: sep (separator) This is an optional parameter that specifies the character or sequence of characters used as the delimiter for splitting the string. If sep is not provided or is set to None, the method defaults to splitting the string by whitespace (including spaces, tabs, and newline characters). If the string starts or ends with the delimiter, it is handled in a specific way. maxsplit This optional parameter defines the maximum number of splits to perform. By default, maxsplit is -1, which means there is no limit, and the string will be split completely. If maxsplit is set to a positive number, the method will split the string only the specified number of times, leaving the remaining part of the string as the last element in the resulting list. These parameters make it possible to customize split() to meet the specific requirements of your task. Let’s explore practical applications of split() with various examples to demonstrate its functionality and how it can be useful in daily data manipulation tasks. Examples of Using the split() Method To better understand how the split() method works, let's look at several practical examples that demonstrate its capabilities and applicability in various scenarios. Splitting a String by Spaces The most common use of the split() method is to break a string into words. By default, if no separator is specified, split() divides the string by whitespace characters. text = "Hello world from Python" words = text.split() print(words) Output: ['Hello', 'world', 'from', 'Python'] Splitting a String by a Specific Character If the data in the string is separated by another character, such as commas, you can specify that character as the sep argument. vegetable_list = "carrot,tomato,cucumber" vegetables = vegetable_list.split(',') print(vegetables) Output: ['carrot', 'tomato', 'cucumber'] Splitting a String a Specified Number of Times Sometimes, it’s necessary to limit the number of splits. The maxsplit parameter allows you to specify the maximum number of splits to be performed. text = "one#two#three#four" result = text.split('#', 2) print(result) Output: ['one', 'two', 'three#four'] In this example, the string was split into two parts, and the remaining portion after the second separator, 'three#four', was kept in the last list element. These examples demonstrate how flexible and useful the split() method can be in Python. Depending on your tasks, you can adapt its use to handle more complex string processing scenarios. Using the maxsplit Parameter The maxsplit parameter provides the ability to limit the number of splits a string will undergo. This can be useful when you only need a certain number of elements and do not require the entire string to be split. Let's take a closer look at how to use this parameter in practice. Limiting the Number of Splits Imagine you have a string containing a full file path, and you only need to extract the drive and the folder: path = "C:/Users/John/Documents/report.txt" parts = path.split('/', 2) print(parts) Output: ['C:', 'Users', 'John/Documents/report.txt'] Using maxsplit for Log File Processing Consider a string representing a log entry, where each part of the entry is separated by spaces. You are only interested in the first two fields—date and time. log_entry = "2024-10-23 11:15:32 User login successful" date_time = log_entry.split(' ', 2) print(date_time[:2]) Output: ['2024-10-23', '11:15:32'] In this case, we split the string twice and extract only the date and time, ignoring the rest of the entry. Application to CSV Data Sometimes, data may contain delimiter characters that you want to ignore after a certain point. csv_data = "Name,Email,Phone,Address" columns = csv_data.split(',', 2) print(columns) Output: ['Name', 'Email', 'Phone,Address'] Here, we limit the number of splits to keep the fields 'Phone' and 'Address' combined. The maxsplit parameter adds flexibility and control to the split() method, making it ideal for more complex data processing scenarios. Working with Delimiters Let’s examine how the split() method handles delimiters, including its default behavior and how to work with consecutive and multiple delimiters. Splitting by Default When no explicit delimiter is provided, the split() method splits the string by whitespace characters (spaces, tabs, and newlines). Additionally, consecutive spaces will be interpreted as a single delimiter, which is particularly useful when working with texts that may contain varying numbers of spaces between words. text = "Python is a versatile language" words = text.split() print(words) Output: ['Python', 'is', 'a', 'versatile', 'language'] Using a Single Delimiter Character If the string contains a specific delimiter, such as a comma or a colon, you can explicitly specify it as the sep argument. data = "red,green,blue,yellow" colors = data.split(',') print(colors) Output: ['red', 'green', 'blue', 'yellow'] In this case, the method splits the string wherever a comma is encountered. Working with Consecutive and Multiple Delimiters It’s important to note that when using a single delimiter character, split() does not treat consecutive delimiters as one. Each occurrence of the delimiter results in a new element in the resulting list, even if the element is empty. data = "one,,two,,,three" items = data.split(',') print(items) Output: ['one', '', 'two', '', '', 'three'] Splitting a String by Multiple Characters There are cases where you need to split a string using multiple delimiters or complex splitting rules. In such cases, it is recommended to use the re module and the re.split() function, which supports regular expressions. import re beverage_data = "coffee;tea juice|soda" beverages = re.split(r'[;|\s]', beverage_data) print(beverages) Output: ['coffee', 'tea', 'juice', 'soda'] In this example, a regular expression is used to split the string by several types of delimiters. Tips for Using the split() Method The split() method is a powerful and flexible tool for working with textual data in Python. To fully leverage its capabilities and avoid common pitfalls, here are some useful recommendations: Consider the Type of Delimiters When choosing a delimiter, make sure it matches the nature of the data. For instance, if the data contains multiple spaces, it might be more appropriate to use split() without explicitly specifying delimiters to avoid empty strings in the list. Use maxsplit for Optimization If you know that you only need a certain number of elements after splitting, use the maxsplit parameter to improve performance. This will also help avoid unexpected results when splitting long strings. Use Regular Expressions for Complex Cases The split() method with regular expressions enables solving more complex splitting tasks, such as when data contains multiple types of delimiters. Including the re library for this purpose significantly expands the method’s capabilities. Handle Empty Values When splitting a string with potentially missing values (e.g., when there are consecutive delimiters), make sure your code correctly handles empty strings or None. data = "value1,,value3" result = [item for item in data.split(',') if item] Validate Input Data Always consider potential errors, such as incorrect delimiters or unexpected data formats. Adding checks for values before calling split() can prevent many issues related to incorrect string splitting. Suitability for Use Remember that split() is unsuitable for processing more complex data structures, such as nested strings with quotes or data with escaped delimiters. In such cases, consider using specialized modules, such as csv for handling CSV formats. Following these tips, you can effectively use the split() method and solve textual data problems in Python. Understanding the subtleties of string splitting will help you avoid errors and make your code more reliable and understandable. Conclusion The split() method is an essential part of string handling in Python, providing developers with flexible and powerful tools for text splitting and data processing. In this article, we explored various aspects of using the split() method, including its syntax, working with parameters and delimiters, as well as practical examples and tips for its use. Check out our app platform to find Python applications, such as Celery, Django, FastAPI and Flask.
13 January 2025 · 8 min to read

Answers to Your Questions

What is Hostman used for, and what services do you offer?

Hostman is a cloud platform where developers and tech teams can host their solutions: websites, e-commerce stores, web services, applications, games, and more. With Hostman, you have the freedom to choose services, reserve as many resources as you need, and manage them through a user-friendly interface.

Currently, we offer ready-to-go solutions for launching cloud servers and databases, as well as a platform for testing any applications.

 

  • Cloud Servers. Your dedicated computing resources on servers in Poland and the Netherlands. Soon, we'll also be in the USA, Singapore, Egypt, and Nigeria. We offer 25+ ready-made setups with pre-installed environments and software for analytics systems, gaming, e-commerce, streaming, and websites of any complexity.

  • Cloud Databases. Instant setup for any popular database management system (DBMS), including MySQL, PostgreSQL, MongoDB, Redis, Apache Kafka, and OpenSearch.

  • Apps. Connect your Github, Gitlab, or Bitbucket and test your websites, services, and applications. No matter the framework - React, Angular, Vue, Next.js, Ember, etc. - chances are, we support it on our app platform.

Can I have confidence in Hostman to handle my sensitive data and cloud-based applications?

Your data's security is our top priority. Only you will have access to whatever you host with Hostman.

Additionally, we house our servers in Tier IV data centers, representing the pinnacle of reliability available today. Furthermore, all data centers comply with international standards: 

  • ISO: Data center design standards

  • PCI DSS: Payment data processing standards

  • GDPR: EU standards for personal data protection

What are the benefits of using Hostman as my cloud service provider?

User-Friendly. With Hostman, you're in control. Manage your services, infrastructure, and pricing structures all within an intuitive dashboard. Cloud computing has never been this convenient.

 

Great Uptime: Experience peace of mind with 99.99% SLA uptime. Your projects stay live, with no interruptions or unpleasant surprises.

 

Around-the-Clock Support. Our experts are ready to assist and consult at any hour. Encountered a hurdle that requires our intervention? Please don't hesitate to reach out. We're here to help you through every step of the process.

 

How does pricing work for your cloud services?

At Hostman, you pay only for the resources you genuinely use, down to the hour. No hidden fees, no restrictions.

Pricing starts as low as $4 per month, providing you with a single-core processor at 3.2 GHz, 1 GB of RAM, and 25 GB of persistent storage. On the higher end, we offer plans up to $75 per month, which gives you access to 8 cores, 16 GB of RAM, and 320 GB of persistent storage.

For a detailed look at all our pricing tiers, please refer to our comprehensive pricing page.

Do you provide 24/7 customer support for any issues or inquiries?

Yes, our technical specialists are available 24/7, providing continuous support via chat, email, phone, and WhatsApp. We strive to respond to inquiries within minutes, ensuring you're never left stranded. Feel free to reach out for any issue — we're here to assist.

Can I easily scale my resources with Hostman's cloud services?

With Hostman, you can scale your servers instantly and effortlessly, allowing for configuration upsizing or downsizing, and bandwidth adjustments.

Please note: While server disk space can technically only be increased, you have the flexibility to create a new server with less disk space at any time, transfer your project, and delete the old server.

What security measures do you have in place to protect my data in the cloud?

Hostman ensures 99.99% reliability per SLA, guaranteeing server downtime of no more than 52 minutes over a year. Additionally, we house our servers exclusively in Tier IV data centers, which comply with all international security standards.

 

How can I get started with Hostman's cloud services for my business?

Just sign up and select the solution that fits your needs. We have ready-made setups for almost any project: a vast marketplace for ordering servers with pre-installed software, set plans, a flexible configurator, and even resources for custom requests.

If you need any assistance, reach out to our support team. Our specialists are always happy to help, advise on the right solution, and migrate your services to the cloud — for free.

Is there a guaranteed Service Level Agreement (SLA) for VPS server uptime?

Hostman guarantees a 99.98% server availability level according to the SLA.

Do you have questions,
comments, or concerns?

Our professionals are available to assist you at any moment,
whether you need help or are just unsure of where to start.
Email us
Hostman's Support