Utveckla med PHP och MySQL i docker

PHP är fortfarande år 2025 ett mycket populärt programmeringsspråk för att bygga webbapplikationer. Det är lättillgängligt, enkelt att hosta och relativt lätt att lära sig.
PHP är fortfarande år 2025 ett mycket populärt programmeringsspråk för att bygga webbapplikationer. Det är lättillgängligt, enkelt att hosta och relativt lätt att lära sig. Den största utmaningen som utvecklare är ofta att få en bra utvecklingsmiljö på plats. Ett vanligt tillvägagångssätt är att installera en färdigpaketerad miljö såsom MAMP, XAMPP eller WAMP. Jag är personligen inte särskilt förtjust i dessa lösningar eftersom de begränsar vilka versioner av de olika komponenterna du kan använda. Dessutom belastar dessa serverprogram datorn onödigt mycket.
Alternativet är att installera webbserver, MySQL och PHP var för sig och därefter konfigurera miljön manuellt. Det har vissa fördelar, såsom att hela PHP:s verktygskedja blir tillgänglig. Nackdelen är att det rör sig om flera program som kräver uppdatering och underhåll. Därför är jag inte heller helt nöjd med detta alternativ.
Ofta faller jag tillbaka till att använda Docker och köra applikationerna i containrar. Det gör det enkelt att skapa en miljö, uppdatera den och återskapa exakt samma miljö på en annan dator. Det enda som behöver installeras är Docker. Det är inte särskilt svårt, och med Docker följer dessutom Docker Compose, som är ett fantastiskt verktyg för att starta flera containrar samtidigt.
Innan vi fortsätter bör vi förklara vad avbildningar och containrar är. En avbildning är en mall för hur en virtuell maskin ska se ut – med operativsystem och alla installerade applikationer. En container är en körande instans av en avbildning. Det finns avbildningar för nästan alla applikationer du kan tänkas vilja köra. Ibland behöver en avbildning anpassas, vilket görs genom att skapa en ny avbildning som ärver från en befintlig version.
En avbildning kan skapas med hjälp av en Dockerfile
.
1# php.dockerfile
2# Use php:8.2-apache as base image
3FROM php:8.2-apache
4
5# Install your extensions
6# Add mysqli
7RUN docker-php-ext-install mysqli
8# Install pdo if you need to use PHP PDO
9RUN docker-php-ext-install pdo pdo_mysql
10# Run docker-php-ext-enable command to activate mysqli
11RUN docker-php-ext-enable mysqli
I detta exempel skapar vi en egen avbildning baserad på PHP:s officiella avbildning. I denna finns Linux och en Apache-webbserver, men den saknar stöd för MySQL. Anpassningen innebär att vi installerar de komponenter som behövs (raderna 7 och 9) och till sist aktiverar vi den modul PHP behöver för att kommunicera med en MySQL-databas.
Vi kan bygga avbildningen med kommandot docker build
. Därefter startar vi en container från avbildningen med kommandot docker start
. Då är en enkel miljö igång men vi vill även ha en databas och några andra komponenter. Dessa kan också köras i Docker. När vi behöver flera avbildningar blir det snabbt krångligt att starta alla containrar manuellt. Här kommer Docker Compose in i bilden. Det läser in en annan fil, docker-compose.yml
, och startar samt konfigurerar flera containrar åt oss. Enklare och smidigare. Låt oss titta på följande docker-compose.yml
-fil:
1services:
2 php:
3 build:
4 context: .
5 dockerfile: php.dockerfile
6 container_name: php-container
7 volumes:
8 - ./src:/var/www/html
9 ports:
10 - "8080:80"
11 networks:
12 - app-network
13
14 mysql:
15 image: mysql:latest
16 container_name: mysql-container
17 restart: always
18 environment:
19 MYSQL_ROOT_PASSWORD: rootpassword
20 MYSQL_DATABASE: mydatabase
21 MYSQL_USER: user
22 MYSQL_PASSWORD: userpassword
23 volumes:
24 - db_data:/var/lib/mysql
25 ports:
26 - "3306:3306"
27 networks:
28 - app-network
29
30 phpmyadmin:
31 image: phpmyadmin/phpmyadmin
32 container_name: phpmyadmin-container
33 environment:
34 PMA_HOST: mysql
35 MYSQL_ROOT_PASSWORD: rootpassword
36 ports:
37 - "8081:80"
38 depends_on:
39 - mysql
40 networks:
41 - app-network
42
43volumes:
44 db_data:
45
46networks:
47 app-network:
48 driver: bridge
Här definierar vi tre tjänster: PHP (rad 2-12), MySQL (rad 14-28) och phpMyAdmin (rad 30-41). Varje tjänst startas som en separat container. Vi definierar även volymer för datalagring och ett nätverk som containrarna kan använda för att kommunicera med varandra.
Låt oss titta närmare på en tjänstedefinition. Först specificeras vilken avbildning som ska användas. Det kan antingen vara en specifik avbildning, som mysql:latest
, eller en build-sektion som beskriver hur en anpassad avbildning ska byggas – vilket vi gör med PHP.
Varje container behöver ett unikt namn. Man kan skapa flera instanser av samma avbildning, men varje instans måste ha ett unikt namn. Ofta behöver programvaran i containern konfigureras, och då är miljövariabler ett smidigt sätt. I MySQL (rad 19–22) och phpMyAdmin (rad 34–35) används miljövariabler som kan justeras vid behov. Här anges t.ex. vilka uppgifter som behövs för att ansluta till databasen.
Data i en container är inte beständig. Det är ett problem vid utveckling eftersom man vill kunna spara det man skapat. Genom att montera volymer i containern kan en yta utanför containern göras tillgänglig. För PHP (rad 8) monterar vi src
-katalogen mot /var/www/html
i containern (om katalogen inte finns kommer den att skapas). Då kan vi arbeta med filer i src
och köra dem direkt via containern. Databasen använder en Docker-volym (raderna 24 samt 43–44), vilket är vanligt för binärdata som måste sparas.
Man kan bestämma vilka portar containrar ska exponera. För PHP mappas port 8080 på värddatorn mot port 80 i containern (rad 10). Det gör att vi kan surfa till localhost:8080
och komma åt webbservern. För databasen görs localhost:3306
tillgänglig (rad 26) och phpMyAdmin exponeras via port 8081 (rad 37). phpMyAdmin är ett populärt verktyg för att administrera MySQL-databaser.
Till sist ser vi att alla tjänster kopplas till nätverket app-network, vilket gör att de kan kommunicera med varandra. Det innebär t.ex. att ett PHP-script i PHP-containern kan ansluta till MySQL-containern.
När konfigurationen är på plats kan du köra docker-compose up -d
för att starta tjänsterna. Första gången tar det en stund eftersom avbildningarna laddas ner. Därefter går uppstarter snabbt. Du kan stoppa alla tjänster med kommandot docker-compose down
eller via Docker Desktop.
Nu är allt klart. När tjänsterna är igång jobbar du med din PHP-kod i src
-katalogen. Webbläsaren svarar på localhost:8080
och phpMyAdmin finns på localhost:8081
.
Lycka till med din utveckling!
Du kan ladda ner mina filer här om du inte vill klipp och klistra: